使用libpcap读取纳秒pcap文件

我有一个纳秒的libpcap(nanosec.pcap)文件,并且可以使用Wireshark显示纳秒时间戳(例如2.123456789)。 现在我想用C语言打开纳秒级libpcap文件,源代码如下。 当我尝试使用pcap_open_offine()打开nanosec.pcap时,它将返回“未知文件格式”错误。 此外,通过将nanosec.pcap标头处的幻数更改为普通pcap(0x1A2B3C4D)的幻数,我从终端(Ubuntu)获得了分段错误。 这里的任何专家都可以建议如何使用libpcap显示时间戳的纳秒部分? 提前致谢! 以下是代码:

#include  #include  #include  #include  #include  #include  #include  #include  struct UDP_hdr { u_short uh_sport; /* source port */ u_short uh_dport; /* destination port */ u_short uh_ulen; /* datagram length */ u_short uh_sum; /* datagram checksum */ }; /* Some helper functions, which we define at the end of this file. */ /* Returns a string representation of a timestamp. */ const char *timestamp_string(struct timeval ts); /* Report a problem with dumping the packet with the given timestamp. */ void problem_pkt(struct timeval ts, const char *reason); /* Report the specific problem of a packet being too short. */ void too_short(struct timeval ts, const char *truncated_hdr); void dump_UDP_packet(const unsigned char *packet, struct timeval ts, unsigned int capture_len) { struct ip *ip; struct UDP_hdr *udp; unsigned int IP_header_length; /* For simplicity, we assume Ethernet encapsulation. */ if (capture_len < sizeof(struct ether_header)) { /* We didn't even capture a full Ethernet header, so we * can't analyze this any further. */ too_short(ts, "Ethernet header"); return; } /* Skip over the Ethernet header. */ packet += sizeof(struct ether_header); capture_len -= sizeof(struct ether_header); if (capture_len ip_hl * 4; /* ip_hl is in 4-byte words */ if (capture_len ip_p != IPPROTO_UDP) { problem_pkt(ts, "non-UDP packet"); return; } /* Skip over the IP header to get to the UDP header. */ packet += IP_header_length; capture_len -= IP_header_length; if (capture_len uh_sport), ntohs(udp->uh_dport), ntohs(udp->uh_ulen)); } int main(int argc, char *argv[]) { pcap_t *pcap; const unsigned char *packet; char errbuf[PCAP_ERRBUF_SIZE]; struct pcap_pkthdr header; /* Skip over the program name. */ ++argv; --argc; /* We expect exactly one argument, the name of the file to dump. */ if ( argc != 1 ) { fprintf(stderr, "program requires one argument, the trace file to dump\n"); exit(1); } pcap = pcap_open_offline(argv[0], errbuf); if (pcap == NULL) { fprintf(stderr, "error reading pcap file: %s\n", errbuf); exit(1); } /* Now just loop through extracting packets as long as we have * some to read. */ while ((packet = pcap_next(pcap, &header)) != NULL) dump_UDP_packet(packet, header.ts, header.caplen); // terminate return 0; } /* Note, this routine returns a pointer into a static buffer, and * so each call overwrites the value returned by the previous call. */ const char *timestamp_string(struct timeval ts) { static char timestamp_string_buf[256]; sprintf(timestamp_string_buf, "%d.%09d", (int) ts.tv_sec, (int) ts.tv_usec); return timestamp_string_buf; } void problem_pkt(struct timeval ts, const char *reason) { fprintf(stderr, "%s: %s\n", timestamp_string(ts), reason); } void too_short(struct timeval ts, const char *truncated_hdr) { fprintf(stderr, "packet with timestamp %s is truncated and lacks a full %s\n", timestamp_string(ts), truncated_hdr); } 

这里的任何专家都可以建议如何使用libpcap显示时间戳的纳秒部分?

使用顶级的Git-trunk版本的libpcap,打开捕获文件

 pcap_open_offline_with_tstamp_precision(pathname, PCAP_TSTAMP_PRECISION_NANO, errbuf); 

并将pcap_pkthdr结构中的struct timeval视为秒和纳秒而不是秒和微秒(即,让你的程序将tv_usec视为纳秒而不是微秒 – 有点令人困惑,但我不确定是否有一个不太简单的解决方案) 。