Enable ND_LONGJMP_FROM_TCHECK.
Use ND_ICHECK*() for length checks.
Fix some length checks.
Add and use standard "invalid" sections.
Remove the redundant ND_TCHECK*() instances.
Add a ND_TCHECK_1().
Factorize some codes.
Update default format for tok2str() calls.
Indicate better invalid packet types, invalid option types,
invalid reset codes and invalid features.
Fix process for DCCP_OPTION_CHANGE_L/DCCP_OPTION_CHANGE_R, not the
same that DCCP_OPTION_CONFIRM_L/DCCP_OPTION_CONFIRM_R process.
Remove spaces in some dccp_feature_num_str[] strings.
Update the output of a test accordingly.
#include "netdissect-stdinc.h"
#include "netdissect-stdinc.h"
+#define ND_LONGJMP_FROM_TCHECK
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
#include "netdissect.h"
#include "addrtoname.h"
#include "extract.h"
{ 5, "ack_ratio" },
{ 6, "send_ack_vector" },
{ 7, "send_ndp_count" },
{ 5, "ack_ratio" },
{ 6, "send_ack_vector" },
{ 7, "send_ndp_count" },
- { 8, "minimum checksum coverage" },
- { 9, "check data checksum" },
+ { 8, "minimum_checksum_coverage" },
+ { 9, "check_data_checksum" },
- /* make sure we have enough data to look at the X bit */
cp = (const u_char *)(dh + 1);
cp = (const u_char *)(dh + 1);
- if (cp > ndo->ndo_snapend)
- goto trunc;
- if (length < sizeof(struct dccp_hdr)) {
- ND_PRINT("truncated-dccp - %zu bytes missing!",
- sizeof(struct dccp_hdr) - length);
- return;
- }
+ ND_ICHECK_ZU(length, <, sizeof(struct dccp_hdr));
/* get the length of the generic header */
fixed_hdrlen = dccp_basic_hdr_len(ndo, dh);
/* get the length of the generic header */
fixed_hdrlen = dccp_basic_hdr_len(ndo, dh);
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-dccp - %u bytes missing!",
- fixed_hdrlen - length);
- return;
- }
+ ND_ICHECK_U(length, <, fixed_hdrlen);
ND_TCHECK_LEN(dh, fixed_hdrlen);
sport = GET_BE_U_2(dh->dccph_sport);
ND_TCHECK_LEN(dh, fixed_hdrlen);
sport = GET_BE_U_2(dh->dccph_sport);
nd_print_protocol_caps(ndo);
if (ndo->ndo_qflag) {
nd_print_protocol_caps(ndo);
if (ndo->ndo_qflag) {
+ ND_ICHECK_U(length, <, hlen);
ND_PRINT(" %u", length - hlen);
ND_PRINT(" %u", length - hlen);
- if (hlen > length) {
- ND_PRINT(" [bad hdr length %u - too long, > %u]",
- hlen, length);
- }
return;
}
/* other variables in generic header */
if (ndo->ndo_vflag) {
ND_PRINT(" (CCVal %u, CsCov %u", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh));
return;
}
/* other variables in generic header */
if (ndo->ndo_vflag) {
ND_PRINT(" (CCVal %u, CsCov %u", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh));
/* checksum calculation */
if (ND_TTEST_LEN(bp, length)) {
uint16_t sum = 0, dccp_sum;
/* checksum calculation */
if (ND_TTEST_LEN(bp, length)) {
uint16_t sum = 0, dccp_sum;
dccph_type = DCCPH_TYPE(dh);
dccph_type = DCCPH_TYPE(dh);
+ ND_PRINT(" %s ", tok2str(dccp_pkt_type_str, "packet-type-%u",
+ dccph_type));
switch (dccph_type) {
case DCCP_PKT_REQUEST: {
const struct dccp_hdr_request *dhr =
(const struct dccp_hdr_request *)(bp + fixed_hdrlen);
fixed_hdrlen += 4;
switch (dccph_type) {
case DCCP_PKT_REQUEST: {
const struct dccp_hdr_request *dhr =
(const struct dccp_hdr_request *)(bp + fixed_hdrlen);
fixed_hdrlen += 4;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_TCHECK_SIZE(dhr);
- ND_PRINT("%s (service=%u) ",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- GET_BE_U_4(dhr->dccph_req_service));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
+ ND_PRINT("(service=%u) ", GET_BE_U_4(dhr->dccph_req_service));
break;
}
case DCCP_PKT_RESPONSE: {
const struct dccp_hdr_response *dhr =
(const struct dccp_hdr_response *)(bp + fixed_hdrlen);
fixed_hdrlen += 12;
break;
}
case DCCP_PKT_RESPONSE: {
const struct dccp_hdr_response *dhr =
(const struct dccp_hdr_response *)(bp + fixed_hdrlen);
fixed_hdrlen += 12;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_TCHECK_SIZE(dhr);
- ND_PRINT("%s (service=%u) ",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- GET_BE_U_4(dhr->dccph_resp_service));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
+ ND_PRINT("(service=%u) ", GET_BE_U_4(dhr->dccph_resp_service));
break;
}
case DCCP_PKT_DATA:
break;
}
case DCCP_PKT_DATA:
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
break;
case DCCP_PKT_ACK: {
fixed_hdrlen += 8;
break;
case DCCP_PKT_ACK: {
fixed_hdrlen += 8;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
break;
}
case DCCP_PKT_DATAACK: {
fixed_hdrlen += 8;
break;
}
case DCCP_PKT_DATAACK: {
fixed_hdrlen += 8;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
break;
}
case DCCP_PKT_CLOSEREQ:
fixed_hdrlen += 8;
break;
}
case DCCP_PKT_CLOSEREQ:
fixed_hdrlen += 8;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
break;
case DCCP_PKT_CLOSE:
fixed_hdrlen += 8;
break;
case DCCP_PKT_CLOSE:
fixed_hdrlen += 8;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
break;
case DCCP_PKT_RESET: {
const struct dccp_hdr_reset *dhr =
(const struct dccp_hdr_reset *)(bp + fixed_hdrlen);
fixed_hdrlen += 12;
break;
case DCCP_PKT_RESET: {
const struct dccp_hdr_reset *dhr =
(const struct dccp_hdr_reset *)(bp + fixed_hdrlen);
fixed_hdrlen += 12;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
+ ND_ICHECK_U(length, <, fixed_hdrlen);
- ND_PRINT("%s (code=%s) ",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- tok2str(dccp_reset_code_str, "invalid", GET_U_1(dhr->dccph_reset_code)));
+ ND_PRINT("(code=%s) ", tok2str(dccp_reset_code_str,
+ "reset-code-%u (invalid)", GET_U_1(dhr->dccph_reset_code)));
break;
}
case DCCP_PKT_SYNC:
fixed_hdrlen += 8;
break;
}
case DCCP_PKT_SYNC:
fixed_hdrlen += 8;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
break;
case DCCP_PKT_SYNCACK:
fixed_hdrlen += 8;
break;
case DCCP_PKT_SYNCACK:
fixed_hdrlen += 8;
- if (length < fixed_hdrlen) {
- ND_PRINT("truncated-%s - %u bytes missing!",
- tok2str(dccp_pkt_type_str, "", dccph_type),
- fixed_hdrlen - length);
- return;
- }
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type));
+ ND_ICHECK_U(length, <, fixed_hdrlen);
- ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type));
while(1){
optlen = dccp_print_option(ndo, cp, hlen);
if (!optlen)
while(1){
optlen = dccp_print_option(ndo, cp, hlen);
if (!optlen)
if (hlen <= optlen)
break;
hlen -= optlen;
if (hlen <= optlen)
break;
hlen -= optlen;
-trunc:
- nd_print_trunc(ndo);
+invalid:
+ nd_print_invalid(ndo);
}
enum dccp_option_type {
}
enum dccp_option_type {
uint8_t option, optlen, i;
option = GET_U_1(bp);
uint8_t option, optlen, i;
option = GET_U_1(bp);
+ if (option >= 128)
+ ND_PRINT("CCID option %u", option);
+ else
+ ND_PRINT("%s",
+ tok2str(dccp_option_values, "option-type-%u", option));
if (option >= 32) {
optlen = GET_U_1(bp + 1);
if (option >= 32) {
optlen = GET_U_1(bp + 1);
- if (optlen < 2) {
- if (option >= 128)
- ND_PRINT("CCID option %u optlen too short",
- option);
- else
- ND_PRINT("%s optlen too short",
- tok2str(dccp_option_values,
- "Option %u", option));
- return 0;
- }
+ ND_ICHECK_U(optlen, <, 2);
- if (hlen < optlen) {
- if (option >= 128)
- ND_PRINT("CCID option %u optlen goes past header length",
- option);
- else
- ND_PRINT("%s optlen goes past header length",
- tok2str(dccp_option_values, "Option %u",
- option));
- return 0;
- }
- ND_TCHECK_LEN(bp, optlen);
+ ND_ICHECKMSG_U("remaining length", hlen, <, optlen);
- ND_PRINT("CCID option %u", option);
switch (optlen) {
case 4:
ND_PRINT(" %u", GET_BE_U_2(bp + 2));
switch (optlen) {
case 4:
ND_PRINT(" %u", GET_BE_U_2(bp + 2));
ND_PRINT(" %u", GET_BE_U_4(bp + 2));
break;
default:
ND_PRINT(" %u", GET_BE_U_4(bp + 2));
break;
default:
+ ND_PRINT(" 0x");
+ for (i = 0; i < optlen - 2; i++)
+ ND_PRINT("%02x", GET_U_1(bp + 2 + i));
- ND_PRINT("%s",
- tok2str(dccp_option_values, "Option %u", option));
+ case DCCP_OPTION_PADDING:
+ case DCCP_OPTION_MANDATORY:
+ case DCCP_OPTION_SLOW_RECEIVER:
+ ND_TCHECK_1(bp);
+ break;
case DCCP_OPTION_CHANGE_L:
case DCCP_OPTION_CHANGE_L:
- case DCCP_OPTION_CONFIRM_L:
case DCCP_OPTION_CHANGE_R:
case DCCP_OPTION_CHANGE_R:
+ ND_ICHECK_U(optlen, <, 4);
+ ND_PRINT(" %s", tok2str(dccp_feature_num_str,
+ "feature-number-%u (invalid)", GET_U_1(bp + 2)));
+ for (i = 0; i < optlen - 3; i++)
+ ND_PRINT(" %u", GET_U_1(bp + 3 + i));
+ break;
+ case DCCP_OPTION_CONFIRM_L:
case DCCP_OPTION_CONFIRM_R:
case DCCP_OPTION_CONFIRM_R:
- if (optlen < 3) {
- ND_PRINT(" optlen too short");
- return optlen;
- }
+ ND_ICHECK_U(optlen, <, 3);
ND_PRINT(" %s", tok2str(dccp_feature_num_str,
ND_PRINT(" %s", tok2str(dccp_feature_num_str,
- "invalid (%u)", GET_U_1(bp + 2)));
+ "feature-number-%u (invalid)", GET_U_1(bp + 2)));
for (i = 0; i < optlen - 3; i++)
ND_PRINT(" %u", GET_U_1(bp + 3 + i));
break;
case DCCP_OPTION_INIT_COOKIE:
for (i = 0; i < optlen - 3; i++)
ND_PRINT(" %u", GET_U_1(bp + 3 + i));
break;
case DCCP_OPTION_INIT_COOKIE:
- if (optlen > 2) {
- ND_PRINT(" 0x");
- for (i = 0; i < optlen - 2; i++)
- ND_PRINT("%02x",
- GET_U_1(bp + 2 + i));
- }
+ ND_ICHECK_U(optlen, <, 3);
+ ND_PRINT(" 0x");
+ for (i = 0; i < optlen - 2; i++)
+ ND_PRINT("%02x", GET_U_1(bp + 2 + i));
break;
case DCCP_OPTION_NDP_COUNT:
break;
case DCCP_OPTION_NDP_COUNT:
+ ND_ICHECK_U(optlen, <, 3);
+ ND_ICHECK_U(optlen, >, 8);
for (i = 0; i < optlen - 2; i++)
ND_PRINT(" %u", GET_U_1(bp + 2 + i));
break;
case DCCP_OPTION_ACK_VECTOR_NONCE_0:
for (i = 0; i < optlen - 2; i++)
ND_PRINT(" %u", GET_U_1(bp + 2 + i));
break;
case DCCP_OPTION_ACK_VECTOR_NONCE_0:
- if (optlen > 2) {
- ND_PRINT(" 0x");
- for (i = 0; i < optlen - 2; i++)
- ND_PRINT("%02x",
- GET_U_1(bp + 2 + i));
- }
- break;
case DCCP_OPTION_ACK_VECTOR_NONCE_1:
case DCCP_OPTION_ACK_VECTOR_NONCE_1:
- if (optlen > 2) {
- ND_PRINT(" 0x");
- for (i = 0; i < optlen - 2; i++)
- ND_PRINT("%02x",
- GET_U_1(bp + 2 + i));
- }
+ ND_ICHECK_U(optlen, <, 3);
+ ND_PRINT(" 0x");
+ for (i = 0; i < optlen - 2; i++)
+ ND_PRINT("%02x", GET_U_1(bp + 2 + i));
break;
case DCCP_OPTION_DATA_DROPPED:
break;
case DCCP_OPTION_DATA_DROPPED:
- if (optlen > 2) {
- ND_PRINT(" 0x");
- for (i = 0; i < optlen - 2; i++)
- ND_PRINT("%02x",
- GET_U_1(bp + 2 + i));
- }
+ ND_ICHECK_U(optlen, <, 3);
+ ND_PRINT(" 0x");
+ for (i = 0; i < optlen - 2; i++)
+ ND_PRINT("%02x", GET_U_1(bp + 2 + i));
break;
case DCCP_OPTION_TIMESTAMP:
/*
break;
case DCCP_OPTION_TIMESTAMP:
/*
* +--------+--------+--------+--------+--------+--------+
* Type=41 Length=6
*/
* +--------+--------+--------+--------+--------+--------+
* Type=41 Length=6
*/
- if (optlen == 6)
- ND_PRINT(" %u", GET_BE_U_4(bp + 2));
- else
- ND_PRINT(" [optlen != 6]");
+ ND_ICHECK_U(optlen, !=, 6);
+ ND_PRINT(" %u", GET_BE_U_4(bp + 2));
break;
case DCCP_OPTION_TIMESTAMP_ECHO:
/*
break;
case DCCP_OPTION_TIMESTAMP_ECHO:
/*
break;
default:
ND_PRINT(" [optlen != 6 or 8 or 10]");
break;
default:
ND_PRINT(" [optlen != 6 or 8 or 10]");
break;
}
break;
case DCCP_OPTION_ELAPSED_TIME:
break;
}
break;
case DCCP_OPTION_ELAPSED_TIME:
- if (optlen == 6)
- ND_PRINT(" %u", GET_BE_U_4(bp + 2));
- else if (optlen == 4)
+ switch (optlen) {
+ case 4:
ND_PRINT(" %u", GET_BE_U_2(bp + 2));
ND_PRINT(" %u", GET_BE_U_2(bp + 2));
+ break;
+ case 6:
+ ND_PRINT(" %u", GET_BE_U_4(bp + 2));
+ break;
+ default:
ND_PRINT(" [optlen != 4 or 6]");
ND_PRINT(" [optlen != 4 or 6]");
break;
case DCCP_OPTION_DATA_CHECKSUM:
break;
case DCCP_OPTION_DATA_CHECKSUM:
- if (optlen > 2) {
- ND_PRINT(" ");
- for (i = 0; i < optlen - 2; i++)
- ND_PRINT("%02x",
- GET_U_1(bp + 2 + i));
- }
+ ND_ICHECK_U(optlen, !=, 6);
+ ND_PRINT(" 0x");
+ for (i = 0; i < optlen - 2; i++)
+ ND_PRINT("%02x", GET_U_1(bp + 2 + i));
+ default:
+ goto invalid;
-trunc:
- nd_print_trunc(ndo);
1 16:59:25.816632 IP (tos 0x0, ttl 64, id 65312, offset 0, flags [DF], proto DCCP (33), length 52)
139.133.209.176.39420 > 139.133.209.65.5001: DCCP (CCVal 0, CsCov 0, cksum 0xaaf3 (incorrect -> 0x8bf3)) DCCP-Request (service=4105078398) seq 8 <nop, nop, nop, nop, change_l ack_ratio 2, change_r ccid 2, change_l ccid 2>
2 14:27:00.817006 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto DCCP (33), length 68)
1 16:59:25.816632 IP (tos 0x0, ttl 64, id 65312, offset 0, flags [DF], proto DCCP (33), length 52)
139.133.209.176.39420 > 139.133.209.65.5001: DCCP (CCVal 0, CsCov 0, cksum 0xaaf3 (incorrect -> 0x8bf3)) DCCP-Request (service=4105078398) seq 8 <nop, nop, nop, nop, change_l ack_ratio 2, change_r ccid 2, change_l ccid 2>
2 14:27:00.817006 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto DCCP (33), length 68)
- 139.133.209.65.5001 > 139.133.209.176.39420: DCCP (CCVal 0, CsCov 0) DCCP-Response (service=0) (ack=38464816766) seq 1960341146 <nop, nop, change_l ack_ratio 2, [|dccp]>
+ 139.133.209.65.5001 > 139.133.209.176.39420: DCCP (CCVal 0, CsCov 0) DCCP-Response (service=0) (ack=38464816766) seq 1960341146 <nop, nop, change_l ack_ratio 2, confirm_r [|dccp]
3 14:27:00.817125 IP (tos 0x0, ttl 64, id 65313, offset 0, flags [DF], proto DCCP (33), length 56)
3 14:27:00.817125 IP (tos 0x0, ttl 64, id 65313, offset 0, flags [DF], proto DCCP (33), length 56)
- 139.133.209.176.39420 > 139.133.209.65.5001: DCCP (CCVal 0, CsCov 0, cksum 0xf53a (incorrect -> 0xf551)) DCCP-Ack (ack=1960341146) seq 38464816767 <nop, confirm_r ack_ratio 2, ack_vector0 0xe9, timestamp_echo [optlen != 6 or 8 or 10]>
+ 139.133.209.176.39420 > 139.133.209.65.5001: DCCP (CCVal 0, CsCov 0, cksum 0xf53a (incorrect -> 0xf551)) DCCP-Ack (ack=1960341146) seq 38464816767 <nop, confirm_r ack_ratio 2, ack_vector0 0xe9, timestamp_echo [optlen != 6 or 8 or 10] (invalid)
4 14:27:00.829614 IP (tos 0x0, ttl 64, id 65314, offset 0, flags [DF], proto DCCP (33), length 152)
139.133.209.176.46076 > 139.133.209.65.48009: DCCP (CCVal 0, CsCov 6) DCCP-DataAck (ack=1960341146) seq 38464816768 <nop, nop, ack_vector0 0x00, elapsed_time 1249, ndp_count 1>
5 14:27:00.830145 IP (tos 0x0, ttl 64, id 3176, offset 0, flags [DF], proto DCCP (33), length 52)
4 14:27:00.829614 IP (tos 0x0, ttl 64, id 65314, offset 0, flags [DF], proto DCCP (33), length 152)
139.133.209.176.46076 > 139.133.209.65.48009: DCCP (CCVal 0, CsCov 6) DCCP-DataAck (ack=1960341146) seq 38464816768 <nop, nop, ack_vector0 0x00, elapsed_time 1249, ndp_count 1>
5 14:27:00.830145 IP (tos 0x0, ttl 64, id 3176, offset 0, flags [DF], proto DCCP (33), length 52)