6

C ++で生のネットワークプログラミングを始めたばかりで、Raspberry Pi自体でコンパイルしています(クロスコンパイルはありません)。それはすべてをリトルエンディアンにします。

IPヘッダーを作成した後、IPチェックサムを計算しましたが、常に正しくありませんでした( http://www.thegeekstuff.com/2012/05/ip-header-checksum/の例に基づく)。

gdbを改良して、IPヘッダーの最初の32ビットの順序まで問題を解決しました。この例では0x4500003C、を使用しています。これは、バージョン4(0x4)、IHL 5(0x5)、TOS 0(0x00)、およびtot_length 60(0x003C)を意味します。だから私は私のパケットを同じように設定しました。

struct iphdr* ip; // Also some mallocing
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->tot_len = 60;

今gdbで、0x3C000045エンディアンのために期待して最初の32ビットを調べましたが、代わりにこれを取得します。

(gdb) print ip
$1 = (iphdr *) 0x11018
(gdb) x/1xw 0x11018
0x11018:        0x003c0045

最初の16ビットはリトルエンディアン(0x0045)ですが、10進数の60を含む2番目のビットはビッグエンディアン(0x003C)のようです。

これを与えているのは何ですか?私は夢中ですか?構造体内のバイト順序について完全に間違っていますか?(それは確かな可能性です)

4

2 に答える 2

7

構造体内のフィールドの順序があり、次にマルチバイトフィールド内のバイトの順序があります。

0x003Cはエンディアンではなく、60の16進値です。確かに、ある程度のエンディアンでメモリに格納されますが、フィールドの書き込みに使用した順序とフィールドの読み取りに使用した順序は同じです。どちらもRaspberry Piのネイティブバイトオーダーであり、キャンセルされます。

通常、次のように記述します。

ip->tot_len = htons(60);

16ビットフィールドをパケットに格納する場合。htonl32ビットフィールド用、およびntohsネットワークntohlパケットからフィールドを読み取るためのものもあります。

于 2012-10-01T23:41:48.377 に答える
1

ARMアーキテクチャはリトルエンディアンとビッグエンディアンの両方を実行できますが、Androidプラットフォームはリトルエンディアンを実行します。

于 2012-10-11T18:35:25.553 に答える