-1

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

Mike1982
  • 439
  • 10
  • 26
  • Aww why did this question get down voted? – Mike1982 Dec 02 '17 at 03:48
  • Your question is missing any code to reproduce your problem so it is hard to tell what you do wrong. But, your arguments are only correct if pcap link type is DLT_EN10MB and UDP is the first extension header in the IPv6 packet. – Steffen Ullrich Dec 02 '17 at 08:31
  • ah ok. I'll attach my code. Not sure what the DLT_EN10MB is, but I have a check that determines if it's UDB based on the protocol value in the IPv6 header. I'm just getting the wrong numbers for port. – Mike1982 Dec 02 '17 at 15:54
  • DLT_EN10MB is one one the many link types which might be use for the pcap file. Different link types have different sizes so you need to check what type the pcap file uses. See https://www.tcpdump.org/manpages/pcap_datalink.3pcap.txt – Steffen Ullrich Dec 02 '17 at 18:38

1 Answers1

2
        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.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • ahhhh ok, so I am getting the correct array indexes, it's just not translating properly. – Mike1982 Dec 02 '17 at 19:11
  • @Mike1982: Correct. And that's why it is almost always better to include the code in the question :) – Steffen Ullrich Dec 02 '17 at 19:17
  • Thank you. So is there a built in function that does this conversion for me? I did packet_data[54] * 256 + packet_data[55] and it works, but I don't know if hardcoding that is an ideal solution. Is there a built in networking function that does this for me? – Mike1982 Dec 02 '17 at 19:43
  • There is [htons](https://linux.die.net/man/3/htons). But of course you have to do treat the two bytes as an `uint16_t` first which can be done with some casting in C, i.e. `htons(*(uint16_t*)(packet_data+54))` – Steffen Ullrich Dec 02 '17 at 20:10