2017-12-02 13 views
-1

パケットキャプチャからUDP情報を取得しようとしていますが、その情報がどこにあるのか混乱しています。イーサネットヘッダーは14バイト、IPv6ヘッダーは40バイトです。また、UDPソースポートは、UDPヘッダーの最初の2バイトです。したがって、14 + 40 - 1 = 53でなければなりません。したがって、UDPソースポートは54,55バイトでなければなりません.20016が得られます。私が使用したpcapファイルの例では、51216になっています。 IPv4またはIPv6を決定し、それがUDPかTCPかを判断します。UDP情報を取得するPCAPヘッダー

int main(int argc, char *argv[]) { 

    pcap_t *pcap_handle = NULL;    /* Handle for PCAP library */ 
    struct pcap_pkthdr *packet_hdr = NULL; /* Packet header from PCAP */ 
    const u_char *packet_data = NULL;  /* Packet data from PCAP */ 
    int ret = 0;       /* Return value from library calls */ 
    char use_file = 0;      /* Flag to use file or live capture */ 

    /* Setup the capture and get the valid handle. */ 
    pcap_handle = setup_capture(argc, argv, &use_file); 

    /* Loop through all the packets in the trace file. 
    * ret will equal -2 when the trace file ends. 
    * ret will never equal -2 for a live capture. */ 
    ret = pcap_next_ex(pcap_handle, &packet_hdr, &packet_data); 

    struct ether_header 
    { 
    u_int8_t ether_dhost[6]; /* destination eth addr */ 
    u_int8_t ether_shost[6]; /* source ether addr */ 
    u_int16_t ether_type;    /* packet type ID field */ 
    }; 

    struct ether_header *eptr; 
    char src[INET_ADDRSTRLEN]; 
    char dst[INET_ADDRSTRLEN]; 
    char src6[INET6_ADDRSTRLEN]; 
    char dst6[INET6_ADDRSTRLEN]; 

    while(ret != -2) { 
     if(valid_capture(ret, pcap_handle, use_file)){ 
     eptr = (struct ether_header *) packet_data; 

     fprintf(stdout,"%s -> ",ether_ntoa((const struct ether_addr *)&eptr->ether_shost)); 
     fprintf(stdout,"%s \n",ether_ntoa((const struct ether_addr *)&eptr->ether_dhost)); 
     if(packet_data[12] == 0x08 && packet_data[13] == 0x00) 
     { 
     printf(" [IPv4] "); 
     fprintf(stdout,"%s -> ", inet_ntop(AF_INET,(const void *)packet_data+26,src,INET_ADDRSTRLEN)); 
     fprintf(stdout,"%s\n", inet_ntop(AF_INET,(const void *)packet_data+30,dst,INET_ADDRSTRLEN)); 
     if(packet_data[23] == 0x06) 
     { 
      printf(" [TCP] \n"); 
     } 
     else if(packet_data[23] == 0x11) 
     { 
     } 
     else{ 
     printf(" [%d] \n",packet_data[23]); 
     } 
     } 
     else if(packet_data[12] == 0x86 && packet_data[13] == 0xdd) 
     { 
     printf("[IPv6] "); 
     printf("%s -> ", inet_ntop(AF_INET6, (const void *)packet_data+22, src6, INET6_ADDRSTRLEN)); 
     printf("%s \n", inet_ntop(AF_INET6, (const void *)packet_data+38, dst6, INET6_ADDRSTRLEN)); 
     if(packet_data[20] == 0x06) 
     { 
      printf(" [TCP] \n"); 
     } 
     else if(packet_data[20] == 0x11) 
     { 
      printf("[UDP] Source: %d",packet_data[54]); //problem here 
      printf("%d \n",packet_data[55]); //problem here 
     } 
     else{ 
     printf(" [%d] \n",packet_data[20]); 
     } 
     } else { 
      fprintf(stdout," [%d] \n",ntohs(eptr->ether_type)); 
     } 

任意のヘルプまたはガイド

+0

Awwなぜこの質問は投票されたのですか? – Mike1982

+0

あなたの質問には問題を再現するためのコードがありませんので、間違ったことを言うのは難しいです。しかし、あなたの引数は、pcapリンクタイプがDLT_EN10MBで、UDPがIPv6パケットの最初の拡張ヘッダである場合にのみ正しいです。 –

+0

ああ。私は自分のコードを添付します。 DLT_EN10MBの内容は不明ですが、IPv6ヘッダーのプロトコル値に基づいてUDBであるかどうかを判断するチェックがあります。私はちょうどポートに間違った番号を取得しています。 – Mike1982

答えて

2
 printf("[UDP] Source: %d",packet_data[54]); //problem here 
     printf("%d \n",packet_data[55]); //problem here 

ためのおかげで、UDPポートは、ネットワークバイト順で16ビットの整数です。代わりに2つの8ビット整数として出力します。 20016data[54]を印刷すると、おそらく200data[55]16です。したがって、ポートの正しい値は200*256+16=51216であり、これはまさにあなたが期待した値です。

+0

ahhhh okを参照してください。正しい配列インデックスを取得しています。正しく翻訳されていません。 – Mike1982

+0

@ Mike1982:正しい。それで、ほとんどの場合、質問にコードを含めるほうがよいのです。 –

+0

ありがとうございます。それで、私のためにこの変換を行う関数が組み込まれていますか?私はpacket_data [54] * 256 + packet_data [55]を実行しましたが、ハードコーディングが理想的な解決策であるかどうかはわかりません。私のためにこれを行うネットワーク機能が組み込まれていますか? – Mike1982

関連する問題