#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
* @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,
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
*
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;
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)
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){