]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Fetch the sequence number the way we fetch the acknowledgment number.
authorGuy Harris <[email protected]>
Sun, 16 Feb 2014 10:21:28 +0000 (02:21 -0800)
committerGuy Harris <[email protected]>
Sun, 16 Feb 2014 10:21:28 +0000 (02:21 -0800)
Fetch 24 bits if the X bit isn't set, 48 bits if it is, using the
appropriate EXTRACT_ macros.

We do this with "struct dccp_hdr" being a header structure with a 24-bit
sequence number and "struct dccp_hdr_ext" being a header structure with
a 48-bit sequence number.

print-dccp.c

index 626853c2d7944053b0f8e758083e6cad8ec61b5d..ffadfb66bb389172807dfc66c6dae6eea3d4c7d1 100644 (file)
@@ -26,7 +26,8 @@
 #include "ipproto.h"
 
 /**
- * struct dccp_hdr - generic part of DCCP packet header
+ * struct dccp_hdr - generic part of DCCP packet header, with a 24-bit
+ * sequence number
  *
  * @dccph_sport - Relevant port on the endpoint that sent this packet
  * @dccph_dport - Relevant port on the other endpoint
@@ -36,7 +37,7 @@
  * @dccph_checksum - Internet checksum, depends on dccph_cscov
  * @dccph_x - 0 = 24 bit sequence number, 1 = 48
  * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
- * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
+ * @dccph_seq - 24-bit sequence number
  */
 struct dccp_hdr {
        u_int16_t       dccph_sport,
@@ -44,28 +45,41 @@ struct dccp_hdr {
        u_int8_t        dccph_doff;
        u_int8_t        dccph_ccval_cscov;
        u_int16_t       dccph_checksum;
-       union {
        u_int8_t        dccph_xtr;
-       u_int32_t       dccph_seq;
-       }               dccph_xtrs;
+       u_int8_t        dccph_seq[3];
 } UNALIGNED;
 
-#define DCCPH_CCVAL(dh)        (((dh)->dccph_ccval_cscov >> 4) & 0xF)
-#define DCCPH_CSCOV(dh)        (((dh)->dccph_ccval_cscov) & 0xF)
-
-#define DCCPH_X(dh)    ((dh)->dccph_xtrs.dccph_xtr & 1)
-#define DCCPH_TYPE(dh) (((dh)->dccph_xtrs.dccph_xtr >> 1) & 0xF)
-#define DCCPH_SEQ(dh)   (((dh)->dccph_xtrs.dccph_seq) >> 8)
-
 /**
- * struct dccp_hdr_ext - the low bits of a 48 bit seq packet
+ * struct dccp_hdr_ext - generic part of DCCP packet header, with a 48-bit
+ * sequence number
  *
- * @dccph_seq_low - low 24 bits of a 48 bit seq packet
+ * @dccph_sport - Relevant port on the endpoint that sent this packet
+ * @dccph_dport - Relevant port on the other endpoint
+ * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
+ * @dccph_ccval - Used by the HC-Sender CCID
+ * @dccph_cscov - Parts of the packet that are covered by the Checksum field
+ * @dccph_checksum - Internet checksum, depends on dccph_cscov
+ * @dccph_x - 0 = 24 bit sequence number, 1 = 48
+ * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
+ * @dccph_seq - 48-bit sequence number
  */
 struct dccp_hdr_ext {
-       u_int32_t       dccph_seq_low;
+       u_int16_t       dccph_sport,
+                       dccph_dport;
+       u_int8_t        dccph_doff;
+       u_int8_t        dccph_ccval_cscov;
+       u_int16_t       dccph_checksum;
+       u_int8_t        dccph_xtr;
+       u_int8_t        reserved;
+       u_int8_t        dccph_seq[6];
 } UNALIGNED;
 
+#define DCCPH_CCVAL(dh)        (((dh)->dccph_ccval_cscov >> 4) & 0xF)
+#define DCCPH_CSCOV(dh)        (((dh)->dccph_ccval_cscov) & 0xF)
+
+#define DCCPH_X(dh)    ((dh)->dccph_xtr & 1)
+#define DCCPH_TYPE(dh) (((dh)->dccph_xtr >> 1) & 0xF)
+
 /**
  * struct dccp_hdr_request - Conection initiation request header
  *
@@ -190,16 +204,16 @@ static const char *dccp_reset_code(u_int8_t code)
        return dccp_reset_codes[code];
 }
 
-static u_int64_t dccp_seqno(const struct dccp_hdr *dh)
+static u_int64_t dccp_seqno(const u_char *bp)
 {
-       u_int32_t seq_high = DCCPH_SEQ(dh);
-       u_int64_t seqno = EXTRACT_24BITS(&seq_high) & 0xFFFFFF;
+       const struct dccp_hdr *dh = (const struct dccp_hdr *)bp;
+       u_int64_t seqno;
 
        if (DCCPH_X(dh) != 0) {
-               const struct dccp_hdr_ext *dhx = (void *)(dh + 1);
-               u_int32_t seq_low = dhx->dccph_seq_low;
-               seqno &= 0x00FFFF;  /* clear reserved field */
-               seqno = (seqno << 32) + EXTRACT_32BITS(&seq_low);
+               const struct dccp_hdr_ext *dhx = (const struct dccp_hdr_ext *)bp;
+               seqno = EXTRACT_48BITS(dhx->dccph_seq);
+       } else {
+               seqno = EXTRACT_24BITS(dh->dccph_seq);
        }
 
        return seqno;
@@ -207,7 +221,7 @@ static u_int64_t dccp_seqno(const struct dccp_hdr *dh)
 
 static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh)
 {
-       return sizeof(*dh) + (DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : 0);
+       return DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : sizeof(struct dccp_hdr);
 }
 
 static void dccp_print_ack_no(const u_char *bp)
@@ -389,7 +403,7 @@ void dccp_print(const u_char *bp, const u_char *data2, u_int len)
        if (vflag < 2)
                return;
 
-       (void)printf("seq %" PRIu64, dccp_seqno(dh));
+       (void)printf("seq %" PRIu64, dccp_seqno(bp));
 
        /* process options */
        if (hlen > dccp_basic_hdr_len(dh) + extlen){