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