0
votes

I started to write an application which will read RTP/H.264 video packets from an existing .pcap file, I need to read the packet size. I tried to use packet->len or header->len, but it never displays the right number of bytes for packets (I'm using wireshark to verify packet size - under Length column). How to do it? This is part of my code:

while (packet = pcap_next(handle,&header)) {

  u_char *pkt_ptr = (u_char *)packet;
  struct ip *ip_hdr = (struct ip *)pkt_ptr; //point to an IP header structure 
  struct pcap_pkthdr  *pkt_hdr =(struct pcap_pkthdr *)packet;

  unsigned int packet_length = pkt_hdr->len;
  unsigned int ip_length = ntohs(ip_hdr->ip_len);
  printf("Packet # %i IP Header length: %d bytes, Packet length: %d bytes\n",pkt_counter,ip_length,packet_length);


Packet # 0 IP Header length: 180 bytes, Packet length: 104857664 bytes
Packet # 1 IP Header length: 52 bytes, Packet length: 104857600 bytes
Packet # 2 IP Header length: 100 bytes, Packet length: 104857600 bytes
Packet # 3 IP Header length: 100 bytes, Packet length: 104857664 bytes
Packet # 4 IP Header length: 52 bytes, Packet length: 104857600 bytes
Packet # 5 IP Header length: 100 bytes, Packet length: 104857600 bytes

Another option I tried is to use: pkt_ptr-> I get:

read_pcapfile.c:67:43: error: request for member ‘len’ in something not a structure or union

2

2 Answers

2
votes

You should be using header.len.

unsigned int packet_length = header.len;
2
votes
while (packet = pcap_next(handle,&header)) {

  u_char *pkt_ptr = (u_char *)packet;

Don't do that; you're throwing away the const, and you really should NOT be modifying what the return value of pcap_next() points to.

  struct ip *ip_hdr = (struct ip *)pkt_ptr; //point to an IP header structure

That will point to an IP header structure ONLY if pcap_datalink(handle) returns DLT_RAW, which it probably will NOT do on most devices.

If, for example, pcap_datalink(handle) returns DLT_EN10MB, packet will point to an Ethernet header (the 10MB is historical - it's used for all Ethernet speeds other than the ancient historical 3MB experimental Ethernet at Xerox, which had a different header type).

See the list of link-layer header type values for a list of the possible DLT_ types.

  struct pcap_pkthdr  *pkt_hdr =(struct pcap_pkthdr *)packet;

That won't work, either. The struct pcap_pkthdr for the packet is in header.

  unsigned int packet_length = pkt_hdr->len;

As per my earlier comment, that won't work. Use header.len instead.

(And bear in mind that, if a "snapshot length" shorter than the maximum packet size was specified in the pcap_open_live() call, or specified in a pcap_set_snaplen() call between the pcap_create() and pcap_activate() calls, header.caplen could be less than header.len, and only header.caplen bytes of the packet data will actually be available.)

  unsigned int ip_length = ntohs(ip_hdr->ip_len);

And, as per my earlier comment, that probably won't work, either.