4

Mac 10.6.8 でソケットを使ってプログラミングしています。パケットを受信すると、常に IP ヘッダーから始まります。Wireshark を使用して着信パケットを分析してきましたが、マシンのソケット実装が IP ヘッダーの「合計長」フィールドを一貫して変更することに気付きました。具体的には、IP ヘッダーの長さを減算し、バイトを (ネットワークからホストの順序に) 逆にします。

たとえば、Wireshark によって報告された IP ヘッダーの先頭は次のとおりです。

45 c0 00 38 ...

それは次のように分解されます。

  • 4 ビット (0x4): IP バージョン: 4
  • 4 ビット (0x5): IP ヘッダー長: 5 ワード (20 バイト)
  • 8 ビット (0xc0): 差別化サービス フラグ
  • 16 ビット (0x0038): 全長: 56 バイト

ただし、recvfrom同じパケットで満たされたバッファーの内容を出力すると、別の LED が表示されます。

ssize_t recvbytes = recvfrom(sock->fd, buffer, size, /*flags=*/0,
  (struct sockaddr*)src, &src_len);

戻り値

45 c0 24 00 ...
  • 4 ビット (0x4): IP バージョン: 4
  • 4 ビット (0x5): IP ヘッダー長: 5 ワード (20 バイト)
  • 8 ビット (0xc0): 差別化サービス フラグ
  • 16 ビット (0x2400): 全長: 9216 バイト (?!)

バッファにアクセスする前に、ソケットの実装が全長を読み取り、IP ヘッダーの長さを差し引いてから、ネットワークの順序 (ビッグ エンディアン) ではなく、ホストの順序 (私のマシンではリトル エンディアン) で書き戻していることがわかりました。 . この例では、次のことを意味します。

  • 全長を読む: 0x0038 = 56
  • ヘッダーの長さを引きます: 56 - 20 = 36
  • ホスト順に書き戻す: 36 = 0x0024 (ビッグ エンディアン) = 0x2400 (リトル エンディアン = 私のマシンのホスト順)

問題は悪化します。最も外側の IP ヘッダーの全長を変更するだけではありません。また、内部 IP ヘッダーの全長フィールドも変更します。たとえば、ICMP の「時間超過」メッセージに埋め込まれているもの (ドロップされたパケットの元の IP ヘッダーを含む必要があります)。さらに面白いことに、内部ヘッダーから IP ヘッダーの長さを差し引くことはありません。バイト順を逆にするだけです。

これは他の誰かに起こっていますか?それは私が知らない標準の一部ですか?マシンのソケット実装を修正して、パケットの改ざんを停止する方法はありますか? Wireshark はこの問題をどのように回避できますか?

ご検討いただきありがとうございます。

編集: 私のコードと Makefile はGitHubで入手できます。IP チェックサムを検証できるfixip_osx関数を作成しました。

https://github.com/thejohnfreeman/netutils/blob/master/lib/ip.c

void fixip_osx(struct ip* ip) {
  /* Something on my Mac subtracts the header length from `ip_len` and stores
   * it in host order (little endian). */
  u16_t ip_hdrlen = ip->ip_hl << 2;
  u16_t ip_totlen = ip->ip_len + ip_hdrlen;
  ip->ip_len = htons(ip_totlen);
}

ただし、ペイロードに別の IP ヘッダーが含まれている場合、ICMP チェックサムを検証することは依然として問題です。

問題は、Clang 3.2 (トランクからビルド) または GCC 4.7 (MacPorts ポート) でコンパイルするかどうかに関係なく存在するため、ソケットの実装 (Mac OS にパッケージ化されている) または Mac OS X 自体に問題があると思います。

4

2 に答える 2

3

プラットフォームの BSD スイート (OpenBSD を除く) は、ホストのバイト順で IP オフセットと長さを示します。受信したネットワーク バイト オーダーに存在する他のすべてのプラットフォーム。これは「機能」であり、IP(4) - インターネット プロトコル(FreeBSD、OS X ) のマニュアル ページで参照されています。

ip_len および ip_off フィールドは、ホストのバイト順で指定する必要があります。他のすべてのフィールドは、ネットワーク バイト順で指定する必要があります。

packet length - IP header lengthFreeBSD/NetBSD では、IP の長さは同じにすることができます。

参照: Stevens/Fenner/Rudolph、Unix Network Programming Vol.1、p.739

これらの異常に対処するには、PGM ネットワーク プロトコルのユーザー空間実装、特定のコードを使用する必要があります。

https://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/packet_parse.c#76

実際、AutoConf を検出するのは非常に面倒です。すべてのパッケージには、プラットフォームごとにハードコードされていると思います。今週、まさにこの問題について提起されたバグ レポート (ヘッダー バイト オーダーの構成オプションが正しく検出されなかった)を見てきました。

于 2013-04-08T14:31:26.303 に答える
0

Mac 自体がそうしている可能性はほとんどありません。もしそうなら、それは根本的に IP プロトコルを壊すでしょう。おそらく、パケットをキャプチャして配信しているものは何でもrecvfrom()(おそらく、無差別なネットワークキャプチャを行っていますよね?)、Macが処理を完了した後にデータを変換しているものです。ireshark は下位レベルで動作し、実際のネットワーク データにアクセスできます。

于 2012-12-11T23:31:23.427 に答える