summaryrefslogtreecommitdiffstats
path: root/contrib/tcpdump/extract.h
diff options
context:
space:
mode:
authordelphij <delphij@FreeBSD.org>2015-01-07 19:55:18 +0000
committerdelphij <delphij@FreeBSD.org>2015-01-07 19:55:18 +0000
commitf49c5d523af9076a4a59e8dd664f9a897108432e (patch)
treee268839e08c106e178b33bd461d8d0a9c6fb5ad9 /contrib/tcpdump/extract.h
parentc371846049d370ab78d943e60e789cdffe0aad3d (diff)
parent08263d19579d35a7a65e0c8bcb768504ce76d04e (diff)
downloadFreeBSD-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.h194
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)))
OpenPOWER on IntegriCloud