Nikolai Fetissov is correct - you must check whether pcap_next()
returns NULL or not. It might return NULL if, for example, the timeout expires and no packets have arrived. In that case, you should keep looping until it returns a non-null value.
However, it could also return NULL if there's an error, and that error might mean that you won't get any more packets. A better routine to use is pcap_next_ex()
, which returns returns 1 if the packet was read without problems, 0 if packets are being read from a live capture and the timeout expired, -1 if an error occurred while reading the packet, and -2 if packets are being read from a savefile and there are no more packets to read from the savefile.
In your case, you're doing a live capture, so you should use pcap_next_ex()
, and loop until it returns either 1, in which case you print the packet information, or -1, in which case you report an error and exit:
int status;
while ((status = pcap_next_ex(descr, &pkthdr, &packet)) == 0)
;
if (status == -1) {
fprintf(stderr, "pcap_next_ex failed: %s\n", pcap_geterr(descr));
exit(1);
}
iphdr = (struct ip *)(packet+14);
tcphdr = (struct tcphdr *)(packet+14+20);
printf("test1\n"); fflush( stdout );
printf("SEQ: %d\n", ntohl(tcphdr->th_seq) ); fflush( stdout );
printf("test2\n");
pcap_close(descr);
Note also that there's no guarantee that the IPv4 header is 20 bytes long - it could be longer, so you need to extract the header length from the first byte of the IPv4 header (the header length/version field), multiply it by 4 (as it's in units of 4-byte words), and use that when calculating the address of the TCP header, rather than using a hard-coded 20.
In addition, you should also make sure that the link-layer header type of the device, as returned by pcap_datalink(descr)
, is DLT_EN10MB
, to make sure the packets have Ethernet headers rather than some other type of header.
In addition, I just copied your printf code, as I was concentrating on the capture problem. Somebody else added an ntohl()
call, which is necessary when printing the sequence number - multi-byte numerical fields in IP and TCP headers are in "network byte order", i.e. big-endian, but you might be running on a little-endian machine, so the sequence number has to be converted to the host byte order before printing it.