]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Add {40,48,56}-bit big-endian extract macros and use them for DCCP ACKs.
authorGuy Harris <[email protected]>
Sun, 16 Feb 2014 04:37:28 +0000 (20:37 -0800)
committerGuy Harris <[email protected]>
Sun, 16 Feb 2014 04:37:28 +0000 (20:37 -0800)
Add macros to, given an octet pointer, extract 40-bit, 48-bit, and
56-bit big-endian numbers from the location pointed to by that pointer,
and use them when extracting ACK numbers from DCCP packets.  This fixes
problems on big-endian(!) machines.

extract.h
print-dccp.c

index 4dfbaae3e720dd8fb855ae2df88675f6f687b786..fe69bbccf08fc47b4fb278f822f1d653e99ead89 100644 (file)
--- a/extract.h
+++ b/extract.h
@@ -165,6 +165,30 @@ EXTRACT_64BITS(const void *p)
                     (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
                     (u_int32_t)*((const u_int8_t *)(p) + 2)))
 
+#define EXTRACT_40BITS(p) \
+       ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 32 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 1) << 24 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 3) << 8 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 4)))
+
+#define EXTRACT_48BITS(p) \
+       ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 40 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 1) << 32 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 2) << 24 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 3) << 16 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 4) << 8 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 5)))
+
+#define EXTRACT_56BITS(p) \
+       ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 48 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 1) << 40 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 2) << 32 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 4) << 16 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 5) << 8 | \
+                    (u_int64_t)*((const u_int8_t *)(p) + 6)))
+
 /*
  * Macros to extract possibly-unaligned little-endian integral values.
  * XXX - do loads on little-endian machines that support unaligned loads?
index 06ea2cd17a2db1d1ac12f8e6ebcf3c0d61414480..fcc2cc1cd0399a2709b2cef9d41fe31886586dda 100644 (file)
@@ -226,23 +226,15 @@ static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh)
 static void dccp_print_ack_no(const u_char *bp)
 {
        const struct dccp_hdr *dh = (const struct dccp_hdr *)bp;
-       const struct dccp_hdr_ack_bits *dh_ack =
-               (struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh));
-       u_int32_t ack_high;
+       const u_char *ackp = bp + dccp_basic_hdr_len(dh);
        u_int64_t ackno;
 
-       TCHECK2(*dh_ack,4);
-       ack_high = DCCPH_ACK(dh_ack);
-       ackno = EXTRACT_24BITS(&ack_high) & 0xFFFFFF;
-
        if (DCCPH_X(dh) != 0) {
-               u_int32_t ack_low;
-
-               TCHECK2(*dh_ack,8);
-               ack_low = dh_ack->dccph_ack_nr_low;
-
-               ackno &= 0x00FFFF;  /* clear reserved field */
-               ackno = (ackno << 32) + EXTRACT_32BITS(&ack_low);
+               TCHECK2(*ackp, 8);
+               ackno = EXTRACT_48BITS(ackp + 2);
+       } else {
+               TCHECK2(*ackp, 4);
+               ackno = EXTRACT_24BITS(ackp + 1);
        }
 
        (void)printf("(ack=%" PRIu64 ") ", ackno);