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
ahcp_time_print(netdissect_options * ndo,const u_char * cp,uint8_t len)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
ahcp_seconds_print(netdissect_options * ndo,const u_char * cp,uint8_t len)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
ahcp_ipv6_addresses_print(netdissect_options * ndo,const u_char * cp,uint8_t len)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
ahcp_ipv4_addresses_print(netdissect_options * ndo,const u_char * cp,uint8_t len)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
ahcp_ipv6_prefixes_print(netdissect_options * ndo,const u_char * cp,uint8_t len)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
ahcp_ipv4_prefixes_print(netdissect_options * ndo,const u_char * cp,uint8_t len)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
ahcp1_options_print(netdissect_options * ndo,const u_char * cp,uint16_t len)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
ahcp1_body_print(netdissect_options * ndo,const u_char * cp,u_int len)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
ahcp_print(netdissect_options * ndo,const u_char * cp,u_int len)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