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;