1

私のアプリケーションでは、次の命令で raw ソケット (LINUX カーネル 3.8.5) を開きます。

::socket( PF_PACKET, SOCK_RAW, htons((uint16_t)ETH_P_ALL));

すべて正常に動作しています。受信して別のインターフェイスに送信できます。しかし、ある時は

::recvfrom() 

そのソケットでは、1518 (1504 ペイロード バイト + 14 ETH_HLEN) が返されます。

この 1518 バイトのバッファを送信しようとすると、命令が

::send(......)

EMSGSIZE (メッセージが長すぎます) を返します。

私の NIC インターフェイスでは MTU が 1500 であるため、::recvfrom で最大 1514 (ペイロード + ETH_HLEN) バイトが取得されると予想されることに注意してください。

ethtype は 0x0800 であるため、vlan タグ付きフレームではないため、これらの 4 バイトの「余分な」は vlan タグによるものではありません

説明はありますか?

4

2 に答える 2

0

問題の詳細については、問題をデバッグする atm には、次の構成があります。

eth0(サーバー1)------------->eth0(サーバー2)-----NAT----->ダミー0(サーバー2)

Server1 と Server2 の間にはスイッチはなく、ケーブルだけであり、dummy0 はダミー ネットワーク モジュールで取得された NIC です。

eth0(Server1)の「TX側」とeth0(Server2)の「RX側」でスニッフィングすると、次のようになります。

送信側:

1514 bytes, sequence number  15476 
1514 bytes, sequence number  15477 
1514 bytes, sequence number  15478 
1514 bytes, sequence number  15479

RX側でも同じことを期待しますが、次のようになります。

1514 bytes, sequence number 15476
1518 bytes, sequence number 15477
1514 bytes, sequence number 15479

面白いことに、15478 は受信されませんでしたが、これらの 1518 バイト (シーケンス番号 15477) の最後の 4 バイトは、失われた eth パケットのペイロードの最初の 4 バイトです。

解決済み: それは GRO オプションでした。実際、::rcv のオプションのおかげで、一度に 2 つ以上のイーサネット フレームを取得することができました。これが、たとえば、シーケンス番号が "表示" されなかった理由です (実際には以前のフレームとマージされていました)。 1 つ)、一部のパケットで 1518 を取得したという事実は、::rcv で渡されたバッファーのサイズが原因であり、はるかに大きなバッファーを渡して、実際にコンテンツを失うことはありません。

于 2013-06-28T16:40:51.077 に答える