13c602fabSXin LI /* 23c602fabSXin LI * Copyright (c) 2013 The TCPDUMP project 33c602fabSXin LI * All rights reserved. 43c602fabSXin LI * 53c602fabSXin LI * Redistribution and use in source and binary forms, with or without 63c602fabSXin LI * modification, are permitted provided that the following conditions 73c602fabSXin LI * are met: 83c602fabSXin LI * 1. Redistributions of source code must retain the above copyright 93c602fabSXin LI * notice, this list of conditions and the following disclaimer. 103c602fabSXin LI * 2. Redistributions in binary form must reproduce the above copyright 113c602fabSXin LI * notice, this list of conditions and the following disclaimer in the 123c602fabSXin LI * documentation and/or other materials provided with the distribution. 133c602fabSXin LI * 143c602fabSXin LI * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 153c602fabSXin LI * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 163c602fabSXin LI * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 173c602fabSXin LI * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 183c602fabSXin LI * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 193c602fabSXin LI * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 203c602fabSXin LI * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 213c602fabSXin LI * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 223c602fabSXin LI * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 233c602fabSXin LI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 243c602fabSXin LI * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 253c602fabSXin LI * POSSIBILITY OF SUCH DAMAGE. 263c602fabSXin LI */ 273c602fabSXin LI 283340d773SGleb Smirnoff /* \summary: Ad Hoc Configuration Protocol (AHCP) printer */ 293340d773SGleb Smirnoff 303340d773SGleb Smirnoff /* Based on draft-chroboczek-ahcp-00 and source code of ahcpd-0.53 */ 313340d773SGleb Smirnoff 32*ee67461eSJoseph Mingrone #include <config.h> 333c602fabSXin LI 34*ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 353c602fabSXin LI 36*ee67461eSJoseph Mingrone #define ND_LONGJMP_FROM_TCHECK 373340d773SGleb Smirnoff #include "netdissect.h" 383c602fabSXin LI #include "extract.h" 393c602fabSXin LI #include "addrtoname.h" 403c602fabSXin LI 413c602fabSXin LI 423c602fabSXin LI #define AHCP_MAGIC_NUMBER 43 433c602fabSXin LI #define AHCP_VERSION_1 1 443c602fabSXin LI #define AHCP1_HEADER_FIX_LEN 24 453c602fabSXin LI #define AHCP1_BODY_MIN_LEN 4 463c602fabSXin LI 473c602fabSXin LI #define AHCP1_MSG_DISCOVER 0 483c602fabSXin LI #define AHCP1_MSG_OFFER 1 493c602fabSXin LI #define AHCP1_MSG_REQUEST 2 503c602fabSXin LI #define AHCP1_MSG_ACK 3 513c602fabSXin LI #define AHCP1_MSG_NACK 4 523c602fabSXin LI #define AHCP1_MSG_RELEASE 5 533c602fabSXin LI 543c602fabSXin LI static const struct tok ahcp1_msg_str[] = { 553c602fabSXin LI { AHCP1_MSG_DISCOVER, "Discover" }, 563c602fabSXin LI { AHCP1_MSG_OFFER, "Offer" }, 573c602fabSXin LI { AHCP1_MSG_REQUEST, "Request" }, 583c602fabSXin LI { AHCP1_MSG_ACK, "Ack" }, 593c602fabSXin LI { AHCP1_MSG_NACK, "Nack" }, 603c602fabSXin LI { AHCP1_MSG_RELEASE, "Release" }, 613c602fabSXin LI { 0, NULL } 623c602fabSXin LI }; 633c602fabSXin LI 643c602fabSXin LI #define AHCP1_OPT_PAD 0 653c602fabSXin LI #define AHCP1_OPT_MANDATORY 1 663c602fabSXin LI #define AHCP1_OPT_ORIGIN_TIME 2 673c602fabSXin LI #define AHCP1_OPT_EXPIRES 3 683c602fabSXin LI #define AHCP1_OPT_MY_IPV6_ADDRESS 4 693c602fabSXin LI #define AHCP1_OPT_MY_IPV4_ADDRESS 5 703c602fabSXin LI #define AHCP1_OPT_IPV6_PREFIX 6 713c602fabSXin LI #define AHCP1_OPT_IPV4_PREFIX 7 723c602fabSXin LI #define AHCP1_OPT_IPV6_ADDRESS 8 733c602fabSXin LI #define AHCP1_OPT_IPV4_ADDRESS 9 743c602fabSXin LI #define AHCP1_OPT_IPV6_PREFIX_DELEGATION 10 753c602fabSXin LI #define AHCP1_OPT_IPV4_PREFIX_DELEGATION 11 763c602fabSXin LI #define AHCP1_OPT_NAME_SERVER 12 773c602fabSXin LI #define AHCP1_OPT_NTP_SERVER 13 783c602fabSXin LI #define AHCP1_OPT_MAX 13 793c602fabSXin LI 803c602fabSXin LI static const struct tok ahcp1_opt_str[] = { 813c602fabSXin LI { AHCP1_OPT_PAD, "Pad" }, 823c602fabSXin LI { AHCP1_OPT_MANDATORY, "Mandatory" }, 833c602fabSXin LI { AHCP1_OPT_ORIGIN_TIME, "Origin Time" }, 843c602fabSXin LI { AHCP1_OPT_EXPIRES, "Expires" }, 853c602fabSXin LI { AHCP1_OPT_MY_IPV6_ADDRESS, "My-IPv6-Address" }, 863c602fabSXin LI { AHCP1_OPT_MY_IPV4_ADDRESS, "My-IPv4-Address" }, 873c602fabSXin LI { AHCP1_OPT_IPV6_PREFIX, "IPv6 Prefix" }, 883c602fabSXin LI { AHCP1_OPT_IPV4_PREFIX, "IPv4 Prefix" }, 893c602fabSXin LI { AHCP1_OPT_IPV6_ADDRESS, "IPv6 Address" }, 903c602fabSXin LI { AHCP1_OPT_IPV4_ADDRESS, "IPv4 Address" }, 913c602fabSXin LI { AHCP1_OPT_IPV6_PREFIX_DELEGATION, "IPv6 Prefix Delegation" }, 923c602fabSXin LI { AHCP1_OPT_IPV4_PREFIX_DELEGATION, "IPv4 Prefix Delegation" }, 933c602fabSXin LI { AHCP1_OPT_NAME_SERVER, "Name Server" }, 943c602fabSXin LI { AHCP1_OPT_NTP_SERVER, "NTP Server" }, 953c602fabSXin LI { 0, NULL } 963c602fabSXin LI }; 973c602fabSXin LI 98*ee67461eSJoseph Mingrone static void 99*ee67461eSJoseph Mingrone ahcp_time_print(netdissect_options *ndo, 100*ee67461eSJoseph Mingrone const u_char *cp, uint8_t len) 1018bdc5a62SPatrick Kelsey { 1023c602fabSXin LI time_t t; 103*ee67461eSJoseph Mingrone char buf[sizeof("-yyyyyyyyyy-mm-dd hh:mm:ss UTC")]; 1043c602fabSXin LI 105*ee67461eSJoseph Mingrone if (len != 4) 1063340d773SGleb Smirnoff goto invalid; 107*ee67461eSJoseph Mingrone t = GET_BE_U_4(cp); 108*ee67461eSJoseph Mingrone ND_PRINT(": %s", 109*ee67461eSJoseph Mingrone nd_format_time(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S UTC", 110*ee67461eSJoseph Mingrone gmtime(&t))); 111*ee67461eSJoseph Mingrone return; 1123c602fabSXin LI 1133340d773SGleb Smirnoff invalid: 114*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 115*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 1163c602fabSXin LI } 1173c602fabSXin LI 118*ee67461eSJoseph Mingrone static void 119*ee67461eSJoseph Mingrone ahcp_seconds_print(netdissect_options *ndo, 120*ee67461eSJoseph Mingrone const u_char *cp, uint8_t len) 1218bdc5a62SPatrick Kelsey { 122*ee67461eSJoseph Mingrone if (len != 4) 1233340d773SGleb Smirnoff goto invalid; 124*ee67461eSJoseph Mingrone ND_PRINT(": %us", GET_BE_U_4(cp)); 125*ee67461eSJoseph Mingrone return; 1263c602fabSXin LI 1273340d773SGleb Smirnoff invalid: 128*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 129*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 1303c602fabSXin LI } 1313c602fabSXin LI 132*ee67461eSJoseph Mingrone static void 133*ee67461eSJoseph Mingrone ahcp_ipv6_addresses_print(netdissect_options *ndo, 134*ee67461eSJoseph Mingrone const u_char *cp, uint8_t len) 1358bdc5a62SPatrick Kelsey { 1363c602fabSXin LI const char *sep = ": "; 1373c602fabSXin LI 138*ee67461eSJoseph Mingrone while (len) { 139*ee67461eSJoseph Mingrone if (len < 16) 1403340d773SGleb Smirnoff goto invalid; 141*ee67461eSJoseph Mingrone ND_PRINT("%s%s", sep, GET_IP6ADDR_STRING(cp)); 1423c602fabSXin LI cp += 16; 143*ee67461eSJoseph Mingrone len -= 16; 1443c602fabSXin LI sep = ", "; 1453c602fabSXin LI } 146*ee67461eSJoseph Mingrone return; 1473c602fabSXin LI 1483340d773SGleb Smirnoff invalid: 149*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 150*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 1513c602fabSXin LI } 1523c602fabSXin LI 153*ee67461eSJoseph Mingrone static void 154*ee67461eSJoseph Mingrone ahcp_ipv4_addresses_print(netdissect_options *ndo, 155*ee67461eSJoseph Mingrone const u_char *cp, uint8_t len) 1568bdc5a62SPatrick Kelsey { 1573c602fabSXin LI const char *sep = ": "; 1583c602fabSXin LI 159*ee67461eSJoseph Mingrone while (len) { 160*ee67461eSJoseph Mingrone if (len < 4) 1613340d773SGleb Smirnoff goto invalid; 162*ee67461eSJoseph Mingrone ND_PRINT("%s%s", sep, GET_IPADDR_STRING(cp)); 1633c602fabSXin LI cp += 4; 164*ee67461eSJoseph Mingrone len -= 4; 1653c602fabSXin LI sep = ", "; 1663c602fabSXin LI } 167*ee67461eSJoseph Mingrone return; 1683c602fabSXin LI 1693340d773SGleb Smirnoff invalid: 170*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 171*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 1723c602fabSXin LI } 1733c602fabSXin LI 174*ee67461eSJoseph Mingrone static void 175*ee67461eSJoseph Mingrone ahcp_ipv6_prefixes_print(netdissect_options *ndo, 176*ee67461eSJoseph Mingrone const u_char *cp, uint8_t len) 1778bdc5a62SPatrick Kelsey { 1783c602fabSXin LI const char *sep = ": "; 1793c602fabSXin LI 180*ee67461eSJoseph Mingrone while (len) { 181*ee67461eSJoseph Mingrone if (len < 17) 1823340d773SGleb Smirnoff goto invalid; 183*ee67461eSJoseph Mingrone ND_PRINT("%s%s/%u", sep, GET_IP6ADDR_STRING(cp), GET_U_1(cp + 16)); 1843c602fabSXin LI cp += 17; 185*ee67461eSJoseph Mingrone len -= 17; 1863c602fabSXin LI sep = ", "; 1873c602fabSXin LI } 188*ee67461eSJoseph Mingrone return; 1893c602fabSXin LI 1903340d773SGleb Smirnoff invalid: 191*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 192*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 1933c602fabSXin LI } 1943c602fabSXin LI 195*ee67461eSJoseph Mingrone static void 196*ee67461eSJoseph Mingrone ahcp_ipv4_prefixes_print(netdissect_options *ndo, 197*ee67461eSJoseph Mingrone const u_char *cp, uint8_t len) 1988bdc5a62SPatrick Kelsey { 1993c602fabSXin LI const char *sep = ": "; 2003c602fabSXin LI 201*ee67461eSJoseph Mingrone while (len) { 202*ee67461eSJoseph Mingrone if (len < 5) 2033340d773SGleb Smirnoff goto invalid; 204*ee67461eSJoseph Mingrone ND_PRINT("%s%s/%u", sep, GET_IPADDR_STRING(cp), GET_U_1(cp + 4)); 2053c602fabSXin LI cp += 5; 206*ee67461eSJoseph Mingrone len -= 5; 2073c602fabSXin LI sep = ", "; 2083c602fabSXin LI } 209*ee67461eSJoseph Mingrone return; 2103c602fabSXin LI 2113340d773SGleb Smirnoff invalid: 212*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 213*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 2143c602fabSXin LI } 2153c602fabSXin LI 216*ee67461eSJoseph Mingrone static void 217*ee67461eSJoseph Mingrone (* const data_decoders[AHCP1_OPT_MAX + 1])(netdissect_options *, const u_char *, uint8_t) = { 2183c602fabSXin LI /* [AHCP1_OPT_PAD] = */ NULL, 2193c602fabSXin LI /* [AHCP1_OPT_MANDATORY] = */ NULL, 2203c602fabSXin LI /* [AHCP1_OPT_ORIGIN_TIME] = */ ahcp_time_print, 2213c602fabSXin LI /* [AHCP1_OPT_EXPIRES] = */ ahcp_seconds_print, 2223c602fabSXin LI /* [AHCP1_OPT_MY_IPV6_ADDRESS] = */ ahcp_ipv6_addresses_print, 2233c602fabSXin LI /* [AHCP1_OPT_MY_IPV4_ADDRESS] = */ ahcp_ipv4_addresses_print, 2243c602fabSXin LI /* [AHCP1_OPT_IPV6_PREFIX] = */ ahcp_ipv6_prefixes_print, 2253c602fabSXin LI /* [AHCP1_OPT_IPV4_PREFIX] = */ NULL, 2263c602fabSXin LI /* [AHCP1_OPT_IPV6_ADDRESS] = */ ahcp_ipv6_addresses_print, 2273c602fabSXin LI /* [AHCP1_OPT_IPV4_ADDRESS] = */ ahcp_ipv4_addresses_print, 2283c602fabSXin LI /* [AHCP1_OPT_IPV6_PREFIX_DELEGATION] = */ ahcp_ipv6_prefixes_print, 2293c602fabSXin LI /* [AHCP1_OPT_IPV4_PREFIX_DELEGATION] = */ ahcp_ipv4_prefixes_print, 2303c602fabSXin LI /* [AHCP1_OPT_NAME_SERVER] = */ ahcp_ipv6_addresses_print, 2313c602fabSXin LI /* [AHCP1_OPT_NTP_SERVER] = */ ahcp_ipv6_addresses_print, 2323c602fabSXin LI }; 2333c602fabSXin LI 2343c602fabSXin LI static void 235*ee67461eSJoseph Mingrone ahcp1_options_print(netdissect_options *ndo, 236*ee67461eSJoseph Mingrone const u_char *cp, uint16_t len) 2378bdc5a62SPatrick Kelsey { 238*ee67461eSJoseph Mingrone while (len) { 2393c602fabSXin LI uint8_t option_no, option_len; 2403c602fabSXin LI 2413c602fabSXin LI /* Option no */ 242*ee67461eSJoseph Mingrone option_no = GET_U_1(cp); 2433c602fabSXin LI cp += 1; 244*ee67461eSJoseph Mingrone len -= 1; 245*ee67461eSJoseph Mingrone ND_PRINT("\n\t %s", tok2str(ahcp1_opt_str, "Unknown-%u", option_no)); 2463c602fabSXin LI if (option_no == AHCP1_OPT_PAD || option_no == AHCP1_OPT_MANDATORY) 2473c602fabSXin LI continue; 2483c602fabSXin LI /* Length */ 249*ee67461eSJoseph Mingrone if (!len) 2503340d773SGleb Smirnoff goto invalid; 251*ee67461eSJoseph Mingrone option_len = GET_U_1(cp); 2523c602fabSXin LI cp += 1; 253*ee67461eSJoseph Mingrone len -= 1; 254*ee67461eSJoseph Mingrone if (option_len > len) 2553340d773SGleb Smirnoff goto invalid; 2563c602fabSXin LI /* Value */ 2573c602fabSXin LI if (option_no <= AHCP1_OPT_MAX && data_decoders[option_no] != NULL) { 258*ee67461eSJoseph Mingrone data_decoders[option_no](ndo, cp, option_len); 2593c602fabSXin LI } else { 260*ee67461eSJoseph Mingrone ND_PRINT(" (Length %u)", option_len); 261*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, option_len); 2623c602fabSXin LI } 2633c602fabSXin LI cp += option_len; 264*ee67461eSJoseph Mingrone len -= option_len; 2653c602fabSXin LI } 2663c602fabSXin LI return; 2673c602fabSXin LI 2683340d773SGleb Smirnoff invalid: 269*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 270*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 2713c602fabSXin LI } 2723c602fabSXin LI 2733c602fabSXin LI static void 274*ee67461eSJoseph Mingrone ahcp1_body_print(netdissect_options *ndo, 275*ee67461eSJoseph Mingrone const u_char *cp, u_int len) 2768bdc5a62SPatrick Kelsey { 2773c602fabSXin LI uint8_t type, mbz; 2783c602fabSXin LI uint16_t body_len; 2793c602fabSXin LI 280*ee67461eSJoseph Mingrone if (len < AHCP1_BODY_MIN_LEN) 2813340d773SGleb Smirnoff goto invalid; 2823c602fabSXin LI /* Type */ 283*ee67461eSJoseph Mingrone type = GET_U_1(cp); 2843c602fabSXin LI cp += 1; 285*ee67461eSJoseph Mingrone len -= 1; 2863c602fabSXin LI /* MBZ */ 287*ee67461eSJoseph Mingrone mbz = GET_U_1(cp); 2883c602fabSXin LI cp += 1; 289*ee67461eSJoseph Mingrone len -= 1; 2903c602fabSXin LI /* Length */ 291*ee67461eSJoseph Mingrone body_len = GET_BE_U_2(cp); 2923c602fabSXin LI cp += 2; 293*ee67461eSJoseph Mingrone len -= 2; 2943c602fabSXin LI 2953c602fabSXin LI if (ndo->ndo_vflag) { 296*ee67461eSJoseph Mingrone ND_PRINT("\n\t%s", tok2str(ahcp1_msg_str, "Unknown-%u", type)); 2973c602fabSXin LI if (mbz != 0) 298*ee67461eSJoseph Mingrone ND_PRINT(", MBZ %u", mbz); 299*ee67461eSJoseph Mingrone ND_PRINT(", Length %u", body_len); 3003c602fabSXin LI } 301*ee67461eSJoseph Mingrone if (body_len > len) 3023340d773SGleb Smirnoff goto invalid; 3033c602fabSXin LI 3043c602fabSXin LI /* Options */ 305*ee67461eSJoseph Mingrone /* Here use "body_len", not "len" (ignore any extra data). */ 3063c602fabSXin LI if (ndo->ndo_vflag >= 2) 307*ee67461eSJoseph Mingrone ahcp1_options_print(ndo, cp, body_len); 3083c602fabSXin LI else 309*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, body_len); 3103c602fabSXin LI return; 3113c602fabSXin LI 3123340d773SGleb Smirnoff invalid: 313*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 314*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 315*ee67461eSJoseph Mingrone 3163c602fabSXin LI } 3173c602fabSXin LI 3183c602fabSXin LI void 319*ee67461eSJoseph Mingrone ahcp_print(netdissect_options *ndo, 320*ee67461eSJoseph Mingrone const u_char *cp, u_int len) 3218bdc5a62SPatrick Kelsey { 3223c602fabSXin LI uint8_t version; 3233c602fabSXin LI 324*ee67461eSJoseph Mingrone ndo->ndo_protocol = "ahcp"; 325*ee67461eSJoseph Mingrone nd_print_protocol_caps(ndo); 3263c602fabSXin LI if (len < 2) 3273340d773SGleb Smirnoff goto invalid; 3283c602fabSXin LI /* Magic */ 329*ee67461eSJoseph Mingrone if (GET_U_1(cp) != AHCP_MAGIC_NUMBER) 3303340d773SGleb Smirnoff goto invalid; 3313c602fabSXin LI cp += 1; 332*ee67461eSJoseph Mingrone len -= 1; 3333c602fabSXin LI /* Version */ 334*ee67461eSJoseph Mingrone version = GET_U_1(cp); 3353c602fabSXin LI cp += 1; 336*ee67461eSJoseph Mingrone len -= 1; 3373c602fabSXin LI switch (version) { 3383c602fabSXin LI case AHCP_VERSION_1: { 339*ee67461eSJoseph Mingrone ND_PRINT(" Version 1"); 340*ee67461eSJoseph Mingrone if (len < AHCP1_HEADER_FIX_LEN - 2) 3413340d773SGleb Smirnoff goto invalid; 3423c602fabSXin LI if (!ndo->ndo_vflag) { 343*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, AHCP1_HEADER_FIX_LEN - 2); 3443c602fabSXin LI cp += AHCP1_HEADER_FIX_LEN - 2; 345*ee67461eSJoseph Mingrone len -= AHCP1_HEADER_FIX_LEN - 2; 3463c602fabSXin LI } else { 3473c602fabSXin LI /* Hopcount */ 348*ee67461eSJoseph Mingrone ND_PRINT("\n\tHopcount %u", GET_U_1(cp)); 3493c602fabSXin LI cp += 1; 350*ee67461eSJoseph Mingrone len -= 1; 3513c602fabSXin LI /* Original Hopcount */ 352*ee67461eSJoseph Mingrone ND_PRINT(", Original Hopcount %u", GET_U_1(cp)); 3533c602fabSXin LI cp += 1; 354*ee67461eSJoseph Mingrone len -= 1; 3553c602fabSXin LI /* Nonce */ 356*ee67461eSJoseph Mingrone ND_PRINT(", Nonce 0x%08x", GET_BE_U_4(cp)); 3573c602fabSXin LI cp += 4; 358*ee67461eSJoseph Mingrone len -= 4; 3593c602fabSXin LI /* Source Id */ 360*ee67461eSJoseph Mingrone ND_PRINT(", Source Id %s", GET_LINKADDR_STRING(cp, LINKADDR_OTHER, 8)); 3613c602fabSXin LI cp += 8; 362*ee67461eSJoseph Mingrone len -= 8; 3633c602fabSXin LI /* Destination Id */ 364*ee67461eSJoseph Mingrone ND_PRINT(", Destination Id %s", GET_LINKADDR_STRING(cp, LINKADDR_OTHER, 8)); 3653c602fabSXin LI cp += 8; 366*ee67461eSJoseph Mingrone len -= 8; 3673c602fabSXin LI } 3683c602fabSXin LI /* Body */ 369*ee67461eSJoseph Mingrone ahcp1_body_print(ndo, cp, len); 3703c602fabSXin LI break; 3713c602fabSXin LI } 3723c602fabSXin LI default: 373*ee67461eSJoseph Mingrone ND_PRINT(" Version %u (unknown)", version); 374*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 3753c602fabSXin LI break; 3763c602fabSXin LI } 3773c602fabSXin LI return; 3783c602fabSXin LI 3793340d773SGleb Smirnoff invalid: 380*ee67461eSJoseph Mingrone nd_print_invalid(ndo); 381*ee67461eSJoseph Mingrone ND_TCHECK_LEN(cp, len); 3823c602fabSXin LI } 383