2017-08-25 14 views
5

私は現在、パケットペイロードを学習経験として変更するカーネルモジュールを作成しています。私はパケットの変更を行ったが、今はオリジナルの後にこの新しい変更されたパケットを送信したい(私はオリジナルをドロップしたくない)。 SKBを送信するカーネル関数を見つけることができないようです。私はdev_queue_xmit(nskb)を試しましたが、それはカーネルパニックを引き起こし、私もskb->next = nskbを試しましたが、それは何もしません。 SKBのリスト処理を実装する必要がありますか?私はこの記事からseems to be outdated以来、それを行う方法がわかりません。SKBをカーネル空間から送信するために

EDIT:

だから私はdev_queue_xmit(nskb)を呼び出すときに、私は誤ってSKBを削除し、ネットフィルターからパニックを引き起こすdev_queue_xmit(SKB)をやっていたカーネルパニックを修正することができました。問題はすべてが機能するようになりましたが、重複したパケットが送信されているのを見ていません。送信された2番目のパケットのトレースはありません。マシン上のTCPDumpに何も表示されず、ターゲットのTPCDumpにも何も表示されません。以下は私のコードです。次のように

unsigned int in_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { 
    struct sk_buff *nskb = skb_copy(skb, GFP_KERNEL); 
    /* Various other variables not relevant to the problem */ 
    __u32 saddr, daddr; 
    saddr = ntohl(iph->saddr); 
    if (saddr == ipToInt(10,0,2,12) || saddr == ipToInt(10,0,2,13)) { 
     /*For loop that saves the payload contents into a variable */ 

     /* Here is where the problem is, 
     I have this if statement to prevent a feedback loop 
     then if the ip matches, I call dev_queue_xmit(nskb) 
     which is supposed to send out sk_buff's, but TCPDump doesn't 
     show anything on any computer */ 
     if (saddr == ipToInt(10,0,2,13)) { 
      dev_queue_xmit(nskb); 
     } 

     /* Rest of the code that isn't relevant to sending packets */ 
    } 
    return NF_ACCEPT; 
} 

マイネットワークの設定があり、それは3のUbuntu ServerのVMの、それらのすべては、ホストコンピュータから(それが重要ならば、私はこの時点では分からないのMacOS)にSSH'dされているのです。上記のカーネルモジュールを実行しているコンピュータは、他の2つのVMを双方向にスプーフィングします。他の2つのVMは、netcatセッションを介してお互いに話をします。私はip 10.0.2.13でVMから1つのメッセージを送信すると、10.0.2.12では同じメッセージが2つ表示されることを期待しています。私は謝辞番号を知っていると思って接続を壊すだろうが、私はそれを取得していない。 3台のコンピュータのいずれかのTCPDumpは、送信されるはずのパケット以外に何も表示しません。

私はこれまでにdev_queue_xmit(nskb)nskb->dev->netdev_ops->ndo_start_xmit(nskb, skb->dev)を試しました。

答えて

0

skb_copyはskbのイーサネットヘッダーをコピーしないので、送信されたパケットは決してその宛先に届きません。

1

私が覚えている限り、dev_queue_xmit()は正しい送信手順です。問題は、あなたが送ってほしいskbをどのように準備しているかです。また、カーネルパニックが発生したときにdmesgからcalltraceを与えてください。あなたはskb-> devを設定しますか?

+0

私がチェックするとDmesgが空で、skb-> devが設定されていると思います。 'if(skb-> dev)'を実行するとtrueを返します。また、今のところ私は2番目のパケットを送信しようとしているので、ネットフィルタ関数によって私に与えられたskbは、2つの重複パケットが見えるようにするために 'dev_queue_xmit(skb)'を実行します。 – MacStation

+0

最も重要なことは、カーネルパニックが発生したときにdmesg(画面上のもの)が正確である必要があることです。私は、カーネルが発生したときにシステムファイルには記録されないかもしれないことを知っています。したがって、シリアルコンソールを接続した状態でセカンドシステムを使用し、このコンソールのダンプを実行できます。 – user2699113

+0

2番目のこと - どのようにskbをコピーしますか? – user2699113

関連する問題