bpf aligns data following the datalink header (e.g. ethernet)
on the BPF_ALIGNMENT boundary.  Since rev1.41 of bpf.h it's
uint32_t instead of a long.  And also since then almost all
packets become "unaligned" from the tcpdump perspective and
require costly copies into the internal buffer.  Neither IP
header (struct ip) nor IPv6 (struct ip6_hdr) have fields
larger than 32 bits and therefore alignment requirements for
them are at most 32 bit.

I've successfully tested this diff on sparc64 and amd64.

OK?

diff --git usr.sbin/tcpdump/print-ip.c usr.sbin/tcpdump/print-ip.c
index 1839869..60946a1 100644
--- usr.sbin/tcpdump/print-ip.c
+++ usr.sbin/tcpdump/print-ip.c
@@ -368,11 +368,11 @@ ip_print(register const u_char *bp, register u_int length)
        /*
         * If the IP header is not aligned, copy into abuf.
         * This will never happen with BPF.  It does happen with raw packet
         * dumps from -r.
         */
-       if ((intptr_t)ip & (sizeof(long)-1)) {
+       if ((intptr_t)ip & (sizeof(u_int32_t)-1)) {
                static u_char *abuf = NULL;
                static int didwarn = 0;
                int clen = snapend - bp;
 
                if (clen > snaplen)
diff --git usr.sbin/tcpdump/print-ip6.c usr.sbin/tcpdump/print-ip6.c
index cca8495..ea3a9b3 100644
--- usr.sbin/tcpdump/print-ip6.c
+++ usr.sbin/tcpdump/print-ip6.c
@@ -70,11 +70,11 @@ ip6_print(register const u_char *bp, register u_int length)
        /*
         * The IP header is not word aligned, so copy into abuf.
         * This will never happen with BPF.  It does happen with
         * raw packet dumps from -r.
         */
-       if ((intptr_t)ip6 & (sizeof(long)-1)) {
+       if ((intptr_t)ip6 & (sizeof(u_int32_t)-1)) {
                static u_char *abuf = NULL;
                static int didwarn = 0;
                int clen = snapend - bp;
                if (clen > snaplen)
                        clen = snaplen;

Reply via email to