The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) Arnaldo Carvalho de Melo 2004 |
| 3 | * Copyright (C) Ian McDonald 2005 |
| 4 | * Copyright (C) Yoshifumi Nishida 2005 |
| 5 | * |
| 6 | * This software may be distributed either under the terms of the |
| 7 | * BSD-style license that accompanies tcpdump or the GNU GPL version 2 |
| 8 | */ |
| 9 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 10 | /* \summary: Datagram Congestion Control Protocol (DCCP) printer */ |
| 11 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 12 | /* specification: RFC 4340 */ |
| 13 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 14 | #ifdef HAVE_CONFIG_H |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 15 | #include <config.h> |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 16 | #endif |
| 17 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 18 | #include "netdissect-stdinc.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 19 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 20 | #include "netdissect.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 21 | #include "addrtoname.h" |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 22 | #include "extract.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 23 | #include "ip.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 24 | #include "ip6.h" |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 25 | #include "ipproto.h" |
| 26 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 27 | /* RFC4340: Datagram Congestion Control Protocol (DCCP) */ |
| 28 | |
| 29 | /** |
| 30 | * struct dccp_hdr - generic part of DCCP packet header, with a 24-bit |
| 31 | * sequence number |
| 32 | * |
| 33 | * @dccph_sport - Relevant port on the endpoint that sent this packet |
| 34 | * @dccph_dport - Relevant port on the other endpoint |
| 35 | * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words |
| 36 | * @dccph_ccval - Used by the HC-Sender CCID |
| 37 | * @dccph_cscov - Parts of the packet that are covered by the Checksum field |
| 38 | * @dccph_checksum - Internet checksum, depends on dccph_cscov |
| 39 | * @dccph_x - 0 = 24 bit sequence number, 1 = 48 |
| 40 | * @dccph_type - packet type, see DCCP_PKT_ prefixed macros |
| 41 | * @dccph_seq - 24-bit sequence number |
| 42 | */ |
| 43 | struct dccp_hdr { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 44 | nd_uint16_t dccph_sport, |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 45 | dccph_dport; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 46 | nd_uint8_t dccph_doff; |
| 47 | nd_uint8_t dccph_ccval_cscov; |
| 48 | nd_uint16_t dccph_checksum; |
| 49 | nd_uint8_t dccph_xtr; |
| 50 | nd_uint24_t dccph_seq; |
| 51 | }; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 52 | |
| 53 | /** |
| 54 | * struct dccp_hdr_ext - generic part of DCCP packet header, with a 48-bit |
| 55 | * sequence number |
| 56 | * |
| 57 | * @dccph_sport - Relevant port on the endpoint that sent this packet |
| 58 | * @dccph_dport - Relevant port on the other endpoint |
| 59 | * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words |
| 60 | * @dccph_ccval - Used by the HC-Sender CCID |
| 61 | * @dccph_cscov - Parts of the packet that are covered by the Checksum field |
| 62 | * @dccph_checksum - Internet checksum, depends on dccph_cscov |
| 63 | * @dccph_x - 0 = 24 bit sequence number, 1 = 48 |
| 64 | * @dccph_type - packet type, see DCCP_PKT_ prefixed macros |
| 65 | * @dccph_seq - 48-bit sequence number |
| 66 | */ |
| 67 | struct dccp_hdr_ext { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 68 | nd_uint16_t dccph_sport, |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 69 | dccph_dport; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 70 | nd_uint8_t dccph_doff; |
| 71 | nd_uint8_t dccph_ccval_cscov; |
| 72 | nd_uint16_t dccph_checksum; |
| 73 | nd_uint8_t dccph_xtr; |
| 74 | nd_uint8_t reserved; |
| 75 | nd_uint48_t dccph_seq; |
| 76 | }; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 77 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 78 | #define DCCPH_CCVAL(dh) ((GET_U_1((dh)->dccph_ccval_cscov) >> 4) & 0xF) |
| 79 | #define DCCPH_CSCOV(dh) (GET_U_1((dh)->dccph_ccval_cscov) & 0xF) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 80 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 81 | #define DCCPH_X(dh) (GET_U_1((dh)->dccph_xtr) & 1) |
| 82 | #define DCCPH_TYPE(dh) ((GET_U_1((dh)->dccph_xtr) >> 1) & 0xF) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 83 | |
| 84 | /** |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 85 | * struct dccp_hdr_request - Connection initiation request header |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 86 | * |
| 87 | * @dccph_req_service - Service to which the client app wants to connect |
| 88 | */ |
| 89 | struct dccp_hdr_request { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 90 | nd_uint32_t dccph_req_service; |
| 91 | }; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 92 | |
| 93 | /** |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 94 | * struct dccp_hdr_response - Connection initiation response header |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 95 | * |
| 96 | * @dccph_resp_ack - 48 bit ack number, contains GSR |
| 97 | * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request |
| 98 | */ |
| 99 | struct dccp_hdr_response { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 100 | nd_uint64_t dccph_resp_ack; /* always 8 bytes, first 2 reserved */ |
| 101 | nd_uint32_t dccph_resp_service; |
| 102 | }; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 103 | |
| 104 | /** |
| 105 | * struct dccp_hdr_reset - Unconditionally shut down a connection |
| 106 | * |
| 107 | * @dccph_resp_ack - 48 bit ack number |
| 108 | * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request |
| 109 | */ |
| 110 | struct dccp_hdr_reset { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 111 | nd_uint64_t dccph_reset_ack; /* always 8 bytes, first 2 reserved */ |
| 112 | nd_uint8_t dccph_reset_code; |
| 113 | nd_uint8_t dccph_reset_data1; |
| 114 | nd_uint8_t dccph_reset_data2; |
| 115 | nd_uint8_t dccph_reset_data3; |
| 116 | }; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 117 | |
| 118 | enum dccp_pkt_type { |
| 119 | DCCP_PKT_REQUEST = 0, |
| 120 | DCCP_PKT_RESPONSE, |
| 121 | DCCP_PKT_DATA, |
| 122 | DCCP_PKT_ACK, |
| 123 | DCCP_PKT_DATAACK, |
| 124 | DCCP_PKT_CLOSEREQ, |
| 125 | DCCP_PKT_CLOSE, |
| 126 | DCCP_PKT_RESET, |
| 127 | DCCP_PKT_SYNC, |
| 128 | DCCP_PKT_SYNCACK |
| 129 | }; |
| 130 | |
| 131 | static const struct tok dccp_pkt_type_str[] = { |
| 132 | { DCCP_PKT_REQUEST, "DCCP-Request" }, |
| 133 | { DCCP_PKT_RESPONSE, "DCCP-Response" }, |
| 134 | { DCCP_PKT_DATA, "DCCP-Data" }, |
| 135 | { DCCP_PKT_ACK, "DCCP-Ack" }, |
| 136 | { DCCP_PKT_DATAACK, "DCCP-DataAck" }, |
| 137 | { DCCP_PKT_CLOSEREQ, "DCCP-CloseReq" }, |
| 138 | { DCCP_PKT_CLOSE, "DCCP-Close" }, |
| 139 | { DCCP_PKT_RESET, "DCCP-Reset" }, |
| 140 | { DCCP_PKT_SYNC, "DCCP-Sync" }, |
| 141 | { DCCP_PKT_SYNCACK, "DCCP-SyncAck" }, |
| 142 | { 0, NULL} |
| 143 | }; |
| 144 | |
| 145 | enum dccp_reset_codes { |
| 146 | DCCP_RESET_CODE_UNSPECIFIED = 0, |
| 147 | DCCP_RESET_CODE_CLOSED, |
| 148 | DCCP_RESET_CODE_ABORTED, |
| 149 | DCCP_RESET_CODE_NO_CONNECTION, |
| 150 | DCCP_RESET_CODE_PACKET_ERROR, |
| 151 | DCCP_RESET_CODE_OPTION_ERROR, |
| 152 | DCCP_RESET_CODE_MANDATORY_ERROR, |
| 153 | DCCP_RESET_CODE_CONNECTION_REFUSED, |
| 154 | DCCP_RESET_CODE_BAD_SERVICE_CODE, |
| 155 | DCCP_RESET_CODE_TOO_BUSY, |
| 156 | DCCP_RESET_CODE_BAD_INIT_COOKIE, |
| 157 | DCCP_RESET_CODE_AGGRESSION_PENALTY, |
| 158 | __DCCP_RESET_CODE_LAST |
| 159 | }; |
| 160 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 161 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 162 | static const char *dccp_reset_codes[] = { |
| 163 | "unspecified", |
| 164 | "closed", |
| 165 | "aborted", |
| 166 | "no_connection", |
| 167 | "packet_error", |
| 168 | "option_error", |
| 169 | "mandatory_error", |
| 170 | "connection_refused", |
| 171 | "bad_service_code", |
| 172 | "too_busy", |
| 173 | "bad_init_cookie", |
| 174 | "aggression_penalty", |
| 175 | }; |
| 176 | |
| 177 | static const char *dccp_feature_nums[] = { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 178 | "reserved", |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 179 | "ccid", |
| 180 | "allow_short_seqno", |
| 181 | "sequence_window", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 182 | "ecn_incapable", |
| 183 | "ack_ratio", |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 184 | "send_ack_vector", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 185 | "send_ndp_count", |
| 186 | "minimum checksum coverage", |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 187 | "check data checksum", |
| 188 | }; |
| 189 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 190 | static u_int |
| 191 | dccp_csum_coverage(netdissect_options *ndo, |
| 192 | const struct dccp_hdr* dh, u_int len) |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 193 | { |
| 194 | u_int cov; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 195 | |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 196 | if (DCCPH_CSCOV(dh) == 0) |
| 197 | return len; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 198 | cov = (GET_U_1(dh->dccph_doff) + DCCPH_CSCOV(dh) - 1) * sizeof(uint32_t); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 199 | return (cov > len)? len : cov; |
| 200 | } |
| 201 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 202 | static uint16_t dccp_cksum(netdissect_options *ndo, const struct ip *ip, |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 203 | const struct dccp_hdr *dh, u_int len) |
| 204 | { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 205 | return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)dh, len, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 206 | dccp_csum_coverage(ndo, dh, len), IPPROTO_DCCP); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 207 | } |
| 208 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 209 | static uint16_t dccp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6, |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 210 | const struct dccp_hdr *dh, u_int len) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 211 | { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 212 | return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)dh, len, |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 213 | dccp_csum_coverage(ndo, dh, len), IPPROTO_DCCP); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 214 | } |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 215 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 216 | static const char *dccp_reset_code(uint8_t code) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 217 | { |
| 218 | if (code >= __DCCP_RESET_CODE_LAST) |
| 219 | return "invalid"; |
| 220 | return dccp_reset_codes[code]; |
| 221 | } |
| 222 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 223 | static uint64_t |
| 224 | dccp_seqno(netdissect_options *ndo, const u_char *bp) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 225 | { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 226 | const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; |
| 227 | uint64_t seqno; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 228 | |
| 229 | if (DCCPH_X(dh) != 0) { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 230 | const struct dccp_hdr_ext *dhx = (const struct dccp_hdr_ext *)bp; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 231 | seqno = GET_BE_U_6(dhx->dccph_seq); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 232 | } else { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 233 | seqno = GET_BE_U_3(dh->dccph_seq); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 234 | } |
| 235 | |
| 236 | return seqno; |
| 237 | } |
| 238 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 239 | static unsigned int |
| 240 | dccp_basic_hdr_len(netdissect_options *ndo, const struct dccp_hdr *dh) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 241 | { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 242 | return DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : sizeof(struct dccp_hdr); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 243 | } |
| 244 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 245 | static void dccp_print_ack_no(netdissect_options *ndo, const u_char *bp) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 246 | { |
| 247 | const struct dccp_hdr *dh = (const struct dccp_hdr *)bp; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 248 | const u_char *ackp = bp + dccp_basic_hdr_len(ndo, dh); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 249 | uint64_t ackno; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 250 | |
| 251 | if (DCCPH_X(dh) != 0) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 252 | ackno = GET_BE_U_6(ackp + 2); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 253 | } else { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 254 | ackno = GET_BE_U_3(ackp + 1); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 255 | } |
| 256 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 257 | ND_PRINT("(ack=%" PRIu64 ") ", ackno); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 258 | } |
| 259 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 260 | static u_int dccp_print_option(netdissect_options *, const u_char *, u_int); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 261 | |
| 262 | /** |
| 263 | * dccp_print - show dccp packet |
| 264 | * @bp - beginning of dccp packet |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 265 | * @data2 - beginning of enclosing |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 266 | * @len - length of ip packet |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 267 | */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 268 | void |
| 269 | dccp_print(netdissect_options *ndo, const u_char *bp, const u_char *data2, |
| 270 | u_int len) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 271 | { |
| 272 | const struct dccp_hdr *dh; |
| 273 | const struct ip *ip; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 274 | const struct ip6_hdr *ip6; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 275 | const u_char *cp; |
| 276 | u_short sport, dport; |
| 277 | u_int hlen; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 278 | u_int fixed_hdrlen; |
| 279 | uint8_t dccph_type; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 280 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 281 | ndo->ndo_protocol = "dccp"; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 282 | dh = (const struct dccp_hdr *)bp; |
| 283 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 284 | ip = (const struct ip *)data2; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 285 | if (IP_V(ip) == 6) |
| 286 | ip6 = (const struct ip6_hdr *)data2; |
| 287 | else |
| 288 | ip6 = NULL; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 289 | |
| 290 | /* make sure we have enough data to look at the X bit */ |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 291 | cp = (const u_char *)(dh + 1); |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 292 | if (cp > ndo->ndo_snapend) |
| 293 | goto trunc; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 294 | if (len < sizeof(struct dccp_hdr)) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 295 | ND_PRINT("truncated-dccp - %zu bytes missing!", |
| 296 | sizeof(struct dccp_hdr) - len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 297 | return; |
| 298 | } |
| 299 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 300 | /* get the length of the generic header */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 301 | fixed_hdrlen = dccp_basic_hdr_len(ndo, dh); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 302 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 303 | ND_PRINT("truncated-dccp - %u bytes missing!", |
| 304 | fixed_hdrlen - len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 305 | return; |
| 306 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 307 | ND_TCHECK_LEN(dh, fixed_hdrlen); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 308 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 309 | sport = GET_BE_U_2(dh->dccph_sport); |
| 310 | dport = GET_BE_U_2(dh->dccph_dport); |
| 311 | hlen = GET_U_1(dh->dccph_doff) * 4; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 312 | |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 313 | if (ip6) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 314 | ND_PRINT("%s.%u > %s.%u: ", |
| 315 | GET_IP6ADDR_STRING(ip6->ip6_src), sport, |
| 316 | GET_IP6ADDR_STRING(ip6->ip6_dst), dport); |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 317 | } else { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 318 | ND_PRINT("%s.%u > %s.%u: ", |
| 319 | GET_IPADDR_STRING(ip->ip_src), sport, |
| 320 | GET_IPADDR_STRING(ip->ip_dst), dport); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 321 | } |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 322 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 323 | nd_print_protocol_caps(ndo); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 324 | |
| 325 | if (ndo->ndo_qflag) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 326 | ND_PRINT(" %u", len - hlen); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 327 | if (hlen > len) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 328 | ND_PRINT(" [bad hdr length %u - too long, > %u]", |
| 329 | hlen, len); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 330 | } |
| 331 | return; |
| 332 | } |
| 333 | |
| 334 | /* other variables in generic header */ |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 335 | if (ndo->ndo_vflag) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 336 | ND_PRINT(" (CCVal %u, CsCov %u, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 337 | } |
| 338 | |
| 339 | /* checksum calculation */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 340 | if (ndo->ndo_vflag && ND_TTEST_LEN(bp, len)) { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 341 | uint16_t sum = 0, dccp_sum; |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 342 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 343 | dccp_sum = GET_BE_U_2(dh->dccph_checksum); |
| 344 | ND_PRINT("cksum 0x%04x ", dccp_sum); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 345 | if (IP_V(ip) == 4) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 346 | sum = dccp_cksum(ndo, ip, dh, len); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 347 | else if (IP_V(ip) == 6) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 348 | sum = dccp6_cksum(ndo, ip6, dh, len); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 349 | if (sum != 0) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 350 | ND_PRINT("(incorrect -> 0x%04x)",in_cksum_shouldbe(dccp_sum, sum)); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 351 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 352 | ND_PRINT("(correct)"); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 353 | } |
| 354 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 355 | if (ndo->ndo_vflag) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 356 | ND_PRINT(")"); |
| 357 | ND_PRINT(" "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 358 | |
| 359 | dccph_type = DCCPH_TYPE(dh); |
| 360 | switch (dccph_type) { |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 361 | case DCCP_PKT_REQUEST: { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 362 | const struct dccp_hdr_request *dhr = |
| 363 | (const struct dccp_hdr_request *)(bp + fixed_hdrlen); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 364 | fixed_hdrlen += 4; |
| 365 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 366 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 367 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 368 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 369 | return; |
| 370 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 371 | ND_TCHECK_SIZE(dhr); |
| 372 | ND_PRINT("%s (service=%u) ", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 373 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 374 | GET_BE_U_4(dhr->dccph_req_service)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 375 | break; |
| 376 | } |
| 377 | case DCCP_PKT_RESPONSE: { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 378 | const struct dccp_hdr_response *dhr = |
| 379 | (const struct dccp_hdr_response *)(bp + fixed_hdrlen); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 380 | fixed_hdrlen += 12; |
| 381 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 382 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 383 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 384 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 385 | return; |
| 386 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 387 | ND_TCHECK_SIZE(dhr); |
| 388 | ND_PRINT("%s (service=%u) ", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 389 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 390 | GET_BE_U_4(dhr->dccph_resp_service)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 391 | break; |
| 392 | } |
| 393 | case DCCP_PKT_DATA: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 394 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 395 | break; |
| 396 | case DCCP_PKT_ACK: { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 397 | fixed_hdrlen += 8; |
| 398 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 399 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 400 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 401 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 402 | return; |
| 403 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 404 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 405 | break; |
| 406 | } |
| 407 | case DCCP_PKT_DATAACK: { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 408 | fixed_hdrlen += 8; |
| 409 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 410 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 411 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 412 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 413 | return; |
| 414 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 415 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 416 | break; |
| 417 | } |
| 418 | case DCCP_PKT_CLOSEREQ: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 419 | fixed_hdrlen += 8; |
| 420 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 421 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 422 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 423 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 424 | return; |
| 425 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 426 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 427 | break; |
| 428 | case DCCP_PKT_CLOSE: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 429 | fixed_hdrlen += 8; |
| 430 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 431 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 432 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 433 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 434 | return; |
| 435 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 436 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 437 | break; |
| 438 | case DCCP_PKT_RESET: { |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 439 | const struct dccp_hdr_reset *dhr = |
| 440 | (const struct dccp_hdr_reset *)(bp + fixed_hdrlen); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 441 | fixed_hdrlen += 12; |
| 442 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 443 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 444 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 445 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 446 | return; |
| 447 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 448 | ND_TCHECK_SIZE(dhr); |
| 449 | ND_PRINT("%s (code=%s) ", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 450 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 451 | dccp_reset_code(GET_U_1(dhr->dccph_reset_code))); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 452 | break; |
| 453 | } |
| 454 | case DCCP_PKT_SYNC: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 455 | fixed_hdrlen += 8; |
| 456 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 457 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 458 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 459 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 460 | return; |
| 461 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 462 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 463 | break; |
| 464 | case DCCP_PKT_SYNCACK: |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 465 | fixed_hdrlen += 8; |
| 466 | if (len < fixed_hdrlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 467 | ND_PRINT("truncated-%s - %u bytes missing!", |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 468 | tok2str(dccp_pkt_type_str, "", dccph_type), |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 469 | fixed_hdrlen - len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 470 | return; |
| 471 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 472 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 473 | break; |
| 474 | default: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 475 | ND_PRINT("%s ", tok2str(dccp_pkt_type_str, "unknown-type-%u", dccph_type)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 476 | break; |
| 477 | } |
| 478 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 479 | if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) && |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 480 | (DCCPH_TYPE(dh) != DCCP_PKT_REQUEST)) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 481 | dccp_print_ack_no(ndo, bp); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 482 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 483 | if (ndo->ndo_vflag < 2) |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 484 | return; |
| 485 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 486 | ND_PRINT("seq %" PRIu64, dccp_seqno(ndo, bp)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 487 | |
| 488 | /* process options */ |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 489 | if (hlen > fixed_hdrlen){ |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 490 | u_int optlen; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 491 | cp = bp + fixed_hdrlen; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 492 | ND_PRINT(" <"); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 493 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 494 | hlen -= fixed_hdrlen; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 495 | while(1){ |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 496 | optlen = dccp_print_option(ndo, cp, hlen); |
| 497 | if (!optlen) |
| 498 | break; |
| 499 | if (hlen <= optlen) |
| 500 | break; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 501 | hlen -= optlen; |
| 502 | cp += optlen; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 503 | ND_PRINT(", "); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 504 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 505 | ND_PRINT(">"); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 506 | } |
| 507 | return; |
| 508 | trunc: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 509 | nd_print_trunc(ndo); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 510 | } |
| 511 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 512 | static const struct tok dccp_option_values[] = { |
| 513 | { 0, "nop" }, |
| 514 | { 1, "mandatory" }, |
| 515 | { 2, "slowreceiver" }, |
| 516 | { 32, "change_l" }, |
| 517 | { 33, "confirm_l" }, |
| 518 | { 34, "change_r" }, |
| 519 | { 35, "confirm_r" }, |
| 520 | { 36, "initcookie" }, |
| 521 | { 37, "ndp_count" }, |
| 522 | { 38, "ack_vector0" }, |
| 523 | { 39, "ack_vector1" }, |
| 524 | { 40, "data_dropped" }, |
| 525 | { 41, "timestamp" }, |
| 526 | { 42, "timestamp_echo" }, |
| 527 | { 43, "elapsed_time" }, |
| 528 | { 44, "data_checksum" }, |
| 529 | { 0, NULL } |
| 530 | }; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 531 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 532 | static u_int |
| 533 | dccp_print_option(netdissect_options *ndo, const u_char *option, u_int hlen) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 534 | { |
| 535 | uint8_t optlen, i; |
| 536 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 537 | if (GET_U_1(option) >= 32) { |
| 538 | optlen = GET_U_1(option + 1); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 539 | if (optlen < 2) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 540 | if (GET_U_1(option) >= 128) |
| 541 | ND_PRINT("CCID option %u optlen too short", |
| 542 | GET_U_1(option)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 543 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 544 | ND_PRINT("%s optlen too short", |
| 545 | tok2str(dccp_option_values, "Option %u", GET_U_1(option))); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 546 | return 0; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 547 | } |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 548 | } else |
| 549 | optlen = 1; |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 550 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 551 | if (hlen < optlen) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 552 | if (GET_U_1(option) >= 128) |
| 553 | ND_PRINT("CCID option %u optlen goes past header length", |
| 554 | GET_U_1(option)); |
JP Abgrall | 53f17a9 | 2014-02-12 14:02:41 -0800 | [diff] [blame] | 555 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 556 | ND_PRINT("%s optlen goes past header length", |
| 557 | tok2str(dccp_option_values, "Option %u", GET_U_1(option))); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 558 | return 0; |
| 559 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 560 | ND_TCHECK_LEN(option, optlen); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 561 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 562 | if (GET_U_1(option) >= 128) { |
| 563 | ND_PRINT("CCID option %u", GET_U_1(option)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 564 | switch (optlen) { |
| 565 | case 4: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 566 | ND_PRINT(" %u", GET_BE_U_2(option + 2)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 567 | break; |
| 568 | case 6: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 569 | ND_PRINT(" %u", GET_BE_U_4(option + 2)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 570 | break; |
| 571 | default: |
| 572 | break; |
| 573 | } |
| 574 | } else { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 575 | ND_PRINT("%s", |
| 576 | tok2str(dccp_option_values, "Option %u", GET_U_1(option))); |
| 577 | switch (GET_U_1(option)) { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 578 | case 32: |
| 579 | case 33: |
| 580 | case 34: |
| 581 | case 35: |
| 582 | if (optlen < 3) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 583 | ND_PRINT(" optlen too short"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 584 | return optlen; |
| 585 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 586 | if (GET_U_1(option + 2) < 10){ |
| 587 | ND_PRINT(" %s", |
| 588 | dccp_feature_nums[GET_U_1(option + 2)]); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 589 | for (i = 0; i < optlen - 3; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 590 | ND_PRINT(" %u", |
| 591 | GET_U_1(option + 3 + i)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 592 | } |
| 593 | break; |
| 594 | case 36: |
| 595 | if (optlen > 2) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 596 | ND_PRINT(" 0x"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 597 | for (i = 0; i < optlen - 2; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 598 | ND_PRINT("%02x", |
| 599 | GET_U_1(option + 2 + i)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 600 | } |
| 601 | break; |
| 602 | case 37: |
| 603 | for (i = 0; i < optlen - 2; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 604 | ND_PRINT(" %u", GET_U_1(option + 2 + i)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 605 | break; |
| 606 | case 38: |
| 607 | if (optlen > 2) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 608 | ND_PRINT(" 0x"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 609 | for (i = 0; i < optlen - 2; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 610 | ND_PRINT("%02x", |
| 611 | GET_U_1(option + 2 + i)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 612 | } |
| 613 | break; |
| 614 | case 39: |
| 615 | if (optlen > 2) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 616 | ND_PRINT(" 0x"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 617 | for (i = 0; i < optlen - 2; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 618 | ND_PRINT("%02x", |
| 619 | GET_U_1(option + 2 + i)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 620 | } |
| 621 | break; |
| 622 | case 40: |
| 623 | if (optlen > 2) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 624 | ND_PRINT(" 0x"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 625 | for (i = 0; i < optlen - 2; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 626 | ND_PRINT("%02x", |
| 627 | GET_U_1(option + 2 + i)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 628 | } |
| 629 | break; |
| 630 | case 41: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 631 | /* |
| 632 | * 13.1. Timestamp Option |
| 633 | * |
| 634 | * +--------+--------+--------+--------+--------+--------+ |
| 635 | * |00101001|00000110| Timestamp Value | |
| 636 | * +--------+--------+--------+--------+--------+--------+ |
| 637 | * Type=41 Length=6 |
| 638 | */ |
| 639 | if (optlen == 6) |
| 640 | ND_PRINT(" %u", GET_BE_U_4(option + 2)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 641 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 642 | ND_PRINT(" [optlen != 6]"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 643 | break; |
| 644 | case 42: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 645 | /* |
| 646 | * 13.3. Timestamp Echo Option |
| 647 | * |
| 648 | * +--------+--------+--------+--------+--------+--------+ |
| 649 | * |00101010|00000110| Timestamp Echo | |
| 650 | * +--------+--------+--------+--------+--------+--------+ |
| 651 | * Type=42 Len=6 |
| 652 | * |
| 653 | * +--------+--------+------- ... -------+--------+--------+ |
| 654 | * |00101010|00001000| Timestamp Echo | Elapsed Time | |
| 655 | * +--------+--------+------- ... -------+--------+--------+ |
| 656 | * Type=42 Len=8 (4 bytes) |
| 657 | * |
| 658 | * +--------+--------+------- ... -------+------- ... -------+ |
| 659 | * |00101010|00001010| Timestamp Echo | Elapsed Time | |
| 660 | * +--------+--------+------- ... -------+------- ... -------+ |
| 661 | * Type=42 Len=10 (4 bytes) (4 bytes) |
| 662 | */ |
| 663 | switch (optlen) { |
| 664 | case 6: |
| 665 | ND_PRINT(" %u", GET_BE_U_4(option + 2)); |
| 666 | break; |
| 667 | case 8: |
| 668 | ND_PRINT(" %u", GET_BE_U_4(option + 2)); |
| 669 | ND_PRINT(" (elapsed time %u)", |
| 670 | GET_BE_U_2(option + 6)); |
| 671 | break; |
| 672 | case 10: |
| 673 | ND_PRINT(" %u", GET_BE_U_4(option + 2)); |
| 674 | ND_PRINT(" (elapsed time %u)", |
| 675 | GET_BE_U_4(option + 6)); |
| 676 | break; |
| 677 | default: |
| 678 | ND_PRINT(" [optlen != 6 or 8 or 10]"); |
| 679 | break; |
| 680 | } |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 681 | break; |
| 682 | case 43: |
| 683 | if (optlen == 6) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 684 | ND_PRINT(" %u", GET_BE_U_4(option + 2)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 685 | else if (optlen == 4) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 686 | ND_PRINT(" %u", GET_BE_U_2(option + 2)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 687 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 688 | ND_PRINT(" [optlen != 4 or 6]"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 689 | break; |
| 690 | case 44: |
| 691 | if (optlen > 2) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 692 | ND_PRINT(" "); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 693 | for (i = 0; i < optlen - 2; i++) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 694 | ND_PRINT("%02x", |
| 695 | GET_U_1(option + 2 + i)); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 696 | } |
| 697 | break; |
| 698 | } |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 699 | } |
| 700 | |
| 701 | return optlen; |
| 702 | trunc: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 703 | nd_print_trunc(ndo); |
The Android Open Source Project | 2949f58 | 2009-03-03 19:30:46 -0800 | [diff] [blame] | 704 | return 0; |
| 705 | } |