On 2016/04/15 23:07, Philip Guenther wrote: > On Thu, Apr 14, 2016 at 3:15 PM, Martin Natano <nat...@natano.net> wrote: > > In rbootd a struct bpf_timeval (with 32bit tv_sec) is copied to a struct > > timeval (with 64 tv_sec) via bcopy(). This most likely causes > > connections to not time out correctly in rbootd. I don't have an HP > > machine to test this with. Who owns such a machine and is willing to > > test this? > > The current code is simply wrong: sizeof(struct timeval) > > sizeof(struct bpf_timeval). I think we should make this change (ok > guenther@) and then work to update struct bpf_hdr or a replacement > thereof to not be limited to 32bit time_t values. Maybe it should be > using a timespec instead too? Have any other free OSes added timespec > (or bintime) APIs? > > (BPF has been around since 1990; the time from then to now is less > than the time from now to 2038 when 32bit time_t fails...)
I'd like this for ports too; it is not sanely possible to patch some programs to support bpf_timeval (in some programs it's common to mix timevals from bpf with timevals on the system and want to calculate time differences etc - patches to fix these cases are often very intrusive). I have a WIP diff to switch bpf to timevals, and convert in libpcap when writing dump files - these need to be 32-bit unsigned in the current format; there is a newer pcapng file format (draft-tuexen-opsawg-pcapng) that has 64-bit timestamps but also has many other changes, libpcap upstream only had partial support last time I checked. It works fine on amd64 but last time I tried it on spar64 I was seeing unaligned access with tcpdump, and dhclient didn't work, I haven't managed to track that down yet (I have some ideas but my x1 died, my other sparc64 is noisy and has no LOM so progress is slow!). Index: lib/libpcap/pcap-int.h =================================================================== RCS file: /cvs/src/lib/libpcap/pcap-int.h,v retrieving revision 1.13 diff -u -p -r1.13 pcap-int.h --- lib/libpcap/pcap-int.h 11 Apr 2014 04:08:58 -0000 1.13 +++ lib/libpcap/pcap-int.h 16 Apr 2016 10:05:57 -0000 @@ -120,11 +120,20 @@ struct pcap { }; /* + * MI timeval structure as used in the dumpfile. + */ + +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.18 diff -u -p -r1.18 pcap.h --- lib/libpcap/pcap.h 6 Apr 2016 08:02:56 -0000 1.18 +++ lib/libpcap/pcap.h 16 Apr 2016 10:05:57 -0000 @@ -90,7 +90,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.16 diff -u -p -r1.16 savefile.c --- lib/libpcap/savefile.c 22 Dec 2015 19:51:04 -0000 1.16 +++ lib/libpcap/savefile.c 16 Apr 2016 10:05:57 -0000 @@ -211,20 +211,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, @@ -332,10 +338,16 @@ void pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { FILE *f; + struct pcap_sf_pkthdr sf_hdr; f = (FILE *)user; + /* XXX does this need memcpy instead for strict alignment arch? */ + 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: lib/libpcap/shlib_version =================================================================== RCS file: /cvs/src/lib/libpcap/shlib_version,v retrieving revision 1.15 diff -u -p -r1.15 shlib_version --- lib/libpcap/shlib_version 6 Apr 2016 08:02:56 -0000 1.15 +++ lib/libpcap/shlib_version 16 Apr 2016 10:05:57 -0000 @@ -1,2 +1,2 @@ -major=8 -minor=1 +major=9 +minor=0 Index: share/man/man4/bpf.4 =================================================================== RCS file: /cvs/src/share/man/man4/bpf.4,v retrieving revision 1.37 diff -u -p -r1.37 bpf.4 --- share/man/man4/bpf.4 10 Mar 2016 04:48:27 -0000 1.37 +++ share/man/man4/bpf.4 16 Apr 2016 10:05:58 -0000 @@ -475,7 +475,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.55 diff -u -p -r1.55 bpf.h --- sys/net/bpf.h 3 Apr 2016 01:37:26 -0000 1.55 +++ sys/net/bpf.h 16 Apr 2016 10:05:58 -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 @@ -151,9 +146,10 @@ struct bpf_hdr { */ #ifdef _KERNEL #if defined(__arm__) || defined(__i386__) || defined(__m68k__) || \ - defined(__mips__) || defined(__ns32k__) || defined(__sparc__) || \ - defined(__sparc64__) -#define SIZEOF_BPF_HDR 18 + defined(__mips__) || defined(__ns32k__) || defined(__sparc__) +#define SIZEOF_BPF_HDR 22 +#elif defined(__sparc64__) +#define SIZEOF_BPF_HDR 26 #else #define SIZEOF_BPF_HDR sizeof(struct bpf_hdr) #endif Index: usr.sbin/tcpdump/interface.h =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/interface.h,v retrieving revision 1.66 diff -u -p -r1.66 interface.h --- usr.sbin/tcpdump/interface.h 15 Nov 2015 20:35:36 -0000 1.66 +++ usr.sbin/tcpdump/interface.h 16 Apr 2016 10:05:58 -0000 @@ -146,9 +146,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.27 diff -u -p -r1.27 util.c --- usr.sbin/tcpdump/util.c 16 Nov 2015 00:16:39 -0000 1.27 +++ usr.sbin/tcpdump/util.c 16 Apr 2016 10:05:58 -0000 @@ -113,12 +113,12 @@ fn_printn(const u_char *s, u_int n, cons * Print the timestamp */ void -ts_print(const struct bpf_timeval *tvp) +ts_print(const struct timeval *tvp) { int s; #define TSBUFLEN 32 static char buf[TSBUFLEN]; - static struct bpf_timeval last; + static struct timeval last; struct timeval diff; time_t t;