On 2013/05/23 14:42, Stuart Henderson wrote: > On 2013/05/23 07:15, Theo de Raadt wrote: > > > what about teduing bpf_timeval from net/bpf.h > > > > Sounds like you don't read commit logs. > > > > bpf_timeval exists so that pcap files can be portable between > > machines, and hopefully between systems too. > > > > Unfortunately the upstream tcpdump people did not adopt it > > because they have no vision for doing things right. > > > > Upstream used a different method to get portable save files; they changed > the file handling routines but continued using timevals internally. The > version we have in our tree has an unused "struct pcap_sf_pkthdr" which > is the first step of this. > > Diff below should have no actual change at present but would allow for > later switching pcap_pkthdr back to timeval if wanted. > > https://github.com/the-tcpdump-group/libpcap/commit/56c33c01be6cfd5dd1cde7ce715d8ad6dd45815a
FWIW here's a larger diff which switches bpf/pcap back to using struct timeval internally but maintains file compatibility. No idea if it would be considered acceptable but it makes things a lot easier in ports land. As happened when switching to bpf_timeval before, this breaks kernel compat (notably things like dhclient/pflogd) so userland and kernel need updating together. Also a handful of ports need tweaks to cope with it (which I'll gladly do: daq, freeradius, nmap, packit, py-pcapy, tcpslice, trafshow). I took my 64-bit time_t system back to -current so can't test now, but I think as-is nmap will probably be fairly broken when we switch across.. Another option to fix nmap might be to change all of nmap's timevals over to bpf_timeval, add a wrapper for gettimeofday to return a bpf_timeval, and adjust the (180+) callers to use that. Manually changing just the relevant calls, and keeping them in-sync through port updates, isn't really viable (and I don't really see any way we can sanely feed this stuff upstream and expect them to keep it working..) With the below diff, we just need to remove some patches (i.e. http://junkpile.org/nmap.diff). This helps, but doesn't completely fix, the problem with -sS that Rodolfo mentioned - with this -sS -T 5 runs in about 70 seconds. Index: lib/libpcap/shlib_version =================================================================== RCS file: /cvs/src/lib/libpcap/shlib_version,v retrieving revision 1.13 diff -u -p -r1.13 shlib_version --- lib/libpcap/shlib_version 25 May 2012 01:58:08 -0000 1.13 +++ lib/libpcap/shlib_version 23 May 2013 15:49:58 -0000 @@ -1,2 +1,2 @@ -major=7 +major=8 minor=0 Index: lib/libpcap/pcap-int.h =================================================================== RCS file: /cvs/src/lib/libpcap/pcap-int.h,v retrieving revision 1.12 diff -u -p -r1.12 pcap-int.h --- lib/libpcap/pcap-int.h 25 May 2012 01:58:08 -0000 1.12 +++ lib/libpcap/pcap-int.h 23 May 2013 15:45:27 -0000 @@ -121,12 +121,17 @@ struct pcap { struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ }; +struct pcap_timeval { + u_int32_t tv_sec; + u_int32_t tv_usec; +}; + /* * How a `pcap_pkthdr' is actually stored in the dumpfile. */ struct pcap_sf_pkthdr { - struct bpf_timeval ts; /* time stamp */ + struct pcap_timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; Index: lib/libpcap/pcap.h =================================================================== RCS file: /cvs/src/lib/libpcap/pcap.h,v retrieving revision 1.15 diff -u -p -r1.15 pcap.h --- lib/libpcap/pcap.h 25 May 2012 01:58:08 -0000 1.15 +++ lib/libpcap/pcap.h 23 May 2013 15:45:27 -0000 @@ -92,7 +92,7 @@ typedef enum { * packet interfaces. */ struct pcap_pkthdr { - struct bpf_timeval ts; /* time stamp */ + struct timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; Index: lib/libpcap/savefile.c =================================================================== RCS file: /cvs/src/lib/libpcap/savefile.c,v retrieving revision 1.10 diff -u -p -r1.10 savefile.c --- lib/libpcap/savefile.c 25 May 2012 01:58:08 -0000 1.10 +++ lib/libpcap/savefile.c 23 May 2013 15:45:27 -0000 @@ -212,20 +212,26 @@ pcap_fopen_offline(FILE *fp, char *errbu static int sf_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char *buf, int buflen) { + struct pcap_sf_pkthdr sf_hdr; FILE *fp = p->sf.rfile; /* read the stamp */ - if (fread((char *)hdr, sizeof(struct pcap_pkthdr), 1, fp) != 1) { + if (fread(&sf_hdr, sizeof(struct pcap_sf_pkthdr), 1, fp) != 1) { /* probably an EOF, though could be a truncated packet */ return (1); } if (p->sf.swapped) { /* these were written in opposite byte order */ - hdr->caplen = SWAPLONG(hdr->caplen); - hdr->len = SWAPLONG(hdr->len); - hdr->ts.tv_sec = SWAPLONG(hdr->ts.tv_sec); - hdr->ts.tv_usec = SWAPLONG(hdr->ts.tv_usec); + hdr->caplen = SWAPLONG(sf_hdr.caplen); + hdr->len = SWAPLONG(sf_hdr.len); + hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec); + hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec); + } else { + hdr->caplen = sf_hdr.caplen; + hdr->len = sf_hdr.len; + hdr->ts.tv_sec = sf_hdr.ts.tv_sec; + hdr->ts.tv_usec = sf_hdr.ts.tv_usec; } /* * We interchanged the caplen and len fields at version 2.3, @@ -334,10 +340,15 @@ void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { register FILE *f; + struct pcap_sf_pkthdr sf_hdr; f = (FILE *)user; + sf_hdr.ts.tv_sec = h->ts.tv_sec; + sf_hdr.ts.tv_usec = h->ts.tv_usec; + sf_hdr.caplen = h->caplen; + sf_hdr.len = h->len; /* XXX we should check the return status */ - (void)fwrite((char *)h, sizeof(*h), 1, f); + (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f); (void)fwrite((char *)sp, h->caplen, 1, f); } Index: usr.sbin/tcpdump/interface.h =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/interface.h,v retrieving revision 1.61 diff -u -p -r1.61 interface.h --- usr.sbin/tcpdump/interface.h 6 Apr 2010 16:01:57 -0000 1.61 +++ usr.sbin/tcpdump/interface.h 23 May 2013 15:45:27 -0000 @@ -147,9 +147,8 @@ extern const u_char *snapend; #define TCHECK(var) TCHECK2(var, sizeof(var)) struct timeval; -struct bpf_timeval; -extern void ts_print(const struct bpf_timeval *); +extern void ts_print(const struct timeval *); extern int fn_print(const u_char *, const u_char *); extern int fn_printn(const u_char *, u_int, const u_char *); Index: usr.sbin/tcpdump/util.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/util.c,v retrieving revision 1.25 diff -u -p -r1.25 util.c --- usr.sbin/tcpdump/util.c 27 Oct 2009 23:59:57 -0000 1.25 +++ usr.sbin/tcpdump/util.c 23 May 2013 15:45:27 -0000 @@ -114,12 +114,12 @@ fn_printn(register const u_char *s, regi * Print the timestamp */ void -ts_print(register const struct bpf_timeval *tvp) +ts_print(register const struct timeval *tvp) { register int s; #define TSBUFLEN 32 static char buf[TSBUFLEN]; - static struct bpf_timeval last; + static struct timeval last; struct timeval diff; time_t t; Index: share/man/man4/bpf.4 =================================================================== RCS file: /cvs/src/share/man/man4/bpf.4,v retrieving revision 1.31 diff -u -p -r1.31 bpf.4 --- share/man/man4/bpf.4 9 Apr 2010 16:25:21 -0000 1.31 +++ share/man/man4/bpf.4 23 May 2013 15:45:27 -0000 @@ -473,7 +473,7 @@ The following structure is prepended to .Xr read 2 : .Bd -literal -offset indent struct bpf_hdr { - struct bpf_timeval bh_tstamp; + struct timeval bh_tstamp; u_int32_t bh_caplen; u_int32_t bh_datalen; u_int16_t bh_hdrlen; Index: sys/net/bpf.h =================================================================== RCS file: /cvs/src/sys/net/bpf.h,v retrieving revision 1.43 diff -u -p -r1.43 bpf.h --- sys/net/bpf.h 26 Mar 2012 19:37:42 -0000 1.43 +++ sys/net/bpf.h 23 May 2013 15:45:27 -0000 @@ -126,16 +126,11 @@ struct bpf_version { #define BPF_DIRECTION_IN 1 #define BPF_DIRECTION_OUT (1<<1) -struct bpf_timeval { - u_int32_t tv_sec; - u_int32_t tv_usec; -}; - /* * Structure prepended to each packet. */ struct bpf_hdr { - struct bpf_timeval bh_tstamp; /* time stamp */ + struct timeval bh_tstamp; /* time stamp */ u_int32_t bh_caplen; /* length of captured portion */ u_int32_t bh_datalen; /* original length of packet */ u_int16_t bh_hdrlen; /* length of bpf header (this struct
