]> The Tcpdump Group git mirrors - tcpdump/blobdiff - extract.h
Add a cast to the EXTRACT_U_1() macro
[tcpdump] / extract.h
index 8f2ed8d053615c1e480675de1966f366a1bfbd97..0ea84e925b4ba5a78b21fbb9f367c9ec74b4201f 100644 (file)
--- a/extract.h
+++ b/extract.h
@@ -25,7 +25,7 @@
  * For 8-bit values; needed to fetch a one-byte value.  Byte order
  * isn't relevant, and alignment isn't an issue.
  */
-#define EXTRACT_U_1(p) (*(p))
+#define EXTRACT_U_1(p) ((uint8_t)(*(p)))
 #define EXTRACT_S_1(p) ((int8_t)(*(p)))
 
 /*
  * XXX - do we need to test for both 32-bit and 64-bit versions of those
  * architectures in all cases?
  */
-static inline uint16_t UNALIGNED_OK
+UNALIGNED_OK static inline uint16_t
 EXTRACT_BE_U_2(const void *p)
 {
        return ((uint16_t)ntohs(*(const uint16_t *)(p)));
 }
 
-static inline int16_t UNALIGNED_OK
+UNALIGNED_OK static inline int16_t
 EXTRACT_BE_S_2(const void *p)
 {
        return ((int16_t)ntohs(*(const int16_t *)(p)));
 }
 
-static inline uint32_t UNALIGNED_OK
+UNALIGNED_OK static inline uint32_t
 EXTRACT_BE_U_4(const void *p)
 {
        return ((uint32_t)ntohl(*(const uint32_t *)(p)));
 }
 
-static inline int32_t UNALIGNED_OK
+UNALIGNED_OK static inline int32_t
 EXTRACT_BE_S_4(const void *p)
 {
        return ((int32_t)ntohl(*(const int32_t *)(p)));
 }
 
-static inline uint64_t UNALIGNED_OK
+UNALIGNED_OK static inline uint64_t
 EXTRACT_BE_U_8(const void *p)
 {
        return ((uint64_t)(((uint64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
@@ -116,7 +116,7 @@ EXTRACT_BE_U_8(const void *p)
 
 }
 
-static inline int64_t UNALIGNED_OK
+UNALIGNED_OK static inline int64_t
 EXTRACT_BE_S_8(const void *p)
 {
        return ((int64_t)(((int64_t)ntohl(*((const uint32_t *)(p) + 0))) << 32 |
@@ -128,20 +128,21 @@ EXTRACT_BE_S_8(const void *p)
  * Extract an IPv4 address, which is in network byte order, and not
  * necessarily aligned, and provide the result in host byte order.
  */
-static inline uint32_t UNALIGNED_OK
+UNALIGNED_OK static inline uint32_t
 EXTRACT_IPV4_TO_HOST_ORDER(const void *p)
 {
        return ((uint32_t)ntohl(*(const uint32_t *)(p)));
 }
-#elif defined(__GNUC__) && defined(HAVE___ATTRIBUTE__) && \
+#elif ND_IS_AT_LEAST_GNUC_VERSION(2,0) && \
     (defined(__alpha) || defined(__alpha__) || \
      defined(__mips) || defined(__mips__))
 /*
  * This is MIPS or Alpha, which don't natively handle unaligned loads,
  * but which have instructions that can help when doing unaligned
- * loads, and this is a GCC-compatible compiler and we have __attribute__,
- * which we assume that mean we have __attribute__((packed)), which
- * we can use to convince the compiler to generate those instructions.
+ * loads, and this is GCC 2.0 or later or a compiler that claims to
+ * be GCC 2.0 or later, which we assume that mean we have
+ * __attribute__((packed)), which we can use to convince the compiler
+ * to generate those instructions.
  *
  * Declare packed structures containing a uint16_t and a uint32_t,
  * cast the pointer to point to one of those, and fetch through it;
@@ -305,6 +306,56 @@ EXTRACT_IPV4_TO_HOST_ORDER(const void *p)
                    ((uint32_t)(*((const uint8_t *)(p) + 3)) << 0)))
 #endif /* unaligned access checks */
 
+/*
+ * Extract numerical values in *host* byte order.  (Some metadata
+ * headers are in the byte order of the host that wrote the file,
+ * and libpcap translate them to the byte order of the host
+ * reading the file.  This means that if a program on that host
+ * reads with libpcap and writes to a new file, the new file will
+ * be written in the byte order of the host writing the file.  Thus,
+ * the magic number in pcap files and byte-order magic in pcapng
+ * files can be used to determine the byte order in those metadata
+ * headers.)
+ *
+ * XXX - on platforms that can do unaligned accesses, just cast and
+ * dereference the pointer.
+ */
+static inline uint16_t
+EXTRACT_HE_U_2(const void *p)
+{
+       uint16_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(uint16_t));
+       return val;
+}
+
+static inline int16_t
+EXTRACT_HE_S_2(const void *p)
+{
+       int16_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(int16_t));
+       return val;
+}
+
+static inline uint32_t
+EXTRACT_HE_U_4(const void *p)
+{
+       uint32_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(uint32_t));
+       return val;
+}
+
+static inline int32_t
+EXTRACT_HE_S_4(const void *p)
+{
+       int32_t val;
+
+       UNALIGNED_MEMCPY(&val, p, sizeof(int32_t));
+       return val;
+}
+
 /*
  * Extract an IPv4 address, which is in network byte order, and which
  * is not necessarily aligned on a 4-byte boundary, and provide the