diff options
author | delphij <delphij@FreeBSD.org> | 2015-01-07 19:55:18 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2015-01-07 19:55:18 +0000 |
commit | f49c5d523af9076a4a59e8dd664f9a897108432e (patch) | |
tree | e268839e08c106e178b33bd461d8d0a9c6fb5ad9 /contrib/tcpdump/extract.h | |
parent | c371846049d370ab78d943e60e789cdffe0aad3d (diff) | |
parent | 08263d19579d35a7a65e0c8bcb768504ce76d04e (diff) | |
download | FreeBSD-src-f49c5d523af9076a4a59e8dd664f9a897108432e.zip FreeBSD-src-f49c5d523af9076a4a59e8dd664f9a897108432e.tar.gz |
MFV r276761: tcpdump 4.6.2.
MFC after: 1 month
Diffstat (limited to 'contrib/tcpdump/extract.h')
-rw-r--r-- | contrib/tcpdump/extract.h | 194 |
1 files changed, 128 insertions, 66 deletions
diff --git a/contrib/tcpdump/extract.h b/contrib/tcpdump/extract.h index 60ecd68..d2174ba 100644 --- a/contrib/tcpdump/extract.h +++ b/contrib/tcpdump/extract.h @@ -17,8 +17,6 @@ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * @(#) $Header: /tcpdump/master/tcpdump/extract.h,v 1.25 2006-01-30 16:20:07 hannes Exp $ (LBL) */ /* @@ -28,104 +26,168 @@ /* * The processor doesn't natively handle unaligned loads. */ -#ifdef HAVE___ATTRIBUTE__ +#if defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \ + (defined(__alpha) || defined(__alpha__) || \ + defined(__mips) || defined(__mips__)) + /* - * We have __attribute__; we assume that means we have __attribute__((packed)). - * Declare packed structures containing a u_int16_t and a u_int32_t, + * This is a GCC-compatible compiler and we have __attribute__, which + * we assume that mean we have __attribute__((packed)), and this is + * MIPS or Alpha, which has instructions that can help when doing + * unaligned loads. + * + * Declare packed structures containing a uint16_t and a uint32_t, * cast the pointer to point to one of those, and fetch through it; * the GCC manual doesn't appear to explicitly say that * __attribute__((packed)) causes the compiler to generate unaligned-safe * code, but it apppears to do so. * - * We do this in case the compiler can generate, for this instruction set, - * better code to do an unaligned load and pass stuff to "ntohs()" or - * "ntohl()" than the code to fetch the bytes one at a time and - * assemble them. (That might not be the case on a little-endian platform, - * where "ntohs()" and "ntohl()" might not be done inline.) + * We do this in case the compiler can generate code using those + * instructions to do an unaligned load and pass stuff to "ntohs()" or + * "ntohl()", which might be better than than the code to fetch the + * bytes one at a time and assemble them. (That might not be the + * case on a little-endian platform, such as DEC's MIPS machines and + * Alpha machines, where "ntohs()" and "ntohl()" might not be done + * inline.) + * + * We do this only for specific architectures because, for example, + * at least some versions of GCC, when compiling for 64-bit SPARC, + * generate code that assumes alignment if we do this. + * + * XXX - add other architectures and compilers as possible and + * appropriate. + * + * HP's C compiler, indicated by __HP_cc being defined, supports + * "#pragma unaligned N" in version A.05.50 and later, where "N" + * specifies a number of bytes at which the typedef on the next + * line is aligned, e.g. + * + * #pragma unalign 1 + * typedef uint16_t unaligned_uint16_t; + * + * to define unaligned_uint16_t as a 16-bit unaligned data type. + * This could be presumably used, in sufficiently recent versions of + * the compiler, with macros similar to those below. This would be + * useful only if that compiler could generate better code for PA-RISC + * or Itanium than would be generated by a bunch of shifts-and-ORs. + * + * DEC C, indicated by __DECC being defined, has, at least on Alpha, + * an __unaligned qualifier that can be applied to pointers to get the + * compiler to generate code that does unaligned loads and stores when + * dereferencing the pointer in question. + * + * XXX - what if the native C compiler doesn't support + * __attribute__((packed))? How can we get it to generate unaligned + * accesses for *specific* items? */ typedef struct { - u_int16_t val; -} __attribute__((packed)) unaligned_u_int16_t; + uint16_t val; +} __attribute__((packed)) unaligned_uint16_t; typedef struct { - u_int32_t val; -} __attribute__((packed)) unaligned_u_int32_t; + uint32_t val; +} __attribute__((packed)) unaligned_uint32_t; -static inline u_int16_t +static inline uint16_t EXTRACT_16BITS(const void *p) { - return ((u_int16_t)ntohs(((const unaligned_u_int16_t *)(p))->val)); + return ((uint16_t)ntohs(((const unaligned_uint16_t *)(p))->val)); } -static inline u_int32_t +static inline uint32_t EXTRACT_32BITS(const void *p) { - return ((u_int32_t)ntohl(((const unaligned_u_int32_t *)(p))->val)); + return ((uint32_t)ntohl(((const unaligned_uint32_t *)(p))->val)); } -static inline u_int64_t +static inline uint64_t EXTRACT_64BITS(const void *p) { - return ((u_int64_t)(((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 0)->val)) << 32 | \ - ((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 1)->val)) << 0)); - + return ((uint64_t)(((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 0)->val)) << 32 | \ + ((uint64_t)ntohl(((const unaligned_uint32_t *)(p) + 1)->val)) << 0)); } -#else /* HAVE___ATTRIBUTE__ */ +#else /* have to do it a byte at a time */ /* - * We don't have __attribute__, so do unaligned loads of big-endian + * This isn't a GCC-compatible compiler, we don't have __attribute__, + * or we do but we don't know of any better way with this instruction + * set to do unaligned loads, so do unaligned loads of big-endian * quantities the hard way - fetch the bytes one at a time and * assemble them. */ #define EXTRACT_16BITS(p) \ - ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \ - (u_int16_t)*((const u_int8_t *)(p) + 1))) + ((uint16_t)((uint16_t)*((const uint8_t *)(p) + 0) << 8 | \ + (uint16_t)*((const uint8_t *)(p) + 1))) #define EXTRACT_32BITS(p) \ - ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \ - (u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \ - (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \ - (u_int32_t)*((const u_int8_t *)(p) + 3))) + ((uint32_t)((uint32_t)*((const uint8_t *)(p) + 0) << 24 | \ + (uint32_t)*((const uint8_t *)(p) + 1) << 16 | \ + (uint32_t)*((const uint8_t *)(p) + 2) << 8 | \ + (uint32_t)*((const uint8_t *)(p) + 3))) #define EXTRACT_64BITS(p) \ - ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 56 | \ - (u_int64_t)*((const u_int8_t *)(p) + 1) << 48 | \ - (u_int64_t)*((const u_int8_t *)(p) + 2) << 40 | \ - (u_int64_t)*((const u_int8_t *)(p) + 3) << 32 | \ - (u_int64_t)*((const u_int8_t *)(p) + 4) << 24 | \ - (u_int64_t)*((const u_int8_t *)(p) + 5) << 16 | \ - (u_int64_t)*((const u_int8_t *)(p) + 6) << 8 | \ - (u_int64_t)*((const u_int8_t *)(p) + 7))) -#endif /* HAVE___ATTRIBUTE__ */ + ((uint64_t)((uint64_t)*((const uint8_t *)(p) + 0) << 56 | \ + (uint64_t)*((const uint8_t *)(p) + 1) << 48 | \ + (uint64_t)*((const uint8_t *)(p) + 2) << 40 | \ + (uint64_t)*((const uint8_t *)(p) + 3) << 32 | \ + (uint64_t)*((const uint8_t *)(p) + 4) << 24 | \ + (uint64_t)*((const uint8_t *)(p) + 5) << 16 | \ + (uint64_t)*((const uint8_t *)(p) + 6) << 8 | \ + (uint64_t)*((const uint8_t *)(p) + 7))) +#endif /* must special-case unaligned accesses */ #else /* LBL_ALIGN */ /* * The processor natively handles unaligned loads, so we can just * cast the pointer and fetch through it. */ -static inline u_int16_t +static inline uint16_t EXTRACT_16BITS(const void *p) { - return ((u_int16_t)ntohs(*(const u_int16_t *)(p))); + return ((uint16_t)ntohs(*(const uint16_t *)(p))); } -static inline u_int32_t +static inline uint32_t EXTRACT_32BITS(const void *p) { - return ((u_int32_t)ntohl(*(const u_int32_t *)(p))); + return ((uint32_t)ntohl(*(const uint32_t *)(p))); } -static inline u_int64_t +static inline uint64_t EXTRACT_64BITS(const void *p) { - return ((u_int64_t)(((u_int64_t)ntohl(*((const u_int32_t *)(p) + 0))) << 32 | \ - ((u_int64_t)ntohl(*((const u_int32_t *)(p) + 1))) << 0)); + return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 | \ + ((uint64_t)ntohl(*((const uint32_t *)(p) + 1))) << 0)); } #endif /* LBL_ALIGN */ #define EXTRACT_24BITS(p) \ - ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \ - (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ - (u_int32_t)*((const u_int8_t *)(p) + 2))) + ((uint32_t)((uint32_t)*((const uint8_t *)(p) + 0) << 16 | \ + (uint32_t)*((const uint8_t *)(p) + 1) << 8 | \ + (uint32_t)*((const uint8_t *)(p) + 2))) + +#define EXTRACT_40BITS(p) \ + ((uint64_t)((uint64_t)*((const uint8_t *)(p) + 0) << 32 | \ + (uint64_t)*((const uint8_t *)(p) + 1) << 24 | \ + (uint64_t)*((const uint8_t *)(p) + 2) << 16 | \ + (uint64_t)*((const uint8_t *)(p) + 3) << 8 | \ + (uint64_t)*((const uint8_t *)(p) + 4))) + +#define EXTRACT_48BITS(p) \ + ((uint64_t)((uint64_t)*((const uint8_t *)(p) + 0) << 40 | \ + (uint64_t)*((const uint8_t *)(p) + 1) << 32 | \ + (uint64_t)*((const uint8_t *)(p) + 2) << 24 | \ + (uint64_t)*((const uint8_t *)(p) + 3) << 16 | \ + (uint64_t)*((const uint8_t *)(p) + 4) << 8 | \ + (uint64_t)*((const uint8_t *)(p) + 5))) + +#define EXTRACT_56BITS(p) \ + ((uint64_t)((uint64_t)*((const uint8_t *)(p) + 0) << 48 | \ + (uint64_t)*((const uint8_t *)(p) + 1) << 40 | \ + (uint64_t)*((const uint8_t *)(p) + 2) << 32 | \ + (uint64_t)*((const uint8_t *)(p) + 3) << 24 | \ + (uint64_t)*((const uint8_t *)(p) + 4) << 16 | \ + (uint64_t)*((const uint8_t *)(p) + 5) << 8 | \ + (uint64_t)*((const uint8_t *)(p) + 6))) /* * Macros to extract possibly-unaligned little-endian integral values. @@ -133,23 +195,23 @@ EXTRACT_64BITS(const void *p) */ #define EXTRACT_LE_8BITS(p) (*(p)) #define EXTRACT_LE_16BITS(p) \ - ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \ - (u_int16_t)*((const u_int8_t *)(p) + 0))) + ((uint16_t)((uint16_t)*((const uint8_t *)(p) + 1) << 8 | \ + (uint16_t)*((const uint8_t *)(p) + 0))) #define EXTRACT_LE_32BITS(p) \ - ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \ - (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ - (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ - (u_int32_t)*((const u_int8_t *)(p) + 0))) + ((uint32_t)((uint32_t)*((const uint8_t *)(p) + 3) << 24 | \ + (uint32_t)*((const uint8_t *)(p) + 2) << 16 | \ + (uint32_t)*((const uint8_t *)(p) + 1) << 8 | \ + (uint32_t)*((const uint8_t *)(p) + 0))) #define EXTRACT_LE_24BITS(p) \ - ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \ - (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \ - (u_int32_t)*((const u_int8_t *)(p) + 0))) + ((uint32_t)((uint32_t)*((const uint8_t *)(p) + 2) << 16 | \ + (uint32_t)*((const uint8_t *)(p) + 1) << 8 | \ + (uint32_t)*((const uint8_t *)(p) + 0))) #define EXTRACT_LE_64BITS(p) \ - ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 7) << 56 | \ - (u_int64_t)*((const u_int8_t *)(p) + 6) << 48 | \ - (u_int64_t)*((const u_int8_t *)(p) + 5) << 40 | \ - (u_int64_t)*((const u_int8_t *)(p) + 4) << 32 | \ - (u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \ - (u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \ - (u_int64_t)*((const u_int8_t *)(p) + 1) << 8 | \ - (u_int64_t)*((const u_int8_t *)(p) + 0))) + ((uint64_t)((uint64_t)*((const uint8_t *)(p) + 7) << 56 | \ + (uint64_t)*((const uint8_t *)(p) + 6) << 48 | \ + (uint64_t)*((const uint8_t *)(p) + 5) << 40 | \ + (uint64_t)*((const uint8_t *)(p) + 4) << 32 | \ + (uint64_t)*((const uint8_t *)(p) + 3) << 24 | \ + (uint64_t)*((const uint8_t *)(p) + 2) << 16 | \ + (uint64_t)*((const uint8_t *)(p) + 1) << 8 | \ + (uint64_t)*((const uint8_t *)(p) + 0))) |