From: Guy Harris Date: Sun, 16 Feb 2014 04:37:28 +0000 (-0800) Subject: Add {40,48,56}-bit big-endian extract macros and use them for DCCP ACKs. X-Git-Tag: tcpdump-4.6.0~225 X-Git-Url: https://git.tcpdump.org/tcpdump/commitdiff_plain/f5e2e1a4a523dde5afbcd73ec3999c0093605d36 Add {40,48,56}-bit big-endian extract macros and use them for DCCP ACKs. 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. --- diff --git a/extract.h b/extract.h index 4dfbaae3..fe69bbcc 100644 --- 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? diff --git a/print-dccp.c b/print-dccp.c index 06ea2cd1..fcc2cc1c 100644 --- a/print-dccp.c +++ b/print-dccp.c @@ -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);