X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/b6303af682e72841f79ac6847f93b0cb0a49c549..1fb50928ce27360c1c987312774f686b23c69b51:/print-dccp.c diff --git a/print-dccp.c b/print-dccp.c index d8a98755..6e252642 100644 --- a/print-dccp.c +++ b/print-dccp.c @@ -7,25 +7,26 @@ * BSD-style license that accompanies tcpdump or the GNU GPL version 2 */ -#define NETDISSECT_REWORKED +/* \summary: Datagram Congestion Control Protocol (DCCP) printer */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include +#include #include #include -#include "interface.h" +#include "netdissect.h" #include "addrtoname.h" -#include "extract.h" /* must come after interface.h */ +#include "extract.h" #include "ip.h" -#ifdef INET6 #include "ip6.h" -#endif #include "ipproto.h" +/* RFC4340: Datagram Congestion Control Protocol (DCCP) */ + /** * struct dccp_hdr - generic part of DCCP packet header, with a 24-bit * sequence number @@ -41,13 +42,13 @@ * @dccph_seq - 24-bit sequence number */ struct dccp_hdr { - u_int16_t dccph_sport, + uint16_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 dccph_seq[3]; + uint8_t dccph_doff; + uint8_t dccph_ccval_cscov; + uint16_t dccph_checksum; + uint8_t dccph_xtr; + uint8_t dccph_seq[3]; } UNALIGNED; /** @@ -65,14 +66,14 @@ struct dccp_hdr { * @dccph_seq - 48-bit sequence number */ struct dccp_hdr_ext { - u_int16_t dccph_sport, + uint16_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]; + uint8_t dccph_doff; + uint8_t dccph_ccval_cscov; + uint16_t dccph_checksum; + uint8_t dccph_xtr; + uint8_t reserved; + uint8_t dccph_seq[6]; } UNALIGNED; #define DCCPH_CCVAL(dh) (((dh)->dccph_ccval_cscov >> 4) & 0xF) @@ -87,7 +88,7 @@ struct dccp_hdr_ext { * @dccph_req_service - Service to which the client app wants to connect */ struct dccp_hdr_request { - u_int32_t dccph_req_service; + uint32_t dccph_req_service; } UNALIGNED; /** @@ -97,8 +98,8 @@ struct dccp_hdr_request { * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request */ struct dccp_hdr_response { - u_int8_t dccph_resp_ack[8]; /* always 8 bytes */ - u_int32_t dccph_resp_service; + uint8_t dccph_resp_ack[8]; /* always 8 bytes */ + uint32_t dccph_resp_service; } UNALIGNED; /** @@ -108,8 +109,8 @@ struct dccp_hdr_response { * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request */ struct dccp_hdr_reset { - u_int8_t dccph_reset_ack[8]; /* always 8 bytes */ - u_int8_t dccph_reset_code, + uint8_t dccph_reset_ack[8]; /* always 8 bytes */ + uint8_t dccph_reset_code, dccph_reset_data[3]; } UNALIGNED; @@ -123,8 +124,21 @@ enum dccp_pkt_type { DCCP_PKT_CLOSE, DCCP_PKT_RESET, DCCP_PKT_SYNC, - DCCP_PKT_SYNCACK, - DCCP_PKT_INVALID + DCCP_PKT_SYNCACK +}; + +static const struct tok dccp_pkt_type_str[] = { + { DCCP_PKT_REQUEST, "DCCP-Request" }, + { DCCP_PKT_RESPONSE, "DCCP-Response" }, + { DCCP_PKT_DATA, "DCCP-Data" }, + { DCCP_PKT_ACK, "DCCP-Ack" }, + { DCCP_PKT_DATAACK, "DCCP-DataAck" }, + { DCCP_PKT_CLOSEREQ, "DCCP-CloseReq" }, + { DCCP_PKT_CLOSE, "DCCP-Close" }, + { DCCP_PKT_RESET, "DCCP-Reset" }, + { DCCP_PKT_SYNC, "DCCP-Sync" }, + { DCCP_PKT_SYNCACK, "DCCP-SyncAck" }, + { 0, NULL} }; enum dccp_reset_codes { @@ -179,36 +193,35 @@ static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) if (DCCPH_CSCOV(dh) == 0) return len; - cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(u_int32_t); + cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(uint32_t); return (cov > len)? len : cov; } static int dccp_cksum(netdissect_options *ndo, const struct ip *ip, const struct dccp_hdr *dh, u_int len) { - return nextproto4_cksum(ndo, ip, (const u_int8_t *)(void *)dh, len, + return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)dh, len, dccp_csum_coverage(dh, len), IPPROTO_DCCP); } -#ifdef INET6 -static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len) +static int dccp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, + const struct dccp_hdr *dh, u_int len) { - return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh, len, + return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)dh, len, dccp_csum_coverage(dh, len), IPPROTO_DCCP); } -#endif -static const char *dccp_reset_code(u_int8_t code) +static const char *dccp_reset_code(uint8_t code) { if (code >= __DCCP_RESET_CODE_LAST) return "invalid"; return dccp_reset_codes[code]; } -static u_int64_t dccp_seqno(const u_char *bp) +static uint64_t dccp_seqno(const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; - u_int64_t seqno; + uint64_t seqno; if (DCCPH_X(dh) != 0) { const struct dccp_hdr_ext *dhx = (const struct dccp_hdr_ext *)bp; @@ -229,7 +242,7 @@ static void dccp_print_ack_no(netdissect_options *ndo, const u_char *bp) { const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; const u_char *ackp = bp + dccp_basic_hdr_len(dh); - u_int64_t ackno; + uint64_t ackno; if (DCCPH_X(dh) != 0) { ND_TCHECK2(*ackp, 8); @@ -253,27 +266,24 @@ static int dccp_print_option(netdissect_options *, const u_char *, u_int); * @len - lenght of ip packet */ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, - u_int len) + u_int len) { const struct dccp_hdr *dh; const struct ip *ip; -#ifdef INET6 const struct ip6_hdr *ip6; -#endif const u_char *cp; u_short sport, dport; u_int hlen; u_int fixed_hdrlen; + uint8_t dccph_type; dh = (const struct dccp_hdr *)bp; - ip = (struct ip *)data2; -#ifdef INET6 + ip = (const struct ip *)data2; if (IP_V(ip) == 6) ip6 = (const struct ip6_hdr *)data2; else ip6 = NULL; -#endif /*INET6*/ /* make sure we have enough data to look at the X bit */ cp = (const u_char *)(dh + 1); @@ -283,7 +293,7 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, } if (len < sizeof(struct dccp_hdr)) { ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", - len - (u_int)sizeof(struct dccp_hdr))); + len - (u_int)sizeof(struct dccp_hdr))); return; } @@ -291,7 +301,7 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, fixed_hdrlen = dccp_basic_hdr_len(dh); if (len < fixed_hdrlen) { ND_PRINT((ndo, "truncated-dccp - %u bytes missing!", - len - fixed_hdrlen)); + len - fixed_hdrlen)); return; } ND_TCHECK2(*dh, fixed_hdrlen); @@ -300,155 +310,169 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, dport = EXTRACT_16BITS(&dh->dccph_dport); hlen = dh->dccph_doff * 4; -#ifdef INET6 if (ip6) { ND_PRINT((ndo, "%s.%d > %s.%d: ", - ip6addr_string(&ip6->ip6_src), sport, - ip6addr_string(&ip6->ip6_dst), dport)); - } else -#endif /*INET6*/ - { + ip6addr_string(ndo, &ip6->ip6_src), sport, + ip6addr_string(ndo, &ip6->ip6_dst), dport)); + } else { ND_PRINT((ndo, "%s.%d > %s.%d: ", - ipaddr_string(&ip->ip_src), sport, - ipaddr_string(&ip->ip_dst), dport)); + ipaddr_string(ndo, &ip->ip_src), sport, + ipaddr_string(ndo, &ip->ip_dst), dport)); } + ND_PRINT((ndo, "DCCP")); + if (ndo->ndo_qflag) { ND_PRINT((ndo, " %d", len - hlen)); if (hlen > len) { - ND_PRINT((ndo, "dccp [bad hdr length %u - too long, > %u]", - hlen, len)); + ND_PRINT((ndo, " [bad hdr length %u - too long, > %u]", + hlen, len)); } return; } /* other variables in generic header */ if (ndo->ndo_vflag) { - ND_PRINT((ndo, "CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh))); + ND_PRINT((ndo, " (CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh))); } /* checksum calculation */ if (ndo->ndo_vflag && ND_TTEST2(bp[0], len)) { - u_int16_t sum = 0, dccp_sum; + uint16_t sum = 0, dccp_sum; dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum); ND_PRINT((ndo, "cksum 0x%04x ", dccp_sum)); if (IP_V(ip) == 4) sum = dccp_cksum(ndo, ip, dh, len); -#ifdef INET6 else if (IP_V(ip) == 6) - sum = dccp6_cksum(ip6, dh, len); -#endif + sum = dccp6_cksum(ndo, ip6, dh, len); if (sum != 0) - ND_PRINT((ndo, "(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum))); + ND_PRINT((ndo, "(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum))); else - ND_PRINT((ndo, "(correct), ")); + ND_PRINT((ndo, "(correct)")); } - switch (DCCPH_TYPE(dh)) { + if (ndo->ndo_vflag) + ND_PRINT((ndo, ")")); + ND_PRINT((ndo, " ")); + + dccph_type = DCCPH_TYPE(dh); + switch (dccph_type) { case DCCP_PKT_REQUEST: { - struct dccp_hdr_request *dhr = - (struct dccp_hdr_request *)(bp + fixed_hdrlen); + const struct dccp_hdr_request *dhr = + (const struct dccp_hdr_request *)(bp + fixed_hdrlen); fixed_hdrlen += 4; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp request - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); - ND_PRINT((ndo, "request (service=%d) ", - EXTRACT_32BITS(&dhr->dccph_req_service))); + ND_PRINT((ndo, "%s (service=%d) ", + tok2str(dccp_pkt_type_str, "", dccph_type), + EXTRACT_32BITS(&dhr->dccph_req_service))); break; } case DCCP_PKT_RESPONSE: { - struct dccp_hdr_response *dhr = - (struct dccp_hdr_response *)(bp + fixed_hdrlen); + const struct dccp_hdr_response *dhr = + (const struct dccp_hdr_response *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp response - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); - ND_PRINT((ndo, "response (service=%d) ", - EXTRACT_32BITS(&dhr->dccph_resp_service))); + ND_PRINT((ndo, "%s (service=%d) ", + tok2str(dccp_pkt_type_str, "", dccph_type), + EXTRACT_32BITS(&dhr->dccph_resp_service))); break; } case DCCP_PKT_DATA: - ND_PRINT((ndo, "data ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_ACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp ack - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } - ND_PRINT((ndo, "ack ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; } case DCCP_PKT_DATAACK: { fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp dataack - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } - ND_PRINT((ndo, "dataack ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; } case DCCP_PKT_CLOSEREQ: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp closereq - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } - ND_PRINT((ndo, "closereq ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_CLOSE: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp close - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } - ND_PRINT((ndo, "close ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_RESET: { - struct dccp_hdr_reset *dhr = - (struct dccp_hdr_reset *)(bp + fixed_hdrlen); + const struct dccp_hdr_reset *dhr = + (const struct dccp_hdr_reset *)(bp + fixed_hdrlen); fixed_hdrlen += 12; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp reset - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } ND_TCHECK(*dhr); - ND_PRINT((ndo, "reset (code=%s) ", - dccp_reset_code(dhr->dccph_reset_code))); + ND_PRINT((ndo, "%s (code=%s) ", + tok2str(dccp_pkt_type_str, "", dccph_type), + dccp_reset_code(dhr->dccph_reset_code))); break; } case DCCP_PKT_SYNC: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp sync - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } - ND_PRINT((ndo, "sync ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; case DCCP_PKT_SYNCACK: fixed_hdrlen += 8; if (len < fixed_hdrlen) { - ND_PRINT((ndo, "truncated-dccp syncack - %u bytes missing!", - len - fixed_hdrlen)); + ND_PRINT((ndo, "truncated-%s - %u bytes missing!", + tok2str(dccp_pkt_type_str, "", dccph_type), + len - fixed_hdrlen)); return; } - ND_PRINT((ndo, "syncack ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "", dccph_type))); break; default: - ND_PRINT((ndo, "invalid ")); + ND_PRINT((ndo, "%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type))); break; } @@ -463,7 +487,6 @@ void dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, /* process options */ if (hlen > fixed_hdrlen){ - const u_char *cp; u_int optlen; cp = bp + fixed_hdrlen; ND_PRINT((ndo, " <")); @@ -504,12 +527,12 @@ static const struct tok dccp_option_values[] = { { 42, "timestamp_echo" }, { 43, "elapsed_time" }, { 44, "data_checksum" }, - { 0, NULL } + { 0, NULL } }; static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) { - u_int8_t optlen, i; + uint8_t optlen, i; ND_TCHECK(*option); @@ -521,7 +544,7 @@ static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_in ND_PRINT((ndo, "CCID option %u optlen too short", *option)); else ND_PRINT((ndo, "%s optlen too short", - tok2str(dccp_option_values, "Option %u", *option))); + tok2str(dccp_option_values, "Option %u", *option))); return 0; } } else @@ -530,10 +553,10 @@ static int dccp_print_option(netdissect_options *ndo, const u_char *option, u_in if (hlen < optlen) { if (*option >= 128) ND_PRINT((ndo, "CCID option %u optlen goes past header length", - *option)); + *option)); else ND_PRINT((ndo, "%s optlen goes past header length", - tok2str(dccp_option_values, "Option %u", *option))); + tok2str(dccp_option_values, "Option %u", *option))); return 0; } ND_TCHECK2(*option, optlen);