2

IPv4ヘッダーを受け取り、それをより小さなヘッダーに圧縮するロード可能なカーネルモジュールとして、IPヘッダー圧縮プロトコルを実装しています(「iphc」ヘッダーと呼びましょう)。

これを行うには、発信パケットの場合、NF_IP_POST_ROUTINGルーティングの決定が完了した後に netfilter フックを使用してパケットを取得しました。次に、IP ヘッダーを IPHC ヘッダー (圧縮された IP) に置き換え、ethertype を別のものに変更し、それをスタックに (イーサネットに) 送信して送信します。私が見ているところによると、NF_IP_POST_ROUTINGフックでパケットをインターセプトすると、MAC ヘッダーはまだ追加されていません。

私が持っていたいくつかの質問:

  1. IP ヘッダーを交換すると、MAC ハードウェア アドレスを検出するイーサネットの機能に影響しますか? 関数で、ip_finish_output2()(関数を使用して) skbuff の dst 値を取得しskb_dst()て、近隣テーブルで ARP エントリを検索することがわかりました。IP ヘッダーを IPHC ヘッダーに交換してプロトコルを変更するだけの場合、ARP ルックアップは失敗しますか? skbuff の「dst」フィールドには触れていないと思います。

  2. IP ヘッダーを IPHC ヘッダーに置き換え、Ethertype を変更し、スタックに戻すだけで十分ですか? または、ip_finish_output2に戻さずに自分で直接送信する必要があります

何らかの理由で、#2 を実行すると、コードがクラッシュします。以下は、NF_IP_POST_ROUTING netfilter フック (skb が渡される) にフックした後に実行しようとしているもののサンプルです。

struct iphc *my_hdr;

/* stripping the IPv4 header from skbuff */
skb_pull(skb, sizeof (struct iphdr));

/* adding my header skb */
skb_push(skb, IPHC_HDR_SIZE);

/* reset network header */
skb_reset_network_header(skb);

my_hdr = (struct iphc *)skb;

my_hdr->field1 = 1;
my_hdr->field2 = 2;

/* change ethertype */
skb->protocol = __constant_htons(ETH_P_IPHC);

return NF_ACCEPT;

ここで何か不足していますか?ありがとう!

4

1 に答える 1

0

skb_pull() と skb_push() は、skb->data が現在どこを指しているかを知らずに使用することはできません。

パケットが NF_IP_POST_ROUTING で傍受された場合、ほとんどの場合、skb->data はフレームの先頭 (MAC ヘッダーの先頭でもある) を指しています。

したがって、skb_push() 操作を行う前に、まず skb_pull() を使用して MAC ヘッダーを取り出し、次に IP ヘッダーを取り出す必要があります。次に、データ (MAC+IPHDR) を (MAC+IPHC) に縮小し、結合された (MAC+IPHC) をまとめて skb_push() します。または、IPHC を最初にプッシュしてから MAC をプッシュすることもできます。

これらの skb 関数の詳細については、skbuff.h を参照してください。skb に関する優れたチュートリアルは、ここにあります。

于 2012-11-02T06:43:54.100 に答える