]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Mark various IPv4 and IPv6 headers as unaligned.
authorGuy Harris <[email protected]>
Tue, 31 Aug 2010 17:03:47 +0000 (10:03 -0700)
committerGuy Harris <[email protected]>
Tue, 31 Aug 2010 17:04:36 +0000 (10:04 -0700)
This prevents GCC on SPARC from generating code that assumes those
structures are aligned naturally, which they are not guaranteed to be.

Move some #defines from interface.h to tcpdump-stdinc.h to make them
available to code that doesn't include interface.h.

Move the declaration of nextproto6_cksum() to ip6.h, so that only files
that use it get it declared, and thus so that you don't need to define
"struct ip6_hdr" in everything that includes interface.h.  Don't include
ip6.h in tcpdump-stdinc.h.

interface.h
ip.h
ip6.h
tcpdump-stdinc.h

index b8acc7d9b5cb78459835d6e09aa9e2f921c324f7..be027ed34c99d328cf6b4b9f21689a94ab68be6f 100644 (file)
 #include "os-proto.h"
 #endif
 
-#ifndef HAVE___ATTRIBUTE__
-#define __attribute__(x)
-#endif
-
-/*
- * Used to declare a structure unaligned, so that the C compiler,
- * if necessary, generates code that doesn't assume alignment.
- * This is required because there is no guarantee that the packet
- * data we get from libpcap/WinPcap is properly aligned.
- *
- * This assumes that, for all compilers that support __attribute__:
- *
- *     1) they support __attribute__((packed));
- *
- *     2) for all instruction set architectures requiring strict
- *        alignment, declaring a structure with that attribute
- *        causes the compiler to generate code that handles
- *        misaligned 2-byte, 4-byte, and 8-byte integral
- *        quantities.
- *
- * It does not (yet) handle compilers where you can get the compiler
- * to generate code of that sort by some other means.
- *
- * This is required in order to, for example, keep the compiler from
- * generating, for
- *
- *     if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
- *
- * in print-bootp.c, code that loads the first 4-byte word of a
- * "struct bootp", masking out the bp_hops field, and comparing the result
- * against 0x01010600.
- *
- * Note: this also requires that padding be put into the structure,
- * at least for compilers where it's implemented as __attribute__((packed)).
- */
-#define UNALIGNED      __attribute__((packed))
-
 /* snprintf et al */
 
 #include <stdarg.h>
@@ -358,7 +321,6 @@ extern u_int usb_linux_64_byte_print(const struct pcap_pkthdr *, const u_char *)
 #ifdef INET6
 extern void ip6_print(const u_char *, u_int);
 extern void ip6_opt_print(const u_char *, int);
-extern int nextproto6_cksum(const struct ip6_hdr *, const u_short *, u_int, u_int);
 extern int hbhopt_print(const u_char *);
 extern int dstopt_print(const u_char *);
 extern int frag6_print(const u_char *, const u_char *);
diff --git a/ip.h b/ip.h
index a01d0f07d49e72cf63725cf76620cfd344fe4cd5..fd53503e426c9683ceb9ae60d518d411dbbf3848 100644 (file)
--- a/ip.h
+++ b/ip.h
@@ -62,7 +62,7 @@ struct ip {
        u_int8_t        ip_p;           /* protocol */
        u_int16_t       ip_sum;         /* checksum */
        struct  in_addr ip_src,ip_dst;  /* source and dest address */
-};
+} UNALIGNED;
 
 #define        IP_MAXPACKET    65535           /* maximum packet size */
 
@@ -134,7 +134,7 @@ struct      ip_timestamp {
                        u_int32_t ipt_time;
                } ipt_ta[1];
        } ipt_timestamp;
-};
+} UNALIGNED;
 
 /* flag bits for ipt_flg */
 #define        IPOPT_TS_TSONLY         0               /* timestamps only */
diff --git a/ip6.h b/ip6.h
index a6df97aae10b2251feef2547ad18e281a2dd4cb6..0a80f39448d428c1dcf12b6abd13f261b43b175d 100644 (file)
--- a/ip6.h
+++ b/ip6.h
@@ -86,7 +86,7 @@ struct ip6_hdr {
        } ip6_ctlun;
        struct in6_addr ip6_src;        /* source address */
        struct in6_addr ip6_dst;        /* destination address */
