4

Linuxカーネル用のドライバーに取り組んでいます。プロジェクトを成功させるには、イーサネットフレームに追加されるパディングの量を最小サイズの60バイト(FCSを除く)よりも小さくする必要があります。私はこれらのフレームを生成していません。処理のためにNICで受信しています。

を持っているstruct sk_buff場合、パケットに追加された後続ゼロの量を直接決定することは可能ですか?

もちろん、パケット全体を調べて、最上位層のコンテンツがどこで終了するかを把握し、フレームサイズ(この場合は60バイト)からその位置を単純に差し引くことで、その値を決定できます。しかし、に保存されている情報から直接それを行うためのより効率的な方法はありstruct sk_buffますか?

4

2 に答える 2

2

編集:私が知る限り、イーサネットヘッダーを実際に確認せずに、sk_buff構造体を使用してゼロパディングを直接チェックする方法はありません。これは非常に簡単です。

とは言うものの、いくつかの単純なポインター演算とバイト減算を使用すると、IPデータの長さフィールドを使用してパディングを把握できます。

これはsk_buffの良いリファレンスです:http: //vger.kernel.org/~davem/skb_data.html

そして、これはパケット構造の良いリファレンスであり、「データ」内の一番下の画像の「長さ」フィールドを示しています。

http://nerdcrunch.com/wp-content/uploads/2011/05/Ethernet-Frame-Explained.png

これが行われなければならない方法だと思いますが、以前に維持していたように解析する必要はありません。ヘッダー/データ構造フィールドは、解析せずにポインター/配列を介して直接参照/削除できるように設定されています。次に、生のパケット長からヘッダー+データ長を差し引くことで、すべてデータを検査せずにパディングを取得できます。

お役に立てば幸いです。

また、ベストプラクティスとして、802.3の両方のバージョンのドライバーアカウントを使用している必要があります。これを行うには、Ethertype/lengthフィールドを調べます。値が1536(0x0600)より大きい場合、それはイーサネットIIタイプのパケットであり、フィールドにはイーサネットパケットが何をカプセル化するかを示すイーサタイプが含まれます。「Ethertype」のウィキペディアで人気のあるものがいくつかあります。

たとえば、IP=0x0800です。フィールドがEthertypeを指定している場合、パディングを見つけるために、内部のデータ長フィールドを見つけることに頼らなければなりません。そうでない場合、イーサネットベースのLANの多くはまだそうではありませんが、長さとして指定されたフィールドを直接使用して作業を行うことができます。

于 2013-01-22T16:15:17.927 に答える
0

IPv4はほぼ同じことを行いますが、おそらくこれ以上の方法はありません。ip_rcv()を確認してください:

len = ntohs(iph->tot_len);
if (skb->len < len) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INTRUNCATEDPKTS);
        goto drop;
} else if (len < (iph->ihl*4))
        goto inhdr_error;

/* Our transport medium may have padded the buffer out. Now we know it
 * is IP we can trim to the true length of the frame.
 * Note this now means skb->len holds ntohs(iph->tot_len).
 */
if (pskb_trim_rcsum(skb, len)) {
        IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
        goto drop;
}
于 2013-01-26T07:04:29.653 に答える