【问题标题】:PCAP headers, obtaining UDP infoPCAP 标头,获取 UDP 信息
【发布时间】:2017-12-02 01:00:02
【问题描述】:

我正在尝试从数据包捕获中获取 UDP 信息,但我很困惑该信息的位置。我知道以太网报头是 14 字节,而 IPv6 报头是 40 字节。此外,UDP 源端口是 UDP 标头中的前 2 个字节。因此,应该是 14 + 40 - 1 = 53。所以 UDP 源端口应该是字节 54 和 55。这是不对的,我得到 20016。对于我使用的示例 pcap 文件,它应该是 51216。其他一切都是对,确定 IPv4 或 IPv6 并确定它是 UDP 还是 TCP。

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));
      }

感谢您的帮助或指导

【问题讨论】:

  • 哇,为什么这个问题被否决了?
  • 您的问题缺少重现问题的任何代码,因此很难判断您做错了什么。但是,只有当 pcap 链接类型为 DLT_EN10MB 并且 UDP 是 IPv6 数据包中的第一个扩展标头时,您的论点才正确。
  • 啊好的。我会附上我的代码。不确定 DLT_EN10MB 是什么,但我有一个检查,根据 IPv6 标头中的协议值确定它是否是 UDB。我只是得到了错误的端口号。
  • DLT_EN10MB 是可用于 pcap 文件的众多链接类型之一。不同的链接类型有不同的大小,因此您需要检查 pcap 文件使用的类型。见tcpdump.org/manpages/pcap_datalink.3pcap.txt

标签: udp ipv6 pcap


【解决方案1】:
        printf("[UDP] Source: %d",packet_data[54]); //problem here
        printf("%d \n",packet_data[55]); //problem here

UDP 端口是一个按网络字节顺序排列的 16 位整数。您改为将其打印为两个 8 位整数。假设您打印20016 data[54] 可能是200data[55]16。因此,端口的正确值是 200*256+16=51216,这正是您所期望的。

【讨论】:

  • ahhhh 好的,所以我得到了正确的数组索引,只是翻译不正确。
  • @Mike1982:正确。这就是为什么在问题中包含代码几乎总是更好的原因:)
  • 谢谢。那么是否有一个内置函数可以为我进行这种转换?我做了 packet_data[54] * 256 + packet_data[55] 并且它有效,但我不知道硬编码是否是一个理想的解决方案。是否有内置的网络功能可以为我做到这一点?
  • htons。但是当然你必须首先将两个字节视为uint16_t,这可以通过C中的一些转换来完成,即htons(*(uint16_t*)(packet_data+54))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-29
  • 2011-05-28
  • 2018-05-16
  • 1970-01-01
  • 2022-12-12
相关资源
最近更新 更多