-};
+} UNALIGNED;
 
 /*
  * Pseudo header, used for higher layer checksumming.
@@ -100,7 +100,7 @@ union ip6_pseudo_hdr {
        u_int8_t        ph_nxt;
     } ph;
     u_int16_t pa[20];
-};
+} UNALIGNED;
 
 #define ip6_vfc                ip6_ctlun.ip6_un2_vfc
 #define ip6_flow       ip6_ctlun.ip6_un1.ip6_un1_flow
@@ -123,25 +123,23 @@ union ip6_pseudo_hdr {
  */
 
 struct ip6_ext {
-       u_char  ip6e_nxt;
-       u_char  ip6e_len;
-};
+       u_int8_t ip6e_nxt;
+       u_int8_t ip6e_len;
+} UNALIGNED;
 
 /* Hop-by-Hop options header */
-/* XXX should we pad it to force alignment on an 8-byte boundary? */
 struct ip6_hbh {
        u_int8_t ip6h_nxt;      /* next header */
        u_int8_t ip6h_len;      /* length in units of 8 octets */
        /* followed by options */
-};
+} UNALIGNED;
 
 /* Destination options header */
-/* XXX should we pad it to force alignment on an 8-byte boundary? */
 struct ip6_dest {
        u_int8_t ip6d_nxt;      /* next header */
        u_int8_t ip6d_len;      /* length in units of 8 octets */
        /* followed by options */
-};
+} UNALIGNED;
 
 /* Option types and related macros */
 #define IP6OPT_PAD1            0x00    /* 00 0 00000 */
@@ -177,7 +175,7 @@ struct ip6_rthdr {
        u_int8_t  ip6r_type;    /* routing type */
        u_int8_t  ip6r_segleft; /* segments left */
        /* followed by routing type specific data */
-};
+} UNALIGNED;
 
 /* Type 0 Routing header */
 struct ip6_rthdr0 {
@@ -188,7 +186,7 @@ struct ip6_rthdr0 {
        u_int8_t  ip6r0_reserved;       /* reserved field */
        u_int8_t  ip6r0_slmap[3];       /* strict/loose bit map */
        struct in6_addr ip6r0_addr[1];  /* up to 23 addresses */
-};
+} UNALIGNED;
 
 /* Fragment header */
 struct ip6_frag {
@@ -196,10 +194,13 @@ struct ip6_frag {
        u_int8_t  ip6f_reserved;        /* reserved field */
        u_int16_t ip6f_offlg;           /* offset, reserved, and flag */
        u_int32_t ip6f_ident;           /* identification */
-};
+} UNALIGNED;
 
 #define IP6F_OFF_MASK          0xfff8  /* mask out offset from ip6f_offlg */
 #define IP6F_RESERVED_MASK     0x0006  /* reserved bits in ip6f_offlg */
 #define IP6F_MORE_FRAG         0x0001  /* more-fragments flag */
 
+/* in print-ip6.c */
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_short *, u_int, u_int);
+
 #endif /* not _NETINET_IP6_H_ */
index c437cc10fe9abfe5ed9277fdac7a5736009a6281..38c987ddd442e856f1b56f42fe42654926072cc3 100644 (file)
@@ -131,10 +131,43 @@ typedef char* caddr_t;
 
 #endif /* WIN32 */
 
-#ifdef INET6
-#include "ip6.h"
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
 #endif
 
+/*
+ * Used to declare a structure unaligned, so that the C compiler,
+ * if necessary, generates code that doesn't assume alignment.
+ * This is required because there is no guarantee that the packet
+ * data we get from libpcap/WinPcap is properly aligned.
+ *
+ * This assumes that, for all compilers that support __attribute__:
+ *
+ *     1) they support __attribute__((packed));
+ *
+ *     2) for all instruction set architectures requiring strict
+ *        alignment, declaring a structure with that attribute
+ *        causes the compiler to generate code that handles
+ *        misaligned 2-byte, 4-byte, and 8-byte integral
+ *        quantities.
+ *
+ * It does not (yet) handle compilers where you can get the compiler
+ * to generate code of that sort by some other means.
+ *
+ * This is required in order to, for example, keep the compiler from
+ * generating, for
+ *
+ *     if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
+ *
+ * in print-bootp.c, code that loads the first 4-byte word of a
+ * "struct bootp", masking out the bp_hops field, and comparing the result
+ * against 0x01010600.
+ *
+ * Note: this also requires that padding be put into the structure,
+ * at least for compilers where it's implemented as __attribute__((packed)).
+ */
+#define UNALIGNED      __attribute__((packed))
+
 #if defined(WIN32) || defined(MSDOS)
   #define FOPEN_READ_TXT   "rt"
   #define FOPEN_READ_BIN   "rb"