13c602fabSXin LI /* 23c602fabSXin LI * This module implements decoding of AHCP (Ad Hoc Configuration Protocol) based 33c602fabSXin LI * on draft-chroboczek-ahcp-00 and source code of ahcpd-0.53. 43c602fabSXin LI * 53c602fabSXin LI * 63c602fabSXin LI * Copyright (c) 2013 The TCPDUMP project 73c602fabSXin LI * All rights reserved. 83c602fabSXin LI * 93c602fabSXin LI * Redistribution and use in source and binary forms, with or without 103c602fabSXin LI * modification, are permitted provided that the following conditions 113c602fabSXin LI * are met: 123c602fabSXin LI * 1. Redistributions of source code must retain the above copyright 133c602fabSXin LI * notice, this list of conditions and the following disclaimer. 143c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright 153c602fabSXin LI * notice, this list of conditions and the following disclaimer in the 163c602fabSXin LI * documentation and/or other materials provided with the distribution. 173c602fabSXin LI * 183c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 193c602fabSXin LI * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 203c602fabSXin LI * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 213c602fabSXin LI * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 223c602fabSXin LI * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 233c602fabSXin LI * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 243c602fabSXin LI * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 253c602fabSXin LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 263c602fabSXin LI * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 273c602fabSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 283c602fabSXin LI * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 293c602fabSXin LI * POSSIBILITY OF SUCH DAMAGE. 303c602fabSXin LI */ 313c602fabSXin LI 323c602fabSXin LI #define NETDISSECT_REWORKED 333c602fabSXin LI #ifdef HAVE_CONFIG_H 343c602fabSXin LI #include "config.h" 353c602fabSXin LI #endif 363c602fabSXin LI 373c602fabSXin LI #include <tcpdump-stdinc.h> 383c602fabSXin LI 393c602fabSXin LI #include "interface.h" 403c602fabSXin LI #include "extract.h" 413c602fabSXin LI #include "addrtoname.h" 423c602fabSXin LI 433c602fabSXin LI static const char tstr[] = " [|ahcp]"; 443c602fabSXin LI static const char cstr[] = "(corrupt)"; 453c602fabSXin LI 463c602fabSXin LI #define AHCP_MAGIC_NUMBER 43 473c602fabSXin LI #define AHCP_VERSION_1 1 483c602fabSXin LI #define AHCP1_HEADER_FIX_LEN 24 493c602fabSXin LI #define AHCP1_BODY_MIN_LEN 4 503c602fabSXin LI 513c602fabSXin LI #define AHCP1_MSG_DISCOVER 0 523c602fabSXin LI #define AHCP1_MSG_OFFER 1 533c602fabSXin LI #define AHCP1_MSG_REQUEST 2 543c602fabSXin LI #define AHCP1_MSG_ACK 3 553c602fabSXin LI #define AHCP1_MSG_NACK 4 563c602fabSXin LI #define AHCP1_MSG_RELEASE 5 573c602fabSXin LI 583c602fabSXin LI static const struct tok ahcp1_msg_str[] = { 593c602fabSXin LI { AHCP1_MSG_DISCOVER, "Discover" }, 603c602fabSXin LI { AHCP1_MSG_OFFER, "Offer" }, 613c602fabSXin LI { AHCP1_MSG_REQUEST, "Request" }, 623c602fabSXin LI { AHCP1_MSG_ACK, "Ack" }, 633c602fabSXin LI { AHCP1_MSG_NACK, "Nack" }, 643c602fabSXin LI { AHCP1_MSG_RELEASE, "Release" }, 653c602fabSXin LI { 0, NULL } 663c602fabSXin LI }; 673c602fabSXin LI 683c602fabSXin LI #define AHCP1_OPT_PAD 0 693c602fabSXin LI #define AHCP1_OPT_MANDATORY 1 703c602fabSXin LI #define AHCP1_OPT_ORIGIN_TIME 2 713c602fabSXin LI #define AHCP1_OPT_EXPIRES 3 723c602fabSXin LI #define AHCP1_OPT_MY_IPV6_ADDRESS 4 733c602fabSXin LI #define AHCP1_OPT_MY_IPV4_ADDRESS 5 743c602fabSXin LI #define AHCP1_OPT_IPV6_PREFIX 6 753c602fabSXin LI #define AHCP1_OPT_IPV4_PREFIX 7 763c602fabSXin LI #define AHCP1_OPT_IPV6_ADDRESS 8 773c602fabSXin LI #define AHCP1_OPT_IPV4_ADDRESS 9 783c602fabSXin LI #define AHCP1_OPT_IPV6_PREFIX_DELEGATION 10 793c602fabSXin LI #define AHCP1_OPT_IPV4_PREFIX_DELEGATION 11 803c602fabSXin LI #define AHCP1_OPT_NAME_SERVER 12 813c602fabSXin LI #define AHCP1_OPT_NTP_SERVER 13 823c602fabSXin LI #define AHCP1_OPT_MAX 13 833c602fabSXin LI 843c602fabSXin LI static const struct tok ahcp1_opt_str[] = { 853c602fabSXin LI { AHCP1_OPT_PAD, "Pad" }, 863c602fabSXin LI { AHCP1_OPT_MANDATORY, "Mandatory" }, 873c602fabSXin LI { AHCP1_OPT_ORIGIN_TIME, "Origin Time" }, 883c602fabSXin LI { AHCP1_OPT_EXPIRES, "Expires" }, 893c602fabSXin LI { AHCP1_OPT_MY_IPV6_ADDRESS, "My-IPv6-Address" }, 903c602fabSXin LI { AHCP1_OPT_MY_IPV4_ADDRESS, "My-IPv4-Address" }, 913c602fabSXin LI { AHCP1_OPT_IPV6_PREFIX, "IPv6 Prefix" }, 923c602fabSXin LI { AHCP1_OPT_IPV4_PREFIX, "IPv4 Prefix" }, 933c602fabSXin LI { AHCP1_OPT_IPV6_ADDRESS, "IPv6 Address" }, 943c602fabSXin LI { AHCP1_OPT_IPV4_ADDRESS, "IPv4 Address" }, 953c602fabSXin LI { AHCP1_OPT_IPV6_PREFIX_DELEGATION, "IPv6 Prefix Delegation" }, 963c602fabSXin LI { AHCP1_OPT_IPV4_PREFIX_DELEGATION, "IPv4 Prefix Delegation" }, 973c602fabSXin LI { AHCP1_OPT_NAME_SERVER, "Name Server" }, 983c602fabSXin LI { AHCP1_OPT_NTP_SERVER, "NTP Server" }, 993c602fabSXin LI { 0, NULL } 1003c602fabSXin LI }; 1013c602fabSXin LI 1023c602fabSXin LI static int 103*8bdc5a62SPatrick Kelsey ahcp_time_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 104*8bdc5a62SPatrick Kelsey { 1053c602fabSXin LI time_t t; 1063c602fabSXin LI struct tm *tm; 1073c602fabSXin LI char buf[BUFSIZE]; 1083c602fabSXin LI 1093c602fabSXin LI if (cp + 4 != ep) 1103c602fabSXin LI goto corrupt; 1113c602fabSXin LI ND_TCHECK2(*cp, 4); 1123c602fabSXin LI t = EXTRACT_32BITS(cp); 1133c602fabSXin LI if (NULL == (tm = gmtime(&t))) 1143c602fabSXin LI ND_PRINT((ndo, ": gmtime() error")); 1153c602fabSXin LI else if (0 == strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm)) 1163c602fabSXin LI ND_PRINT((ndo, ": strftime() error")); 1173c602fabSXin LI else 1183c602fabSXin LI ND_PRINT((ndo, ": %s UTC", buf)); 1193c602fabSXin LI return 0; 1203c602fabSXin LI 1213c602fabSXin LI corrupt: 1223c602fabSXin LI ND_PRINT((ndo, ": %s", cstr)); 1233c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 1243c602fabSXin LI return 0; 1253c602fabSXin LI trunc: 1263c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 1273c602fabSXin LI return -1; 1283c602fabSXin LI } 1293c602fabSXin LI 1303c602fabSXin LI static int 131*8bdc5a62SPatrick Kelsey ahcp_seconds_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 132*8bdc5a62SPatrick Kelsey { 1333c602fabSXin LI if (cp + 4 != ep) 1343c602fabSXin LI goto corrupt; 1353c602fabSXin LI ND_TCHECK2(*cp, 4); 1363c602fabSXin LI ND_PRINT((ndo, ": %us", EXTRACT_32BITS(cp))); 1373c602fabSXin LI return 0; 1383c602fabSXin LI 1393c602fabSXin LI corrupt: 1403c602fabSXin LI ND_PRINT((ndo, ": %s", cstr)); 1413c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 1423c602fabSXin LI return 0; 1433c602fabSXin LI trunc: 1443c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 1453c602fabSXin LI return -1; 1463c602fabSXin LI } 1473c602fabSXin LI 1483c602fabSXin LI static int 149*8bdc5a62SPatrick Kelsey ahcp_ipv6_addresses_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 150*8bdc5a62SPatrick Kelsey { 1513c602fabSXin LI const char *sep = ": "; 1523c602fabSXin LI 1533c602fabSXin LI while (cp < ep) { 1543c602fabSXin LI if (cp + 16 > ep) 1553c602fabSXin LI goto corrupt; 1563c602fabSXin LI ND_TCHECK2(*cp, 16); 1573c602fabSXin LI #ifdef INET6 1583c602fabSXin LI ND_PRINT((ndo, "%s%s", sep, ip6addr_string(ndo, cp))); 1593c602fabSXin LI #else 1603c602fabSXin LI ND_PRINT((ndo, "%s(compiled w/o IPv6)", sep)); 1613c602fabSXin LI #endif /* INET6 */ 1623c602fabSXin LI cp += 16; 1633c602fabSXin LI sep = ", "; 1643c602fabSXin LI } 1653c602fabSXin LI return 0; 1663c602fabSXin LI 1673c602fabSXin LI corrupt: 1683c602fabSXin LI ND_PRINT((ndo, ": %s", cstr)); 1693c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 1703c602fabSXin LI return 0; 1713c602fabSXin LI trunc: 1723c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 1733c602fabSXin LI return -1; 1743c602fabSXin LI } 1753c602fabSXin LI 1763c602fabSXin LI static int 177*8bdc5a62SPatrick Kelsey ahcp_ipv4_addresses_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 178*8bdc5a62SPatrick Kelsey { 1793c602fabSXin LI const char *sep = ": "; 1803c602fabSXin LI 1813c602fabSXin LI while (cp < ep) { 1823c602fabSXin LI if (cp + 4 > ep) 1833c602fabSXin LI goto corrupt; 1843c602fabSXin LI ND_TCHECK2(*cp, 4); 1853c602fabSXin LI ND_PRINT((ndo, "%s%s", sep, ipaddr_string(ndo, cp))); 1863c602fabSXin LI cp += 4; 1873c602fabSXin LI sep = ", "; 1883c602fabSXin LI } 1893c602fabSXin LI return 0; 1903c602fabSXin LI 1913c602fabSXin LI corrupt: 1923c602fabSXin LI ND_PRINT((ndo, ": %s", cstr)); 1933c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 1943c602fabSXin LI return 0; 1953c602fabSXin LI trunc: 1963c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 1973c602fabSXin LI return -1; 1983c602fabSXin LI } 1993c602fabSXin LI 2003c602fabSXin LI static int 201*8bdc5a62SPatrick Kelsey ahcp_ipv6_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 202*8bdc5a62SPatrick Kelsey { 2033c602fabSXin LI const char *sep = ": "; 2043c602fabSXin LI 2053c602fabSXin LI while (cp < ep) { 2063c602fabSXin LI if (cp + 17 > ep) 2073c602fabSXin LI goto corrupt; 2083c602fabSXin LI ND_TCHECK2(*cp, 17); 2093c602fabSXin LI #ifdef INET6 2103c602fabSXin LI ND_PRINT((ndo, "%s%s/%u", sep, ip6addr_string(ndo, cp), *(cp + 16))); 2113c602fabSXin LI #else 2123c602fabSXin LI ND_PRINT((ndo, "%s(compiled w/o IPv6)/%u", sep, *(cp + 16))); 2133c602fabSXin LI #endif /* INET6 */ 2143c602fabSXin LI cp += 17; 2153c602fabSXin LI sep = ", "; 2163c602fabSXin LI } 2173c602fabSXin LI return 0; 2183c602fabSXin LI 2193c602fabSXin LI corrupt: 2203c602fabSXin LI ND_PRINT((ndo, ": %s", cstr)); 2213c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 2223c602fabSXin LI return 0; 2233c602fabSXin LI trunc: 2243c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 2253c602fabSXin LI return -1; 2263c602fabSXin LI } 2273c602fabSXin LI 2283c602fabSXin LI static int 229*8bdc5a62SPatrick Kelsey ahcp_ipv4_prefixes_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 230*8bdc5a62SPatrick Kelsey { 2313c602fabSXin LI const char *sep = ": "; 2323c602fabSXin LI 2333c602fabSXin LI while (cp < ep) { 2343c602fabSXin LI if (cp + 5 > ep) 2353c602fabSXin LI goto corrupt; 2363c602fabSXin LI ND_TCHECK2(*cp, 5); 2373c602fabSXin LI ND_PRINT((ndo, "%s%s/%u", sep, ipaddr_string(ndo, cp), *(cp + 4))); 2383c602fabSXin LI cp += 5; 2393c602fabSXin LI sep = ", "; 2403c602fabSXin LI } 2413c602fabSXin LI return 0; 2423c602fabSXin LI 2433c602fabSXin LI corrupt: 2443c602fabSXin LI ND_PRINT((ndo, ": %s", cstr)); 2453c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 2463c602fabSXin LI return 0; 2473c602fabSXin LI trunc: 2483c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 2493c602fabSXin LI return -1; 2503c602fabSXin LI } 2513c602fabSXin LI 2523c602fabSXin LI /* Data decoders signal truncated data with -1. */ 2533c602fabSXin LI static int 2543c602fabSXin LI (* const data_decoders[AHCP1_OPT_MAX + 1])(netdissect_options *, const u_char *, const u_char *) = { 2553c602fabSXin LI /* [AHCP1_OPT_PAD] = */ NULL, 2563c602fabSXin LI /* [AHCP1_OPT_MANDATORY] = */ NULL, 2573c602fabSXin LI /* [AHCP1_OPT_ORIGIN_TIME] = */ ahcp_time_print, 2583c602fabSXin LI /* [AHCP1_OPT_EXPIRES] = */ ahcp_seconds_print, 2593c602fabSXin LI /* [AHCP1_OPT_MY_IPV6_ADDRESS] = */ ahcp_ipv6_addresses_print, 2603c602fabSXin LI /* [AHCP1_OPT_MY_IPV4_ADDRESS] = */ ahcp_ipv4_addresses_print, 2613c602fabSXin LI /* [AHCP1_OPT_IPV6_PREFIX] = */ ahcp_ipv6_prefixes_print, 2623c602fabSXin LI /* [AHCP1_OPT_IPV4_PREFIX] = */ NULL, 2633c602fabSXin LI /* [AHCP1_OPT_IPV6_ADDRESS] = */ ahcp_ipv6_addresses_print, 2643c602fabSXin LI /* [AHCP1_OPT_IPV4_ADDRESS] = */ ahcp_ipv4_addresses_print, 2653c602fabSXin LI /* [AHCP1_OPT_IPV6_PREFIX_DELEGATION] = */ ahcp_ipv6_prefixes_print, 2663c602fabSXin LI /* [AHCP1_OPT_IPV4_PREFIX_DELEGATION] = */ ahcp_ipv4_prefixes_print, 2673c602fabSXin LI /* [AHCP1_OPT_NAME_SERVER] = */ ahcp_ipv6_addresses_print, 2683c602fabSXin LI /* [AHCP1_OPT_NTP_SERVER] = */ ahcp_ipv6_addresses_print, 2693c602fabSXin LI }; 2703c602fabSXin LI 2713c602fabSXin LI static void 272*8bdc5a62SPatrick Kelsey ahcp1_options_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 273*8bdc5a62SPatrick Kelsey { 2743c602fabSXin LI uint8_t option_no, option_len; 2753c602fabSXin LI 2763c602fabSXin LI while (cp < ep) { 2773c602fabSXin LI /* Option no */ 2783c602fabSXin LI ND_TCHECK2(*cp, 1); 2793c602fabSXin LI option_no = *cp; 2803c602fabSXin LI cp += 1; 2813c602fabSXin LI ND_PRINT((ndo, "\n\t %s", tok2str(ahcp1_opt_str, "Unknown-%u", option_no))); 2823c602fabSXin LI if (option_no == AHCP1_OPT_PAD || option_no == AHCP1_OPT_MANDATORY) 2833c602fabSXin LI continue; 2843c602fabSXin LI /* Length */ 2853c602fabSXin LI if (cp + 1 > ep) 2863c602fabSXin LI goto corrupt; 2873c602fabSXin LI ND_TCHECK2(*cp, 1); 2883c602fabSXin LI option_len = *cp; 2893c602fabSXin LI cp += 1; 2903c602fabSXin LI if (cp + option_len > ep) 2913c602fabSXin LI goto corrupt; 2923c602fabSXin LI /* Value */ 2933c602fabSXin LI if (option_no <= AHCP1_OPT_MAX && data_decoders[option_no] != NULL) { 2943c602fabSXin LI if (data_decoders[option_no](ndo, cp, cp + option_len) < 0) 2953c602fabSXin LI break; /* truncated and already marked up */ 2963c602fabSXin LI } else { 2973c602fabSXin LI ND_PRINT((ndo, " (Length %u)", option_len)); 2983c602fabSXin LI ND_TCHECK2(*cp, option_len); 2993c602fabSXin LI } 3003c602fabSXin LI cp += option_len; 3013c602fabSXin LI } 3023c602fabSXin LI return; 3033c602fabSXin LI 3043c602fabSXin LI corrupt: 3053c602fabSXin LI ND_PRINT((ndo, " %s", cstr)); 3063c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 3073c602fabSXin LI return; 3083c602fabSXin LI trunc: 3093c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 3103c602fabSXin LI } 3113c602fabSXin LI 3123c602fabSXin LI static void 313*8bdc5a62SPatrick Kelsey ahcp1_body_print(netdissect_options *ndo, const u_char *cp, const u_char *ep) 314*8bdc5a62SPatrick Kelsey { 3153c602fabSXin LI uint8_t type, mbz; 3163c602fabSXin LI uint16_t body_len; 3173c602fabSXin LI 3183c602fabSXin LI if (cp + AHCP1_BODY_MIN_LEN > ep) 3193c602fabSXin LI goto corrupt; 3203c602fabSXin LI /* Type */ 3213c602fabSXin LI ND_TCHECK2(*cp, 1); 3223c602fabSXin LI type = *cp; 3233c602fabSXin LI cp += 1; 3243c602fabSXin LI /* MBZ */ 3253c602fabSXin LI ND_TCHECK2(*cp, 1); 3263c602fabSXin LI mbz = *cp; 3273c602fabSXin LI cp += 1; 3283c602fabSXin LI /* Length */ 3293c602fabSXin LI ND_TCHECK2(*cp, 2); 3303c602fabSXin LI body_len = EXTRACT_16BITS(cp); 3313c602fabSXin LI cp += 2; 3323c602fabSXin LI 3333c602fabSXin LI if (ndo->ndo_vflag) { 3343c602fabSXin LI ND_PRINT((ndo, "\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type))); 3353c602fabSXin LI if (mbz != 0) 3363c602fabSXin LI ND_PRINT((ndo, ", MBZ %u", mbz)); 3373c602fabSXin LI ND_PRINT((ndo, ", Length %u", body_len)); 3383c602fabSXin LI } 3393c602fabSXin LI if (cp + body_len > ep) 3403c602fabSXin LI goto corrupt; 3413c602fabSXin LI 3423c602fabSXin LI /* Options */ 3433c602fabSXin LI if (ndo->ndo_vflag >= 2) 3443c602fabSXin LI ahcp1_options_print(ndo, cp, cp + body_len); /* not ep (ignore extra data) */ 3453c602fabSXin LI else 3463c602fabSXin LI ND_TCHECK2(*cp, body_len); 3473c602fabSXin LI return; 3483c602fabSXin LI 3493c602fabSXin LI corrupt: 3503c602fabSXin LI ND_PRINT((ndo, " %s", cstr)); 3513c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 3523c602fabSXin LI return; 3533c602fabSXin LI trunc: 3543c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 3553c602fabSXin LI } 3563c602fabSXin LI 3573c602fabSXin LI void 358*8bdc5a62SPatrick Kelsey ahcp_print(netdissect_options *ndo, const u_char *cp, const u_int len) 359*8bdc5a62SPatrick Kelsey { 3603c602fabSXin LI const u_char *ep = cp + len; 3613c602fabSXin LI uint8_t version; 3623c602fabSXin LI 3633c602fabSXin LI ND_PRINT((ndo, "AHCP")); 3643c602fabSXin LI if (len < 2) 3653c602fabSXin LI goto corrupt; 3663c602fabSXin LI /* Magic */ 3673c602fabSXin LI ND_TCHECK2(*cp, 1); 3683c602fabSXin LI if (*cp != AHCP_MAGIC_NUMBER) 3693c602fabSXin LI goto corrupt; 3703c602fabSXin LI cp += 1; 3713c602fabSXin LI /* Version */ 3723c602fabSXin LI ND_TCHECK2(*cp, 1); 3733c602fabSXin LI version = *cp; 3743c602fabSXin LI cp += 1; 3753c602fabSXin LI switch (version) { 3763c602fabSXin LI case AHCP_VERSION_1: { 3773c602fabSXin LI ND_PRINT((ndo, " Version 1")); 3783c602fabSXin LI if (len < AHCP1_HEADER_FIX_LEN) 3793c602fabSXin LI goto corrupt; 3803c602fabSXin LI if (!ndo->ndo_vflag) { 3813c602fabSXin LI ND_TCHECK2(*cp, AHCP1_HEADER_FIX_LEN - 2); 3823c602fabSXin LI cp += AHCP1_HEADER_FIX_LEN - 2; 3833c602fabSXin LI } else { 3843c602fabSXin LI /* Hopcount */ 3853c602fabSXin LI ND_TCHECK2(*cp, 1); 3863c602fabSXin LI ND_PRINT((ndo, "\n\tHopcount %u", *cp)); 3873c602fabSXin LI cp += 1; 3883c602fabSXin LI /* Original Hopcount */ 3893c602fabSXin LI ND_TCHECK2(*cp, 1); 3903c602fabSXin LI ND_PRINT((ndo, ", Original Hopcount %u", *cp)); 3913c602fabSXin LI cp += 1; 3923c602fabSXin LI /* Nonce */ 3933c602fabSXin LI ND_TCHECK2(*cp, 4); 3943c602fabSXin LI ND_PRINT((ndo, ", Nonce 0x%08x", EXTRACT_32BITS(cp))); 3953c602fabSXin LI cp += 4; 3963c602fabSXin LI /* Source Id */ 3973c602fabSXin LI ND_TCHECK2(*cp, 8); 3983c602fabSXin LI ND_PRINT((ndo, ", Source Id %s", linkaddr_string(ndo, cp, 0, 8))); 3993c602fabSXin LI cp += 8; 4003c602fabSXin LI /* Destination Id */ 4013c602fabSXin LI ND_TCHECK2(*cp, 8); 4023c602fabSXin LI ND_PRINT((ndo, ", Destination Id %s", linkaddr_string(ndo, cp, 0, 8))); 4033c602fabSXin LI cp += 8; 4043c602fabSXin LI } 4053c602fabSXin LI /* Body */ 4063c602fabSXin LI ahcp1_body_print(ndo, cp, ep); 4073c602fabSXin LI break; 4083c602fabSXin LI } 4093c602fabSXin LI default: 4103c602fabSXin LI ND_PRINT((ndo, " Version %u (unknown)", version)); 4113c602fabSXin LI break; 4123c602fabSXin LI } 4133c602fabSXin LI return; 4143c602fabSXin LI 4153c602fabSXin LI corrupt: 4163c602fabSXin LI ND_PRINT((ndo, " %s", cstr)); 4173c602fabSXin LI ND_TCHECK2(*cp, ep - cp); 4183c602fabSXin LI return; 4193c602fabSXin LI trunc: 4203c602fabSXin LI ND_PRINT((ndo, "%s", tstr)); 4213c602fabSXin LI } 422