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;
 

Reply via email to