Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 1 | /* |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 2 | * Copyright (c) 2013 The TCPDUMP project |
| 3 | * All rights reserved. |
| 4 | * |
| 5 | * Redistribution and use in source and binary forms, with or without |
| 6 | * modification, are permitted provided that the following conditions |
| 7 | * are met: |
| 8 | * 1. Redistributions of source code must retain the above copyright |
| 9 | * notice, this list of conditions and the following disclaimer. |
| 10 | * 2. Redistributions in binary form must reproduce the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer in the |
| 12 | * documentation and/or other materials provided with the distribution. |
| 13 | * |
| 14 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 15 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 16 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| 17 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| 18 | * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| 19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| 20 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 21 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| 22 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| 24 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 25 | * POSSIBILITY OF SUCH DAMAGE. |
| 26 | */ |
| 27 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 28 | /* \summary: Ad Hoc Configuration Protocol (AHCP) printer */ |
| 29 | |
| 30 | /* Based on draft-chroboczek-ahcp-00 and source code of ahcpd-0.53 */ |
| 31 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 32 | #ifdef HAVE_CONFIG_H |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 33 | #include <config.h> |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 34 | #endif |
| 35 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 36 | #include "netdissect-stdinc.h" |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 37 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 38 | #define ND_LONGJMP_FROM_TCHECK |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 39 | #include "netdissect.h" |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 40 | #include "extract.h" |
| 41 | #include "addrtoname.h" |
| 42 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 43 | |
| 44 | #define AHCP_MAGIC_NUMBER 43 |
| 45 | #define AHCP_VERSION_1 1 |
| 46 | #define AHCP1_HEADER_FIX_LEN 24 |
| 47 | #define AHCP1_BODY_MIN_LEN 4 |
| 48 | |
| 49 | #define AHCP1_MSG_DISCOVER 0 |
| 50 | #define AHCP1_MSG_OFFER 1 |
| 51 | #define AHCP1_MSG_REQUEST 2 |
| 52 | #define AHCP1_MSG_ACK 3 |
| 53 | #define AHCP1_MSG_NACK 4 |
| 54 | #define AHCP1_MSG_RELEASE 5 |
| 55 | |
| 56 | static const struct tok ahcp1_msg_str[] = { |
| 57 | { AHCP1_MSG_DISCOVER, "Discover" }, |
| 58 | { AHCP1_MSG_OFFER, "Offer" }, |
| 59 | { AHCP1_MSG_REQUEST, "Request" }, |
| 60 | { AHCP1_MSG_ACK, "Ack" }, |
| 61 | { AHCP1_MSG_NACK, "Nack" }, |
| 62 | { AHCP1_MSG_RELEASE, "Release" }, |
| 63 | { 0, NULL } |
| 64 | }; |
| 65 | |
| 66 | #define AHCP1_OPT_PAD 0 |
| 67 | #define AHCP1_OPT_MANDATORY 1 |
| 68 | #define AHCP1_OPT_ORIGIN_TIME 2 |
| 69 | #define AHCP1_OPT_EXPIRES 3 |
| 70 | #define AHCP1_OPT_MY_IPV6_ADDRESS 4 |
| 71 | #define AHCP1_OPT_MY_IPV4_ADDRESS 5 |
| 72 | #define AHCP1_OPT_IPV6_PREFIX 6 |
| 73 | #define AHCP1_OPT_IPV4_PREFIX 7 |
| 74 | #define AHCP1_OPT_IPV6_ADDRESS 8 |
| 75 | #define AHCP1_OPT_IPV4_ADDRESS 9 |
| 76 | #define AHCP1_OPT_IPV6_PREFIX_DELEGATION 10 |
| 77 | #define AHCP1_OPT_IPV4_PREFIX_DELEGATION 11 |
| 78 | #define AHCP1_OPT_NAME_SERVER 12 |
| 79 | #define AHCP1_OPT_NTP_SERVER 13 |
| 80 | #define AHCP1_OPT_MAX 13 |
| 81 | |
| 82 | static const struct tok ahcp1_opt_str[] = { |
| 83 | { AHCP1_OPT_PAD, "Pad" }, |
| 84 | { AHCP1_OPT_MANDATORY, "Mandatory" }, |
| 85 | { AHCP1_OPT_ORIGIN_TIME, "Origin Time" }, |
| 86 | { AHCP1_OPT_EXPIRES, "Expires" }, |
| 87 | { AHCP1_OPT_MY_IPV6_ADDRESS, "My-IPv6-Address" }, |
| 88 | { AHCP1_OPT_MY_IPV4_ADDRESS, "My-IPv4-Address" }, |
| 89 | { AHCP1_OPT_IPV6_PREFIX, "IPv6 Prefix" }, |
| 90 | { AHCP1_OPT_IPV4_PREFIX, "IPv4 Prefix" }, |
| 91 | { AHCP1_OPT_IPV6_ADDRESS, "IPv6 Address" }, |
| 92 | { AHCP1_OPT_IPV4_ADDRESS, "IPv4 Address" }, |
| 93 | { AHCP1_OPT_IPV6_PREFIX_DELEGATION, "IPv6 Prefix Delegation" }, |
| 94 | { AHCP1_OPT_IPV4_PREFIX_DELEGATION, "IPv4 Prefix Delegation" }, |
| 95 | { AHCP1_OPT_NAME_SERVER, "Name Server" }, |
| 96 | { AHCP1_OPT_NTP_SERVER, "NTP Server" }, |
| 97 | { 0, NULL } |
| 98 | }; |
| 99 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 100 | static void |
| 101 | ahcp_time_print(netdissect_options *ndo, |
| 102 | const u_char *cp, uint8_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 103 | { |
| 104 | time_t t; |
| 105 | struct tm *tm; |
| 106 | char buf[BUFSIZE]; |
| 107 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 108 | if (len != 4) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 109 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 110 | t = GET_BE_U_4(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 111 | if (NULL == (tm = gmtime(&t))) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 112 | ND_PRINT(": gmtime() error"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 113 | else if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 114 | ND_PRINT(": strftime() error"); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 115 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 116 | ND_PRINT(": %s UTC", buf); |
| 117 | return; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 118 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 119 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 120 | nd_print_invalid(ndo); |
| 121 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 122 | } |
| 123 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 124 | static void |
| 125 | ahcp_seconds_print(netdissect_options *ndo, |
| 126 | const u_char *cp, uint8_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 127 | { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 128 | if (len != 4) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 129 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 130 | ND_PRINT(": %us", GET_BE_U_4(cp)); |
| 131 | return; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 132 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 133 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 134 | nd_print_invalid(ndo); |
| 135 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 136 | } |
| 137 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 138 | static void |
| 139 | ahcp_ipv6_addresses_print(netdissect_options *ndo, |
| 140 | const u_char *cp, uint8_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 141 | { |
| 142 | const char *sep = ": "; |
| 143 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 144 | while (len) { |
| 145 | if (len < 16) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 146 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 147 | ND_PRINT("%s%s", sep, GET_IP6ADDR_STRING(cp)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 148 | cp += 16; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 149 | len -= 16; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 150 | sep = ", "; |
| 151 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 152 | return; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 153 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 154 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 155 | nd_print_invalid(ndo); |
| 156 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 157 | } |
| 158 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 159 | static void |
| 160 | ahcp_ipv4_addresses_print(netdissect_options *ndo, |
| 161 | const u_char *cp, uint8_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 162 | { |
| 163 | const char *sep = ": "; |
| 164 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 165 | while (len) { |
| 166 | if (len < 4) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 167 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 168 | ND_PRINT("%s%s", sep, GET_IPADDR_STRING(cp)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 169 | cp += 4; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 170 | len -= 4; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 171 | sep = ", "; |
| 172 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 173 | return; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 174 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 175 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 176 | nd_print_invalid(ndo); |
| 177 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 178 | } |
| 179 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 180 | static void |
| 181 | ahcp_ipv6_prefixes_print(netdissect_options *ndo, |
| 182 | const u_char *cp, uint8_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 183 | { |
| 184 | const char *sep = ": "; |
| 185 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 186 | while (len) { |
| 187 | if (len < 17) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 188 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 189 | ND_PRINT("%s%s/%u", sep, GET_IP6ADDR_STRING(cp), GET_U_1(cp + 16)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 190 | cp += 17; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 191 | len -= 17; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 192 | sep = ", "; |
| 193 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 194 | return; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 195 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 196 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 197 | nd_print_invalid(ndo); |
| 198 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 199 | } |
| 200 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 201 | static void |
| 202 | ahcp_ipv4_prefixes_print(netdissect_options *ndo, |
| 203 | const u_char *cp, uint8_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 204 | { |
| 205 | const char *sep = ": "; |
| 206 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 207 | while (len) { |
| 208 | if (len < 5) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 209 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 210 | ND_PRINT("%s%s/%u", sep, GET_IPADDR_STRING(cp), GET_U_1(cp + 4)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 211 | cp += 5; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 212 | len -= 5; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 213 | sep = ", "; |
| 214 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 215 | return; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 216 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 217 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 218 | nd_print_invalid(ndo); |
| 219 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 220 | } |
| 221 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 222 | static void |
| 223 | (* const data_decoders[AHCP1_OPT_MAX + 1])(netdissect_options *, const u_char *, uint8_t) = { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 224 | /* [AHCP1_OPT_PAD] = */ NULL, |
| 225 | /* [AHCP1_OPT_MANDATORY] = */ NULL, |
| 226 | /* [AHCP1_OPT_ORIGIN_TIME] = */ ahcp_time_print, |
| 227 | /* [AHCP1_OPT_EXPIRES] = */ ahcp_seconds_print, |
| 228 | /* [AHCP1_OPT_MY_IPV6_ADDRESS] = */ ahcp_ipv6_addresses_print, |
| 229 | /* [AHCP1_OPT_MY_IPV4_ADDRESS] = */ ahcp_ipv4_addresses_print, |
| 230 | /* [AHCP1_OPT_IPV6_PREFIX] = */ ahcp_ipv6_prefixes_print, |
| 231 | /* [AHCP1_OPT_IPV4_PREFIX] = */ NULL, |
| 232 | /* [AHCP1_OPT_IPV6_ADDRESS] = */ ahcp_ipv6_addresses_print, |
| 233 | /* [AHCP1_OPT_IPV4_ADDRESS] = */ ahcp_ipv4_addresses_print, |
| 234 | /* [AHCP1_OPT_IPV6_PREFIX_DELEGATION] = */ ahcp_ipv6_prefixes_print, |
| 235 | /* [AHCP1_OPT_IPV4_PREFIX_DELEGATION] = */ ahcp_ipv4_prefixes_print, |
| 236 | /* [AHCP1_OPT_NAME_SERVER] = */ ahcp_ipv6_addresses_print, |
| 237 | /* [AHCP1_OPT_NTP_SERVER] = */ ahcp_ipv6_addresses_print, |
| 238 | }; |
| 239 | |
| 240 | static void |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 241 | ahcp1_options_print(netdissect_options *ndo, |
| 242 | const u_char *cp, uint16_t len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 243 | { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 244 | while (len) { |
| 245 | uint8_t option_no, option_len; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 246 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 247 | /* Option no */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 248 | option_no = GET_U_1(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 249 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 250 | len -= 1; |
| 251 | ND_PRINT("\n\t %s", tok2str(ahcp1_opt_str, "Unknown-%u", option_no)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 252 | if (option_no == AHCP1_OPT_PAD || option_no == AHCP1_OPT_MANDATORY) |
| 253 | continue; |
| 254 | /* Length */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 255 | if (!len) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 256 | goto invalid; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 257 | option_len = GET_U_1(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 258 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 259 | len -= 1; |
| 260 | if (option_len > len) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 261 | goto invalid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 262 | /* Value */ |
| 263 | if (option_no <= AHCP1_OPT_MAX && data_decoders[option_no] != NULL) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 264 | data_decoders[option_no](ndo, cp, option_len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 265 | } else { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 266 | ND_PRINT(" (Length %u)", option_len); |
| 267 | ND_TCHECK_LEN(cp, option_len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 268 | } |
| 269 | cp += option_len; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 270 | len -= option_len; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 271 | } |
| 272 | return; |
| 273 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 274 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 275 | nd_print_invalid(ndo); |
| 276 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 277 | } |
| 278 | |
| 279 | static void |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 280 | ahcp1_body_print(netdissect_options *ndo, |
| 281 | const u_char *cp, u_int len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 282 | { |
| 283 | uint8_t type, mbz; |
| 284 | uint16_t body_len; |
| 285 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 286 | if (len < AHCP1_BODY_MIN_LEN) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 287 | goto invalid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 288 | /* Type */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 289 | type = GET_U_1(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 290 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 291 | len -= 1; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 292 | /* MBZ */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 293 | mbz = GET_U_1(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 294 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 295 | len -= 1; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 296 | /* Length */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 297 | body_len = GET_BE_U_2(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 298 | cp += 2; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 299 | len -= 2; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 300 | |
| 301 | if (ndo->ndo_vflag) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 302 | ND_PRINT("\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 303 | if (mbz != 0) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 304 | ND_PRINT(", MBZ %u", mbz); |
| 305 | ND_PRINT(", Length %u", body_len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 306 | } |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 307 | if (body_len > len) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 308 | goto invalid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 309 | |
| 310 | /* Options */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 311 | /* Here use "body_len", not "len" (ignore any extra data). */ |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 312 | if (ndo->ndo_vflag >= 2) |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 313 | ahcp1_options_print(ndo, cp, body_len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 314 | else |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 315 | ND_TCHECK_LEN(cp, body_len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 316 | return; |
| 317 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 318 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 319 | nd_print_invalid(ndo); |
| 320 | ND_TCHECK_LEN(cp, len); |
| 321 | |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 322 | } |
| 323 | |
| 324 | void |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 325 | ahcp_print(netdissect_options *ndo, |
| 326 | const u_char *cp, u_int len) |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 327 | { |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 328 | uint8_t version; |
| 329 | |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 330 | ndo->ndo_protocol = "ahcp"; |
| 331 | nd_print_protocol_caps(ndo); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 332 | if (len < 2) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 333 | goto invalid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 334 | /* Magic */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 335 | if (GET_U_1(cp) != AHCP_MAGIC_NUMBER) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 336 | goto invalid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 337 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 338 | len -= 1; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 339 | /* Version */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 340 | version = GET_U_1(cp); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 341 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 342 | len -= 1; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 343 | switch (version) { |
| 344 | case AHCP_VERSION_1: { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 345 | ND_PRINT(" Version 1"); |
| 346 | if (len < AHCP1_HEADER_FIX_LEN - 2) |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 347 | goto invalid; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 348 | if (!ndo->ndo_vflag) { |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 349 | ND_TCHECK_LEN(cp, AHCP1_HEADER_FIX_LEN - 2); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 350 | cp += AHCP1_HEADER_FIX_LEN - 2; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 351 | len -= AHCP1_HEADER_FIX_LEN - 2; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 352 | } else { |
| 353 | /* Hopcount */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 354 | ND_PRINT("\n\tHopcount %u", GET_U_1(cp)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 355 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 356 | len -= 1; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 357 | /* Original Hopcount */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 358 | ND_PRINT(", Original Hopcount %u", GET_U_1(cp)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 359 | cp += 1; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 360 | len -= 1; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 361 | /* Nonce */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 362 | ND_PRINT(", Nonce 0x%08x", GET_BE_U_4(cp)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 363 | cp += 4; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 364 | len -= 4; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 365 | /* Source Id */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 366 | ND_PRINT(", Source Id %s", GET_LINKADDR_STRING(cp, LINKADDR_OTHER, 8)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 367 | cp += 8; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 368 | len -= 8; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 369 | /* Destination Id */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 370 | ND_PRINT(", Destination Id %s", GET_LINKADDR_STRING(cp, LINKADDR_OTHER, 8)); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 371 | cp += 8; |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 372 | len -= 8; |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 373 | } |
| 374 | /* Body */ |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 375 | ahcp1_body_print(ndo, cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 376 | break; |
| 377 | } |
| 378 | default: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 379 | ND_PRINT(" Version %u (unknown)", version); |
| 380 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 381 | break; |
| 382 | } |
| 383 | return; |
| 384 | |
Elliott Hughes | e2e3bd1 | 2017-05-15 10:59:29 -0700 | [diff] [blame] | 385 | invalid: |
Elliott Hughes | 820eced | 2021-08-20 18:00:50 -0700 | [diff] [blame] | 386 | nd_print_invalid(ndo); |
| 387 | ND_TCHECK_LEN(cp, len); |
Elliott Hughes | 892a68b | 2015-10-19 14:43:53 -0700 | [diff] [blame] | 388 | } |