Search code examples
udpipv6pcap

PCAP headers, obtaining UDP info


I'm trying to get the UDP information from a packet capture and I'm confused where that info lies. I know the Ethernet Header is 14 bytes and the IPv6 header is 40 bytes. Also, the UDP source port is the first 2 bytes in the UDP header. Therefore, it should be 14 + 40 - 1 = 53. So the UDP source port should be bytes 54 and 55. It's not right, I get 20016. For the example pcap file i used, it's supposed to be 51216. Everything else is right, determining IPv4 or IPv6 and determining if it's UDP OR 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));
      }

Thanks for any help or guide


Solution

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

    The UDP port is a 16 bit integer in network byte order. You instead print it as two 8 bit integers. Given that you print 20016 data[54] is probably 200 and data[55] is 16. Thus the correct value for the port is 200*256+16=51216 which is exactly what you expected.