2

libpcap を使用して TCP ペイロード情報を表示しようとしています。これを行うには、メモリ内のペイロードの位置を特定する必要があります。このProgramming With Pcapガイドを使用して、リクエスト ペイロードの場所を特定しています。サービス (ループバック アダプター) と同じマシン上に存在するクライアントから発信されたパケットをスニッフィングすると、IP ヘッダーの長さが 0 になります。要求ペイロードの場所を見つけることができません。これは、ループバック アダプターをリッスンするときに予期されることですか? アダプター「lo0」をリッスンする MacOSx 10.8 システムで作業しています。

ここに私がしようとしているものがあります:

    //this callback is called when a packet is found
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
    ethernet = (struct sniff_ethernet*)(packet);
    ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0
    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);

}

構造体 sniff_ip:

#define SIZE_ETHERNET 14

 /* IP header */
struct sniff_ip {
    u_char ip_vhl;      /* version << 4 | header length >> 2 */
    u_char ip_tos;      /* type of service */
    u_short ip_len;     /* total length */
    u_short ip_id;      /* identification */
    u_short ip_off;     /* fragment offset field */
#define IP_RF 0x8000        /* reserved fragment flag */
#define IP_DF 0x4000        /* dont fragment flag */
#define IP_MF 0x2000        /* more fragments flag */
#define IP_OFFMASK 0x1fff   /* mask for fragmenting bits */
    u_char ip_ttl;      /* time to live */
    u_char ip_p;        /* protocol */
    u_short ip_sum;     /* checksum */
    struct in_addr ip_src,ip_dst; /* source and dest address */
};
4

1 に答える 1

8
ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET); <-- the result is 0

ループバック インターフェイスでキャプチャしている場合、そのコードは間違っています。OS X (または libpcap/WinPcap をサポートするその他の OS) のすべてのインターフェイスがイーサネット ヘッダーを提供するわけではありません。を呼び出しpcap_datalink()てキャプチャ デバイス (または でキャプチャ ファイルを読み取る場合はキャプチャ ファイルpcap_open_offline()) のリンク層タイプを見つけ、それに基づいてパケットのリンク層ヘッダーを解析する必要があります。

完全なリストについては、pcap リンク層ヘッダー タイプのリストを参照してください。

DLT_EN10MBイーサネット デバイスのリンク層ヘッダー タイプです (「10MB」は歴史的なものであり、ヘッダーが異なる 3MB 対 10MB イーサネットを指しますDLT_EN10MB。10 MB と 100 MB と 1 GB と 10 GB と 40 GB と 100 GB に適用されます)および...イーサネット)、および偽のイーサネット ヘッダーを提供する一部の非イーサネット デバイス。

ほとんどの BSD および OS X でのループバック デバイスのリンク層ヘッダー タイプはDLT_NULL; PF_リンク層ヘッダーの種類のページにあるように、プロトコルの OS の値を含む 4 バイトのリンク層ヘッダーがあり、おそらく IPv4 または IPv6 になります。

于 2013-06-16T02:11:16.340 に答える