1

状況は次のとおりです。私のシナリオでは、A、B、Cの3台のコンピューターがあります。

コンピューターAはコンピューターBにデータを送信します。コンピューターBはこれらのパケットをpcapでキャプチャし、ヘッダーを追加し、チェックサムをやり直して、コンピューターCへの別のイーサネットインターフェイスから注入します。したがって、基本的にAはCに送信しますが、Cの観点からはデータはコンピューターBから来ています。

私の問題はこれです:キャプチャされたパケットの分析に関するTCPDUMPのチュートリアルに従って、オフセットを計算し、タイプキャストを使用してイーサネット、IP、およびtcpヘッダー構造を取得する方法を学びました。その方法を以下に示します。

ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
    printf("   * Invalid IP header length: %u bytes\n", size_ip);
    return;
}
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
    printf("   * Invalid TCP header length: %u bytes\n", size_tcp);
    return;
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);

キャプチャしたパケットを挿入してコンピュータBからコンピュータCに送信したいので、送信元/宛先情報の一部を変更し、完了したらチェックサムを再計算する必要があります。ただし、私の問題は、このデータがイーサネットヘッダー、IPヘッダー、およびTCPヘッダーの構造に分割されているため、使用できるに戻すにはどうすればu_charよいpcap_injectですか?

ここで何らかの連結を行うことは可能ですか?

4

1 に答える 1

1

ここに表示されているコードから、libpcapキャプチャしたメモリを実際に分析しているわけではありません。各キャスト操作は、ポインターから始まるバイトをどのように処理するか、つまり、それらのオブジェクトのサイズ、データのどの部分を見つけるためのオフセット、およびそれらの長さをコンパイラーに伝えるだけです。

これらのポインタを介してこのメ​​モリを変更すると、プロセスメモリ内の唯一のコピーが変更され、「より基本的な」ポインタのいくつかを使用して、メモリのブロック全体を渡すことができますsendmsg(2)。データを再構築します。分解することはありません。

アップデート

パケットをネットワークに戻すには、raw(7)ソケット タイプを使用する必要があります。ソケットを介して TCP パケットを送信するには、IPPROTO_RAWsocket オプションが必要です。raw(7)そうしないと、すべてのTCP パケットがraw(7)開いたソケットに送信され、マシン上のネットワークが使いにくくなります。

ソケットは、いくつかのraw(7)再計算タスクを実行します。

   A protocol of IPPROTO_RAW implies enabled IP_HDRINCL and is
   able to send any IP protocol that is specified in the passed
   header.  Receiving of all IP protocols via IPPROTO_RAW is not
   possible using raw sockets.

          ┌───────────────────────────────────────────────────┐
          │IP Header fields modified on sending by IP_HDRINCL │
          ├──────────────────────┬────────────────────────────┤
          │IP Checksum           │Always filled in.           │
          ├──────────────────────┼────────────────────────────┤
          │Source Address        │Filled in when zero.        │
          ├──────────────────────┼────────────────────────────┤
          │Packet Id             │Filled in when zero.        │
          ├──────────────────────┼────────────────────────────┤
          │Total Length          │Always filled in.           │
          └──────────────────────+────────────────────────────┘

   If IP_HDRINCL is specified and the IP header has a nonzero
   destination address then the destination address of the
   socket is used to route the packet.  When MSG_DONTROUTE is
   specified, the destination address should refer to a local
   interface, otherwise a routing table lookup is done anyway
   but gatewayed routes are ignored.

   If IP_HDRINCL isn't set, then IP header options can be set on
   raw sockets with setsockopt(2); see ip(7) for more
   information.

カーネルがあなたのためにしてくれることは何でも再計算させてください。

于 2011-11-19T10:10:26.600 に答える