xref: /netbsd-src/external/bsd/tcpdump/dist/print-isakmp.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*
2  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE 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  * 3. Neither the name of the project nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  */
30 
31 #include <sys/cdefs.h>
32 #ifndef lint
33 #if 0
34 static const char rcsid[] _U_ =
35     "@(#) Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp  (LBL)";
36 #else
37 __RCSID("$NetBSD: print-isakmp.c,v 1.6 2013/12/31 17:33:31 christos Exp $");
38 #endif
39 #endif
40 
41 #define NETDISSECT_REWORKED
42 #ifdef HAVE_CONFIG_H
43 #include "config.h"
44 #endif
45 
46 /* The functions from print-esp.c used in this file are only defined when both
47  * OpenSSL and evp.h are detected. Employ the same preprocessor device here.
48  */
49 #ifndef HAVE_OPENSSL_EVP_H
50 #undef HAVE_LIBCRYPTO
51 #endif
52 
53 #include <tcpdump-stdinc.h>
54 
55 #include <string.h>
56 
57 #include <stdio.h>
58 
59 #include "isakmp.h"
60 #include "ipsec_doi.h"
61 #include "oakley.h"
62 #include "interface.h"
63 #include "addrtoname.h"
64 #include "extract.h"                    /* must come after interface.h */
65 
66 #include "ip.h"
67 #ifdef INET6
68 #include "ip6.h"
69 #endif
70 
71 #ifndef HAVE_SOCKADDR_STORAGE
72 #define sockaddr_storage sockaddr
73 #endif
74 
75 #define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \
76 		netdissect_options *ndo, u_char tpay,	              \
77 		const struct isakmp_gen *ext,			      \
78 		u_int item_len, \
79 		const u_char *end_pointer, \
80 		u_int32_t phase,\
81 		u_int32_t doi0, \
82 		u_int32_t proto0, int depth)
83 
84 DECLARE_PRINTER(v1_sa);
85 DECLARE_PRINTER(v1_p);
86 DECLARE_PRINTER(v1_t);
87 DECLARE_PRINTER(v1_ke);
88 DECLARE_PRINTER(v1_id);
89 DECLARE_PRINTER(v1_cert);
90 DECLARE_PRINTER(v1_cr);
91 DECLARE_PRINTER(v1_sig);
92 DECLARE_PRINTER(v1_hash);
93 DECLARE_PRINTER(v1_nonce);
94 DECLARE_PRINTER(v1_n);
95 DECLARE_PRINTER(v1_d);
96 DECLARE_PRINTER(v1_vid);
97 
98 DECLARE_PRINTER(v2_sa);
99 DECLARE_PRINTER(v2_ke);
100 DECLARE_PRINTER(v2_ID);
101 DECLARE_PRINTER(v2_cert);
102 DECLARE_PRINTER(v2_cr);
103 DECLARE_PRINTER(v2_auth);
104 DECLARE_PRINTER(v2_nonce);
105 DECLARE_PRINTER(v2_n);
106 DECLARE_PRINTER(v2_d);
107 DECLARE_PRINTER(v2_vid);
108 DECLARE_PRINTER(v2_TS);
109 DECLARE_PRINTER(v2_cp);
110 DECLARE_PRINTER(v2_eap);
111 
112 static const u_char *ikev2_e_print(netdissect_options *ndo,
113 				   struct isakmp *base,
114 				   u_char tpay,
115 				   const struct isakmp_gen *ext,
116 				   u_int item_len,
117 				   const u_char *end_pointer,
118 				   u_int32_t phase,
119 				   u_int32_t doi0,
120 				   u_int32_t proto0, int depth);
121 
122 
123 static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
124 	const u_char *,	u_int32_t, u_int32_t, u_int32_t, int);
125 static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
126 	const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
127 
128 static const u_char *ikev2_sub_print(netdissect_options *ndo,
129 				     struct isakmp *base,
130 				     u_char np, const struct isakmp_gen *ext,
131 				     const u_char *ep, u_int32_t phase,
132 				     u_int32_t doi, u_int32_t proto,
133 				     int depth);
134 
135 
136 static char *numstr(int);
137 static void safememcpy(void *, const void *, size_t);
138 
139 static void
140 ikev1_print(netdissect_options *ndo,
141 	    const u_char *bp,  u_int length,
142 	    const u_char *bp2, struct isakmp *base);
143 
144 #define MAXINITIATORS	20
145 int ninitiator = 0;
146 struct {
147 	cookie_t initiator;
148 	struct sockaddr_storage iaddr;
149 	struct sockaddr_storage raddr;
150 } cookiecache[MAXINITIATORS];
151 
152 /* protocol id */
153 static const char *protoidstr[] = {
154 	NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
155 };
156 
157 /* isakmp->np */
158 static const char *npstr[] = {
159 	"none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */
160 	"sig", "nonce", "n", "d", "vid",      /* 9 - 13 */
161 	"pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */
162 	"pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */
163 	"pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */
164 	"pay29", "pay30", "pay31", "pay32",          /* 29- 32 */
165 	"v2sa",  "v2ke",  "v2IDi", "v2IDr", "v2cert",/* 33- 37 */
166 	"v2cr",  "v2auth","v2nonce", "v2n",   "v2d",   /* 38- 42 */
167 	"v2vid", "v2TSi", "v2TSr", "v2e",   "v2cp",  /* 43- 47 */
168 	"v2eap",                                     /* 48 */
169 
170 };
171 
172 /* isakmp->np */
173 static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
174 				 const struct isakmp_gen *ext,
175 				 u_int item_len,
176 				 const u_char *end_pointer,
177 				 u_int32_t phase,
178 				 u_int32_t doi0,
179 				 u_int32_t proto0, int depth) = {
180 	NULL,
181 	ikev1_sa_print,
182 	ikev1_p_print,
183 	ikev1_t_print,
184 	ikev1_ke_print,
185 	ikev1_id_print,
186 	ikev1_cert_print,
187 	ikev1_cr_print,
188 	ikev1_hash_print,
189 	ikev1_sig_print,
190 	ikev1_nonce_print,
191 	ikev1_n_print,
192 	ikev1_d_print,
193 	ikev1_vid_print,                  /* 13 */
194 	NULL, NULL, NULL, NULL, NULL,     /* 14- 18 */
195 	NULL, NULL, NULL, NULL, NULL,     /* 19- 23 */
196 	NULL, NULL, NULL, NULL, NULL,     /* 24- 28 */
197 	NULL, NULL, NULL, NULL,           /* 29- 32 */
198 	ikev2_sa_print,                 /* 33 */
199 	ikev2_ke_print,                 /* 34 */
200 	ikev2_ID_print,                 /* 35 */
201 	ikev2_ID_print,                 /* 36 */
202 	ikev2_cert_print,               /* 37 */
203 	ikev2_cr_print,                 /* 38 */
204 	ikev2_auth_print,               /* 39 */
205 	ikev2_nonce_print,              /* 40 */
206 	ikev2_n_print,                  /* 41 */
207 	ikev2_d_print,                  /* 42 */
208 	ikev2_vid_print,                /* 43 */
209 	ikev2_TS_print,                 /* 44 */
210 	ikev2_TS_print,                 /* 45 */
211 	NULL, /* ikev2_e_print,*/       /* 46 - special */
212 	ikev2_cp_print,                 /* 47 */
213 	ikev2_eap_print,                /* 48 */
214 };
215 
216 /* isakmp->etype */
217 static const char *etypestr[] = {
218 /* IKEv1 exchange types */
219 	"none", "base", "ident", "auth", "agg", "inf", NULL, NULL,  /* 0-7 */
220 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /*  8-15 */
221 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 16-23 */
222 	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 24-31 */
223 	"oakley-quick", "oakley-newgroup",               /* 32-33 */
224 /* IKEv2 exchange types */
225 	"ikev2_init", "ikev2_auth", "child_sa", "inf2"   /* 34-37 */
226 };
227 
228 #define STR_OR_ID(x, tab) \
229 	(((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)])	? tab[(x)] : numstr(x))
230 #define PROTOIDSTR(x)	STR_OR_ID(x, protoidstr)
231 #define NPSTR(x)	STR_OR_ID(x, npstr)
232 #define ETYPESTR(x)	STR_OR_ID(x, etypestr)
233 
234 #define CHECKLEN(p, np)							\
235 		if (ep < (u_char *)(p)) {				\
236 			ND_PRINT((ndo," [|%s]", NPSTR(np)));		\
237 			goto done;					\
238 		}
239 
240 
241 #define NPFUNC(x) \
242 	(((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
243 		? npfunc[(x)] : NULL)
244 
245 static int
246 iszero(u_char *p, size_t l)
247 {
248 	while (l--) {
249 		if (*p++)
250 			return 0;
251 	}
252 	return 1;
253 }
254 
255 /* find cookie from initiator cache */
256 static int
257 cookie_find(cookie_t *in)
258 {
259 	int i;
260 
261 	for (i = 0; i < MAXINITIATORS; i++) {
262 		if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
263 			return i;
264 	}
265 
266 	return -1;
267 }
268 
269 /* record initiator */
270 static void
271 cookie_record(cookie_t *in, const u_char *bp2)
272 {
273 	int i;
274 	struct ip *ip;
275 	struct sockaddr_in *sin;
276 #ifdef INET6
277 	struct ip6_hdr *ip6;
278 	struct sockaddr_in6 *sin6;
279 #endif
280 
281 	i = cookie_find(in);
282 	if (0 <= i) {
283 		ninitiator = (i + 1) % MAXINITIATORS;
284 		return;
285 	}
286 
287 	ip = (struct ip *)bp2;
288 	switch (IP_V(ip)) {
289 	case 4:
290 		memset(&cookiecache[ninitiator].iaddr, 0,
291 			sizeof(cookiecache[ninitiator].iaddr));
292 		memset(&cookiecache[ninitiator].raddr, 0,
293 			sizeof(cookiecache[ninitiator].raddr));
294 
295 		sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
296 #ifdef HAVE_SOCKADDR_SA_LEN
297 		sin->sin_len = sizeof(struct sockaddr_in);
298 #endif
299 		sin->sin_family = AF_INET;
300 		memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
301 		sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
302 #ifdef HAVE_SOCKADDR_SA_LEN
303 		sin->sin_len = sizeof(struct sockaddr_in);
304 #endif
305 		sin->sin_family = AF_INET;
306 		memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
307 		break;
308 #ifdef INET6
309 	case 6:
310 		memset(&cookiecache[ninitiator].iaddr, 0,
311 			sizeof(cookiecache[ninitiator].iaddr));
312 		memset(&cookiecache[ninitiator].raddr, 0,
313 			sizeof(cookiecache[ninitiator].raddr));
314 
315 		ip6 = (struct ip6_hdr *)bp2;
316 		sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;
317 #ifdef HAVE_SOCKADDR_SA_LEN
318 		sin6->sin6_len = sizeof(struct sockaddr_in6);
319 #endif
320 		sin6->sin6_family = AF_INET6;
321 		memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
322 		sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
323 #ifdef HAVE_SOCKADDR_SA_LEN
324 		sin6->sin6_len = sizeof(struct sockaddr_in6);
325 #endif
326 		sin6->sin6_family = AF_INET6;
327 		memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
328 		break;
329 #endif
330 	default:
331 		return;
332 	}
333 	memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
334 	ninitiator = (ninitiator + 1) % MAXINITIATORS;
335 }
336 
337 #define cookie_isinitiator(x, y)	cookie_sidecheck((x), (y), 1)
338 #define cookie_isresponder(x, y)	cookie_sidecheck((x), (y), 0)
339 static int
340 cookie_sidecheck(int i, const u_char *bp2, int initiator)
341 {
342 	struct sockaddr_storage ss;
343 	struct sockaddr *sa;
344 	struct ip *ip;
345 	struct sockaddr_in *sin;
346 #ifdef INET6
347 	struct ip6_hdr *ip6;
348 	struct sockaddr_in6 *sin6;
349 #endif
350 	int salen;
351 
352 	memset(&ss, 0, sizeof(ss));
353 	ip = (struct ip *)bp2;
354 	switch (IP_V(ip)) {
355 	case 4:
356 		sin = (struct sockaddr_in *)&ss;
357 #ifdef HAVE_SOCKADDR_SA_LEN
358 		sin->sin_len = sizeof(struct sockaddr_in);
359 #endif
360 		sin->sin_family = AF_INET;
361 		memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
362 		break;
363 #ifdef INET6
364 	case 6:
365 		ip6 = (struct ip6_hdr *)bp2;
366 		sin6 = (struct sockaddr_in6 *)&ss;
367 #ifdef HAVE_SOCKADDR_SA_LEN
368 		sin6->sin6_len = sizeof(struct sockaddr_in6);
369 #endif
370 		sin6->sin6_family = AF_INET6;
371 		memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
372 		break;
373 #endif
374 	default:
375 		return 0;
376 	}
377 
378 	sa = (struct sockaddr *)&ss;
379 	if (initiator) {
380 		if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
381 			return 0;
382 #ifdef HAVE_SOCKADDR_SA_LEN
383 		salen = sa->sa_len;
384 #else
385 #ifdef INET6
386 		if (sa->sa_family == AF_INET6)
387 			salen = sizeof(struct sockaddr_in6);
388 		else
389 			salen = sizeof(struct sockaddr);
390 #else
391 		salen = sizeof(struct sockaddr);
392 #endif
393 #endif
394 		if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
395 			return 1;
396 	} else {
397 		if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
398 			return 0;
399 #ifdef HAVE_SOCKADDR_SA_LEN
400 		salen = sa->sa_len;
401 #else
402 #ifdef INET6
403 		if (sa->sa_family == AF_INET6)
404 			salen = sizeof(struct sockaddr_in6);
405 		else
406 			salen = sizeof(struct sockaddr);
407 #else
408 		salen = sizeof(struct sockaddr);
409 #endif
410 #endif
411 		if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
412 			return 1;
413 	}
414 	return 0;
415 }
416 
417 static void
418 hexprint(netdissect_options *ndo, caddr_t loc, size_t len)
419 {
420 	u_char *p;
421 	size_t i;
422 
423 	p = (u_char *)loc;
424 	for (i = 0; i < len; i++)
425 		ND_PRINT((ndo,"%02x", p[i] & 0xff));
426 }
427 
428 static int
429 rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
430 {
431 	ND_TCHECK2(*loc, len);
432 
433 	hexprint(ndo, loc, len);
434 	return 1;
435 trunc:
436 	return 0;
437 }
438 
439 
440 /*
441  * returns false if we run out of data buffer
442  */
443 static int ike_show_somedata(struct netdissect_options *ndo,
444 			     const u_char *cp, const u_char *ep)
445 {
446 	/* there is too much data, just show some of it */
447 	const u_char *end = ep - 20;
448 	int  elen = 20;
449 	int   len = ep - cp;
450 	if(len > 10) {
451 		len = 10;
452 	}
453 
454 	/* really shouldn't happen because of above */
455 	if(end < cp + len) {
456 		end = cp+len;
457 		elen = ep - end;
458 	}
459 
460 	ND_PRINT((ndo," data=("));
461 	if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc;
462 	ND_PRINT((ndo, "..."));
463 	if(elen) {
464 		if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc;
465 	}
466 	ND_PRINT((ndo,")"));
467 	return 1;
468 
469 trunc:
470 	return 0;
471 }
472 
473 struct attrmap {
474 	const char *type;
475 	u_int nvalue;
476 	const char *value[30];	/*XXX*/
477 };
478 
479 static const u_char *
480 ikev1_attrmap_print(netdissect_options *ndo,
481 		    const u_char *p, const u_char *ep,
482 		    const struct attrmap *map, size_t nmap)
483 {
484 	u_int16_t *q;
485 	int totlen;
486 	u_int32_t t, v;
487 
488 	q = (u_int16_t *)p;
489 	if (p[0] & 0x80)
490 		totlen = 4;
491 	else
492 		totlen = 4 + EXTRACT_16BITS(&q[1]);
493 	if (ep < p + totlen) {
494 		ND_PRINT((ndo,"[|attr]"));
495 		return ep + 1;
496 	}
497 
498 	ND_PRINT((ndo,"("));
499 	t = EXTRACT_16BITS(&q[0]) & 0x7fff;
500 	if (map && t < nmap && map[t].type)
501 		ND_PRINT((ndo,"type=%s ", map[t].type));
502 	else
503 		ND_PRINT((ndo,"type=#%d ", t));
504 	if (p[0] & 0x80) {
505 		ND_PRINT((ndo,"value="));
506 		v = EXTRACT_16BITS(&q[1]);
507 		if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
508 			ND_PRINT((ndo,"%s", map[t].value[v]));
509 		else
510 			rawprint(ndo, (caddr_t)&q[1], 2);
511 	} else {
512 		ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1])));
513 		rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1]));
514 	}
515 	ND_PRINT((ndo,")"));
516 	return p + totlen;
517 }
518 
519 static const u_char *
520 ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
521 {
522 	u_int16_t *q;
523 	int totlen;
524 	u_int32_t t;
525 
526 	q = (u_int16_t *)p;
527 	if (p[0] & 0x80)
528 		totlen = 4;
529 	else
530 		totlen = 4 + EXTRACT_16BITS(&q[1]);
531 	if (ep < p + totlen) {
532 		ND_PRINT((ndo,"[|attr]"));
533 		return ep + 1;
534 	}
535 
536 	ND_PRINT((ndo,"("));
537 	t = EXTRACT_16BITS(&q[0]) & 0x7fff;
538 	ND_PRINT((ndo,"type=#%d ", t));
539 	if (p[0] & 0x80) {
540 		ND_PRINT((ndo,"value="));
541 		t = q[1];
542 		rawprint(ndo, (caddr_t)&q[1], 2);
543 	} else {
544 		ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1])));
545 		rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1]));
546 	}
547 	ND_PRINT((ndo,")"));
548 	return p + totlen;
549 }
550 
551 static const u_char *
552 ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
553 	       const struct isakmp_gen *ext,
554 		u_int item_len _U_,
555 		const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
556 		u_int32_t proto0, int depth)
557 {
558 	const struct ikev1_pl_sa *p;
559 	struct ikev1_pl_sa sa;
560 	u_int32_t doi, sit, ident;
561 	const u_char *cp, *np;
562 	int t;
563 
564 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));
565 
566 	p = (struct ikev1_pl_sa *)ext;
567 	ND_TCHECK(*p);
568 	safememcpy(&sa, ext, sizeof(sa));
569 	doi = ntohl(sa.doi);
570 	sit = ntohl(sa.sit);
571 	if (doi != 1) {
572 		ND_PRINT((ndo," doi=%d", doi));
573 		ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit)));
574 		return (u_char *)(p + 1);
575 	}
576 
577 	ND_PRINT((ndo," doi=ipsec"));
578 	ND_PRINT((ndo," situation="));
579 	t = 0;
580 	if (sit & 0x01) {
581 		ND_PRINT((ndo,"identity"));
582 		t++;
583 	}
584 	if (sit & 0x02) {
585 		ND_PRINT((ndo,"%ssecrecy", t ? "+" : ""));
586 		t++;
587 	}
588 	if (sit & 0x04)
589 		ND_PRINT((ndo,"%sintegrity", t ? "+" : ""));
590 
591 	np = (u_char *)ext + sizeof(sa);
592 	if (sit != 0x01) {
593 		ND_TCHECK2(*(ext + 1), sizeof(ident));
594 		safememcpy(&ident, ext + 1, sizeof(ident));
595 		ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident)));
596 		np += sizeof(ident);
597 	}
598 
599 	ext = (struct isakmp_gen *)np;
600 	ND_TCHECK(*ext);
601 
602 	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
603 		depth);
604 
605 	return cp;
606 trunc:
607 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA)));
608 	return NULL;
609 }
610 
611 static const u_char *
612 ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
613 	      const struct isakmp_gen *ext, u_int item_len _U_,
614 	       const u_char *ep, u_int32_t phase, u_int32_t doi0,
615 	       u_int32_t proto0 _U_, int depth)
616 {
617 	const struct ikev1_pl_p *p;
618 	struct ikev1_pl_p prop;
619 	const u_char *cp;
620 
621 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));
622 
623 	p = (struct ikev1_pl_p *)ext;
624 	ND_TCHECK(*p);
625 	safememcpy(&prop, ext, sizeof(prop));
626 	ND_PRINT((ndo," #%d protoid=%s transform=%d",
627 		  prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
628 	if (prop.spi_size) {
629 		ND_PRINT((ndo," spi="));
630 		if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
631 			goto trunc;
632 	}
633 
634 	ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
635 	ND_TCHECK(*ext);
636 
637 	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
638 			     prop.prot_id, depth);
639 
640 	return cp;
641 trunc:
642 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
643 	return NULL;
644 }
645 
646 static const char *ikev1_p_map[] = {
647 	NULL, "ike",
648 };
649 
650 static const char *ikev2_t_type_map[]={
651 	NULL, "encr", "prf", "integ", "dh", "esn"
652 };
653 
654 static const char *ah_p_map[] = {
655 	NULL, "(reserved)", "md5", "sha", "1des",
656 	"sha2-256", "sha2-384", "sha2-512",
657 };
658 
659 static const char *prf_p_map[] = {
660 	NULL, "hmac-md5", "hmac-sha", "hmac-tiger",
661 	"aes128_xcbc"
662 };
663 
664 static const char *integ_p_map[] = {
665 	NULL, "hmac-md5", "hmac-sha", "dec-mac",
666 	"kpdk-md5", "aes-xcbc"
667 };
668 
669 static const char *esn_p_map[] = {
670 	"no-esn", "esn"
671 };
672 
673 static const char *dh_p_map[] = {
674 	NULL, "modp768",
675 	"modp1024",    /* group 2 */
676 	"EC2N 2^155",  /* group 3 */
677 	"EC2N 2^185",  /* group 4 */
678 	"modp1536",    /* group 5 */
679 	"iana-grp06", "iana-grp07", /* reserved */
680 	"iana-grp08", "iana-grp09",
681 	"iana-grp10", "iana-grp11",
682 	"iana-grp12", "iana-grp13",
683 	"modp2048",    /* group 14 */
684 	"modp3072",    /* group 15 */
685 	"modp4096",    /* group 16 */
686 	"modp6144",    /* group 17 */
687 	"modp8192",    /* group 18 */
688 };
689 
690 static const char *esp_p_map[] = {
691 	NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
692 	"blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
693 };
694 
695 static const char *ipcomp_p_map[] = {
696 	NULL, "oui", "deflate", "lzs",
697 };
698 
699 const struct attrmap ipsec_t_map[] = {
700 	{ NULL,	0, { NULL } },
701 	{ "lifetype", 3, { NULL, "sec", "kb", }, },
702 	{ "life", 0, { NULL } },
703 	{ "group desc", 18,	{ NULL, "modp768",
704 				  "modp1024",    /* group 2 */
705 				  "EC2N 2^155",  /* group 3 */
706 				  "EC2N 2^185",  /* group 4 */
707 				  "modp1536",    /* group 5 */
708 				  "iana-grp06", "iana-grp07", /* reserved */
709 				  "iana-grp08", "iana-grp09",
710 				  "iana-grp10", "iana-grp11",
711 				  "iana-grp12", "iana-grp13",
712 				  "modp2048",    /* group 14 */
713 				  "modp3072",    /* group 15 */
714 				  "modp4096",    /* group 16 */
715 				  "modp6144",    /* group 17 */
716 				  "modp8192",    /* group 18 */
717 		}, },
718 	{ "enc mode", 3, { NULL, "tunnel", "transport", }, },
719 	{ "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
720 	{ "keylen", 0, { NULL } },
721 	{ "rounds", 0, { NULL } },
722 	{ "dictsize", 0, { NULL } },
723 	{ "privalg", 0, { NULL } },
724 };
725 
726 const struct attrmap encr_t_map[] = {
727 	{ NULL,	0, { NULL } }, 	{ NULL,	0, { NULL } },  /* 0, 1 */
728 	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 2, 3 */
729 	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 4, 5 */
730 	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 6, 7 */
731 	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 8, 9 */
732 	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 10,11*/
733 	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 12,13*/
734 	{ "keylen", 14, { NULL }},
735 };
736 
737 const struct attrmap oakley_t_map[] = {
738 	{ NULL,	0, { NULL } },
739 	{ "enc", 8,	{ NULL, "1des", "idea", "blowfish", "rc5",
740 		 	  "3des", "cast", "aes", }, },
741 	{ "hash", 7,	{ NULL, "md5", "sha1", "tiger",
742 			  "sha2-256", "sha2-384", "sha2-512", }, },
743 	{ "auth", 6,	{ NULL, "preshared", "dss", "rsa sig", "rsa enc",
744 			  "rsa enc revised", }, },
745 	{ "group desc", 18,	{ NULL, "modp768",
746 				  "modp1024",    /* group 2 */
747 				  "EC2N 2^155",  /* group 3 */
748 				  "EC2N 2^185",  /* group 4 */
749 				  "modp1536",    /* group 5 */
750 				  "iana-grp06", "iana-grp07", /* reserved */
751 				  "iana-grp08", "iana-grp09",
752 				  "iana-grp10", "iana-grp11",
753 				  "iana-grp12", "iana-grp13",
754 				  "modp2048",    /* group 14 */
755 				  "modp3072",    /* group 15 */
756 				  "modp4096",    /* group 16 */
757 				  "modp6144",    /* group 17 */
758 				  "modp8192",    /* group 18 */
759 		}, },
760 	{ "group type", 4,	{ NULL, "MODP", "ECP", "EC2N", }, },
761 	{ "group prime", 0, { NULL } },
762 	{ "group gen1", 0, { NULL } },
763 	{ "group gen2", 0, { NULL } },
764 	{ "group curve A", 0, { NULL } },
765 	{ "group curve B", 0, { NULL } },
766 	{ "lifetype", 3,	{ NULL, "sec", "kb", }, },
767 	{ "lifeduration", 0, { NULL } },
768 	{ "prf", 0, { NULL } },
769 	{ "keylen", 0, { NULL } },
770 	{ "field", 0, { NULL } },
771 	{ "order", 0, { NULL } },
772 };
773 
774 static const u_char *
775 ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
776 	      const struct isakmp_gen *ext, u_int item_len,
777 	      const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
778 	      u_int32_t proto, int depth _U_)
779 {
780 	const struct ikev1_pl_t *p;
781 	struct ikev1_pl_t t;
782 	const u_char *cp;
783 	const char *idstr;
784 	const struct attrmap *map;
785 	size_t nmap;
786 	const u_char *ep2;
787 
788 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T)));
789 
790 	p = (struct ikev1_pl_t *)ext;
791 	ND_TCHECK(*p);
792 	safememcpy(&t, ext, sizeof(t));
793 
794 	switch (proto) {
795 	case 1:
796 		idstr = STR_OR_ID(t.t_id, ikev1_p_map);
797 		map = oakley_t_map;
798 		nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
799 		break;
800 	case 2:
801 		idstr = STR_OR_ID(t.t_id, ah_p_map);
802 		map = ipsec_t_map;
803 		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
804 		break;
805 	case 3:
806 		idstr = STR_OR_ID(t.t_id, esp_p_map);
807 		map = ipsec_t_map;
808 		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
809 		break;
810 	case 4:
811 		idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
812 		map = ipsec_t_map;
813 		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
814 		break;
815 	default:
816 		idstr = NULL;
817 		map = NULL;
818 		nmap = 0;
819 		break;
820 	}
821 
822 	if (idstr)
823 		ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr));
824 	else
825 		ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id));
826 	cp = (u_char *)(p + 1);
827 	ep2 = (u_char *)p + item_len;
828 	while (cp < ep && cp < ep2) {
829 		if (map && nmap) {
830 			cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
831 				map, nmap);
832 		} else
833 			cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
834 	}
835 	if (ep < ep2)
836 		ND_PRINT((ndo,"..."));
837 	return cp;
838 trunc:
839 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
840 	return NULL;
841 }
842 
843 static const u_char *
844 ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
845 	       const struct isakmp_gen *ext, u_int item_len _U_,
846 	       const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
847 	       u_int32_t proto _U_, int depth _U_)
848 {
849 	struct isakmp_gen e;
850 
851 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
852 
853 	ND_TCHECK(*ext);
854 	safememcpy(&e, ext, sizeof(e));
855 	ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
856 	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
857 		ND_PRINT((ndo," "));
858 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
859 			goto trunc;
860 	}
861 	return (u_char *)ext + ntohs(e.len);
862 trunc:
863 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE)));
864 	return NULL;
865 }
866 
867 static const u_char *
868 ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
869 	       const struct isakmp_gen *ext, u_int item_len _U_,
870 	       const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_,
871 	       u_int32_t proto _U_, int depth _U_)
872 {
873 #define USE_IPSECDOI_IN_PHASE1	1
874 	const struct ikev1_pl_id *p;
875 	struct ikev1_pl_id id;
876 	static const char *idtypestr[] = {
877 		"IPv4", "IPv4net", "IPv6", "IPv6net",
878 	};
879 	static const char *ipsecidtypestr[] = {
880 		NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
881 		"IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
882 		"keyid",
883 	};
884 	int len;
885 	const u_char *data;
886 
887 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID)));
888 
889 	p = (struct ikev1_pl_id *)ext;
890 	ND_TCHECK(*p);
891 	safememcpy(&id, ext, sizeof(id));
892 	if (sizeof(*p) < item_len) {
893 		data = (u_char *)(p + 1);
894 		len = item_len - sizeof(*p);
895 	} else {
896 		data = NULL;
897 		len = 0;
898 	}
899 
900 #if 0 /*debug*/
901 	ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto));
902 #endif
903 	switch (phase) {
904 #ifndef USE_IPSECDOI_IN_PHASE1
905 	case 1:
906 #endif
907 	default:
908 		ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)));
909 		ND_PRINT((ndo," doi_data=%u",
910 			  (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff)));
911 		break;
912 
913 #ifdef USE_IPSECDOI_IN_PHASE1
914 	case 1:
915 #endif
916 	case 2:
917 	    {
918 		const struct ipsecdoi_id *p;
919 		struct ipsecdoi_id id;
920 		struct protoent *pe;
921 
922 		p = (struct ipsecdoi_id *)ext;
923 		ND_TCHECK(*p);
924 		safememcpy(&id, ext, sizeof(id));
925 		ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)));
926 		if (id.proto_id) {
927 #ifndef WIN32
928 			setprotoent(1);
929 #endif /* WIN32 */
930 			pe = getprotobynumber(id.proto_id);
931 			if (pe)
932 				ND_PRINT((ndo," protoid=%s", pe->p_name));
933 #ifndef WIN32
934 			endprotoent();
935 #endif /* WIN32 */
936 		} else {
937 			/* it DOES NOT mean IPPROTO_IP! */
938 			ND_PRINT((ndo," protoid=%s", "0"));
939 		}
940 		ND_PRINT((ndo," port=%d", ntohs(id.port)));
941 		if (!len)
942 			break;
943 		if (data == NULL)
944 			goto trunc;
945 		ND_TCHECK2(*data, len);
946 		switch (id.type) {
947 		case IPSECDOI_ID_IPV4_ADDR:
948 			if (len < 4)
949 				ND_PRINT((ndo," len=%d [bad: < 4]", len));
950 			else
951 				ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data)));
952 			len = 0;
953 			break;
954 		case IPSECDOI_ID_FQDN:
955 		case IPSECDOI_ID_USER_FQDN:
956 		    {
957 			int i;
958 			ND_PRINT((ndo," len=%d ", len));
959 			for (i = 0; i < len; i++)
960 				safeputchar(data[i]);
961 			len = 0;
962 			break;
963 		    }
964 		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
965 		    {
966 			const u_char *mask;
967 			if (len < 8)
968 				ND_PRINT((ndo," len=%d [bad: < 8]", len));
969 			else {
970 				mask = data + sizeof(struct in_addr);
971 				ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len,
972 					  ipaddr_string(data),
973 					  mask[0], mask[1], mask[2], mask[3]));
974 			}
975 			len = 0;
976 			break;
977 		    }
978 #ifdef INET6
979 		case IPSECDOI_ID_IPV6_ADDR:
980 			if (len < 16)
981 				ND_PRINT((ndo," len=%d [bad: < 16]", len));
982 			else
983 				ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data)));
984 			len = 0;
985 			break;
986 		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
987 		    {
988 			const u_int32_t *mask;
989 			if (len < 20)
990 				ND_PRINT((ndo," len=%d [bad: < 20]", len));
991 			else {
992 				mask = (u_int32_t *)(data + sizeof(struct in6_addr));
993 				/*XXX*/
994 				ND_PRINT((ndo," len=%d %s/0x%08x%08x%08x%08x", len,
995 					  ip6addr_string(data),
996 					  mask[0], mask[1], mask[2], mask[3]));
997 			}
998 			len = 0;
999 			break;
1000 		    }
1001 #endif /*INET6*/
1002 		case IPSECDOI_ID_IPV4_ADDR_RANGE:
1003 			if (len < 8)
1004 				ND_PRINT((ndo," len=%d [bad: < 8]", len));
1005 			else {
1006 				ND_PRINT((ndo," len=%d %s-%s", len,
1007 					  ipaddr_string(data),
1008 					  ipaddr_string(data + sizeof(struct in_addr))));
1009 			}
1010 			len = 0;
1011 			break;
1012 #ifdef INET6
1013 		case IPSECDOI_ID_IPV6_ADDR_RANGE:
1014 			if (len < 32)
1015 				ND_PRINT((ndo," len=%d [bad: < 32]", len));
1016 			else {
1017 				ND_PRINT((ndo," len=%d %s-%s", len,
1018 					  ip6addr_string(data),
1019 					  ip6addr_string(data + sizeof(struct in6_addr))));
1020 			}
1021 			len = 0;
1022 			break;
1023 #endif /*INET6*/
1024 		case IPSECDOI_ID_DER_ASN1_DN:
1025 		case IPSECDOI_ID_DER_ASN1_GN:
1026 		case IPSECDOI_ID_KEY_ID:
1027 			break;
1028 		}
1029 		break;
1030 	    }
1031 	}
1032 	if (data && len) {
1033 		ND_PRINT((ndo," len=%d", len));
1034 		if (2 < ndo->ndo_vflag) {
1035 			ND_PRINT((ndo," "));
1036 			if (!rawprint(ndo, (caddr_t)data, len))
1037 				goto trunc;
1038 		}
1039 	}
1040 	return (u_char *)ext + item_len;
1041 trunc:
1042 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID)));
1043 	return NULL;
1044 }
1045 
1046 static const u_char *
1047 ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
1048 		 const struct isakmp_gen *ext, u_int item_len _U_,
1049 		 const u_char *ep _U_, u_int32_t phase _U_,
1050 		 u_int32_t doi0 _U_,
1051 		 u_int32_t proto0 _U_, int depth _U_)
1052 {
1053 	const struct ikev1_pl_cert *p;
1054 	struct ikev1_pl_cert cert;
1055 	static const char *certstr[] = {
1056 		"none",	"pkcs7", "pgp", "dns",
1057 		"x509sign", "x509ke", "kerberos", "crl",
1058 		"arl", "spki", "x509attr",
1059 	};
1060 
1061 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT)));
1062 
1063 	p = (struct ikev1_pl_cert *)ext;
1064 	ND_TCHECK(*p);
1065 	safememcpy(&cert, ext, sizeof(cert));
1066 	ND_PRINT((ndo," len=%d", item_len - 4));
1067 	ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1068 	if (2 < ndo->ndo_vflag && 4 < item_len) {
1069 		ND_PRINT((ndo," "));
1070 		if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
1071 			goto trunc;
1072 	}
1073 	return (u_char *)ext + item_len;
1074 trunc:
1075 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)));
1076 	return NULL;
1077 }
1078 
1079 static const u_char *
1080 ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
1081 	       const struct isakmp_gen *ext, u_int item_len _U_,
1082 	       const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
1083 	       u_int32_t proto0 _U_, int depth _U_)
1084 {
1085 	const struct ikev1_pl_cert *p;
1086 	struct ikev1_pl_cert cert;
1087 	static const char *certstr[] = {
1088 		"none",	"pkcs7", "pgp", "dns",
1089 		"x509sign", "x509ke", "kerberos", "crl",
1090 		"arl", "spki", "x509attr",
1091 	};
1092 
1093 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR)));
1094 
1095 	p = (struct ikev1_pl_cert *)ext;
1096 	ND_TCHECK(*p);
1097 	safememcpy(&cert, ext, sizeof(cert));
1098 	ND_PRINT((ndo," len=%d", item_len - 4));
1099 	ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1100 	if (2 < ndo->ndo_vflag && 4 < item_len) {
1101 		ND_PRINT((ndo," "));
1102 		if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
1103 			goto trunc;
1104 	}
1105 	return (u_char *)ext + item_len;
1106 trunc:
1107 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR)));
1108 	return NULL;
1109 }
1110 
1111 static const u_char *
1112 ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
1113 		 const struct isakmp_gen *ext, u_int item_len _U_,
1114 		 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
1115 		 u_int32_t proto _U_, int depth _U_)
1116 {
1117 	struct isakmp_gen e;
1118 
1119 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
1120 
1121 	ND_TCHECK(*ext);
1122 	safememcpy(&e, ext, sizeof(e));
1123 	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1124 	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1125 		ND_PRINT((ndo," "));
1126 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1127 			goto trunc;
1128 	}
1129 	return (u_char *)ext + ntohs(e.len);
1130 trunc:
1131 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)));
1132 	return NULL;
1133 }
1134 
1135 static const u_char *
1136 ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
1137 		const struct isakmp_gen *ext, u_int item_len _U_,
1138 		const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
1139 		u_int32_t proto _U_, int depth _U_)
1140 {
1141 	struct isakmp_gen e;
1142 
1143 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
1144 
1145 	ND_TCHECK(*ext);
1146 	safememcpy(&e, ext, sizeof(e));
1147 	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1148 	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1149 		ND_PRINT((ndo," "));
1150 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1151 			goto trunc;
1152 	}
1153 	return (u_char *)ext + ntohs(e.len);
1154 trunc:
1155 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)));
1156 	return NULL;
1157 }
1158 
1159 static const u_char *
1160 ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
1161 		  const struct isakmp_gen *ext,
1162 		  u_int item_len _U_,
1163 		  const u_char *ep _U_,
1164 		  u_int32_t phase _U_, u_int32_t doi _U_,
1165 		  u_int32_t proto _U_, int depth _U_)
1166 {
1167 	struct isakmp_gen e;
1168 
1169 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
1170 
1171 	ND_TCHECK(*ext);
1172 	safememcpy(&e, ext, sizeof(e));
1173 	ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
1174 	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1175 		ND_PRINT((ndo," "));
1176 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1177 			goto trunc;
1178 	} else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1179 		ND_PRINT((ndo," "));
1180 		if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep))
1181 			goto trunc;
1182 	}
1183 	return (u_char *)ext + ntohs(e.len);
1184 trunc:
1185 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)));
1186 	return NULL;
1187 }
1188 
1189 static const u_char *
1190 ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
1191 	      const struct isakmp_gen *ext, u_int item_len,
1192 	      const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
1193 	      u_int32_t proto0 _U_, int depth)
1194 {
1195 	struct ikev1_pl_n *p, n;
1196 	const u_char *cp;
1197 	u_char *ep2;
1198 	u_int32_t doi;
1199 	u_int32_t proto;
1200 	static const char *notify_error_str[] = {
1201 		NULL,				"INVALID-PAYLOAD-TYPE",
1202 		"DOI-NOT-SUPPORTED",		"SITUATION-NOT-SUPPORTED",
1203 		"INVALID-COOKIE",		"INVALID-MAJOR-VERSION",
1204 		"INVALID-MINOR-VERSION",	"INVALID-EXCHANGE-TYPE",
1205 		"INVALID-FLAGS",		"INVALID-MESSAGE-ID",
1206 		"INVALID-PROTOCOL-ID",		"INVALID-SPI",
1207 		"INVALID-TRANSFORM-ID",		"ATTRIBUTES-NOT-SUPPORTED",
1208 		"NO-PROPOSAL-CHOSEN",		"BAD-PROPOSAL-SYNTAX",
1209 		"PAYLOAD-MALFORMED",		"INVALID-KEY-INFORMATION",
1210 		"INVALID-ID-INFORMATION",	"INVALID-CERT-ENCODING",
1211 		"INVALID-CERTIFICATE",		"CERT-TYPE-UNSUPPORTED",
1212 		"INVALID-CERT-AUTHORITY",	"INVALID-HASH-INFORMATION",
1213 		"AUTHENTICATION-FAILED",	"INVALID-SIGNATURE",
1214 		"ADDRESS-NOTIFICATION",		"NOTIFY-SA-LIFETIME",
1215 		"CERTIFICATE-UNAVAILABLE",	"UNSUPPORTED-EXCHANGE-TYPE",
1216 		"UNEQUAL-PAYLOAD-LENGTHS",
1217 	};
1218 	static const char *ipsec_notify_error_str[] = {
1219 		"RESERVED",
1220 	};
1221 	static const char *notify_status_str[] = {
1222 		"CONNECTED",
1223 	};
1224 	static const char *ipsec_notify_status_str[] = {
1225 		"RESPONDER-LIFETIME",		"REPLAY-STATUS",
1226 		"INITIAL-CONTACT",
1227 	};
1228 /* NOTE: these macro must be called with x in proper range */
1229 
1230 /* 0 - 8191 */
1231 #define NOTIFY_ERROR_STR(x) \
1232 	STR_OR_ID((x), notify_error_str)
1233 
1234 /* 8192 - 16383 */
1235 #define IPSEC_NOTIFY_ERROR_STR(x) \
1236 	STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1237 
1238 /* 16384 - 24575 */
1239 #define NOTIFY_STATUS_STR(x) \
1240 	STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1241 
1242 /* 24576 - 32767 */
1243 #define IPSEC_NOTIFY_STATUS_STR(x) \
1244 	STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1245 
1246 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N)));
1247 
1248 	p = (struct ikev1_pl_n *)ext;
1249 	ND_TCHECK(*p);
1250 	safememcpy(&n, ext, sizeof(n));
1251 	doi = ntohl(n.doi);
1252 	proto = n.prot_id;
1253 	if (doi != 1) {
1254 		ND_PRINT((ndo," doi=%d", doi));
1255 		ND_PRINT((ndo," proto=%d", proto));
1256 		if (ntohs(n.type) < 8192)
1257 			ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
1258 		else if (ntohs(n.type) < 16384)
1259 			ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1260 		else if (ntohs(n.type) < 24576)
1261 			ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
1262 		else
1263 			ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1264 		if (n.spi_size) {
1265 			ND_PRINT((ndo," spi="));
1266 			if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
1267 				goto trunc;
1268 		}
1269 		return (u_char *)(p + 1) + n.spi_size;
1270 	}
1271 
1272 	ND_PRINT((ndo," doi=ipsec"));
1273 	ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
1274 	if (ntohs(n.type) < 8192)
1275 		ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
1276 	else if (ntohs(n.type) < 16384)
1277 		ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type))));
1278 	else if (ntohs(n.type) < 24576)
1279 		ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
1280 	else if (ntohs(n.type) < 32768)
1281 		ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type))));
1282 	else
1283 		ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1284 	if (n.spi_size) {
1285 		ND_PRINT((ndo," spi="));
1286 		if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
1287 			goto trunc;
1288 	}
1289 
1290 	cp = (u_char *)(p + 1) + n.spi_size;
1291 	ep2 = (u_char *)p + item_len;
1292 
1293 	if (cp < ep) {
1294 		ND_PRINT((ndo," orig=("));
1295 		switch (ntohs(n.type)) {
1296 		case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1297 		    {
1298 			const struct attrmap *map = oakley_t_map;
1299 			size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1300 			while (cp < ep && cp < ep2) {
1301 				cp = ikev1_attrmap_print(ndo, cp,
1302 					(ep < ep2) ? ep : ep2, map, nmap);
1303 			}
1304 			break;
1305 		    }
1306 		case IPSECDOI_NTYPE_REPLAY_STATUS:
1307 			ND_PRINT((ndo,"replay detection %sabled",
1308 				  (*(u_int32_t *)cp) ? "en" : "dis"));
1309 			break;
1310 		case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1311 			if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
1312 					    (struct isakmp_gen *)cp, ep, phase, doi, proto,
1313 					    depth) == NULL)
1314 				return NULL;
1315 			break;
1316 		default:
1317 			/* NULL is dummy */
1318 			isakmp_print(ndo, cp,
1319 				     item_len - sizeof(*p) - n.spi_size,
1320 				     NULL);
1321 		}
1322 		ND_PRINT((ndo,")"));
1323 	}
1324 	return (u_char *)ext + item_len;
1325 trunc:
1326 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
1327 	return NULL;
1328 }
1329 
1330 static const u_char *
1331 ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
1332 	      const struct isakmp_gen *ext, u_int item_len _U_,
1333 	      const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
1334 	      u_int32_t proto0 _U_, int depth _U_)
1335 {
1336 	const struct ikev1_pl_d *p;
1337 	struct ikev1_pl_d d;
1338 	const u_int8_t *q;
1339 	u_int32_t doi;
1340 	u_int32_t proto;
1341 	int i;
1342 
1343 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D)));
1344 
1345 	p = (struct ikev1_pl_d *)ext;
1346 	ND_TCHECK(*p);
1347 	safememcpy(&d, ext, sizeof(d));
1348 	doi = ntohl(d.doi);
1349 	proto = d.prot_id;
1350 	if (doi != 1) {
1351 		ND_PRINT((ndo," doi=%u", doi));
1352 		ND_PRINT((ndo," proto=%u", proto));
1353 	} else {
1354 		ND_PRINT((ndo," doi=ipsec"));
1355 		ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
1356 	}
1357 	ND_PRINT((ndo," spilen=%u", d.spi_size));
1358 	ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi)));
1359 	ND_PRINT((ndo," spi="));
1360 	q = (u_int8_t *)(p + 1);
1361 	for (i = 0; i < ntohs(d.num_spi); i++) {
1362 		if (i != 0)
1363 			ND_PRINT((ndo,","));
1364 		if (!rawprint(ndo, (caddr_t)q, d.spi_size))
1365 			goto trunc;
1366 		q += d.spi_size;
1367 	}
1368 	return q;
1369 trunc:
1370 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D)));
1371 	return NULL;
1372 }
1373 
1374 static const u_char *
1375 ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
1376 		const struct isakmp_gen *ext,
1377 		u_int item_len _U_, const u_char *ep _U_,
1378 		u_int32_t phase _U_, u_int32_t doi _U_,
1379 		u_int32_t proto _U_, int depth _U_)
1380 {
1381 	struct isakmp_gen e;
1382 
1383 	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
1384 
1385 	ND_TCHECK(*ext);
1386 	safememcpy(&e, ext, sizeof(e));
1387 	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1388 	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1389 		ND_PRINT((ndo," "));
1390 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1391 			goto trunc;
1392 	}
1393 	return (u_char *)ext + ntohs(e.len);
1394 trunc:
1395 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID)));
1396 	return NULL;
1397 }
1398 
1399 /************************************************************/
1400 /*                                                          */
1401 /*              IKE v2 - rfc4306 - dissector                */
1402 /*                                                          */
1403 /************************************************************/
1404 
1405 static void
1406 ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical)
1407 {
1408 	ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : ""));
1409 }
1410 
1411 static const u_char *
1412 ikev2_gen_print(netdissect_options *ndo, u_char tpay,
1413 		const struct isakmp_gen *ext)
1414 {
1415 	struct isakmp_gen e;
1416 
1417 	ND_TCHECK(*ext);
1418 	safememcpy(&e, ext, sizeof(e));
1419 	ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
1420 
1421 	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1422 	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1423 		ND_PRINT((ndo," "));
1424 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1425 			goto trunc;
1426 	}
1427 	return (u_char *)ext + ntohs(e.len);
1428 trunc:
1429 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1430 	return NULL;
1431 }
1432 
1433 static const u_char *
1434 ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
1435 	      const struct isakmp_gen *ext, u_int item_len,
1436 	      const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
1437 	      u_int32_t proto _U_, int depth _U_)
1438 {
1439 	const struct ikev2_t *p;
1440 	struct ikev2_t t;
1441 	u_int16_t  t_id;
1442 	const u_char *cp;
1443 	const char *idstr;
1444 	const struct attrmap *map;
1445 	size_t nmap;
1446 	const u_char *ep2;
1447 
1448 	p = (struct ikev2_t *)ext;
1449 	ND_TCHECK(*p);
1450 	safememcpy(&t, ext, sizeof(t));
1451 	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
1452 
1453 	t_id = ntohs(t.t_id);
1454 
1455 	map = NULL;
1456 	nmap = 0;
1457 
1458 	switch (t.t_type) {
1459 	case IV2_T_ENCR:
1460 		idstr = STR_OR_ID(t_id, esp_p_map);
1461 		map = encr_t_map;
1462 		nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]);
1463 		break;
1464 
1465 	case IV2_T_PRF:
1466 		idstr = STR_OR_ID(t_id, prf_p_map);
1467 		break;
1468 
1469 	case IV2_T_INTEG:
1470 		idstr = STR_OR_ID(t_id, integ_p_map);
1471 		break;
1472 
1473 	case IV2_T_DH:
1474 		idstr = STR_OR_ID(t_id, dh_p_map);
1475 		break;
1476 
1477 	case IV2_T_ESN:
1478 		idstr = STR_OR_ID(t_id, esn_p_map);
1479 		break;
1480 
1481 	default:
1482 		idstr = NULL;
1483 		break;
1484 	}
1485 
1486 	if (idstr)
1487 		ND_PRINT((ndo," #%u type=%s id=%s ", pcount,
1488 			  STR_OR_ID(t.t_type, ikev2_t_type_map),
1489 			  idstr));
1490 	else
1491 		ND_PRINT((ndo," #%u type=%s id=%u ", pcount,
1492 			  STR_OR_ID(t.t_type, ikev2_t_type_map),
1493 			  t.t_id));
1494 	cp = (u_char *)(p + 1);
1495 	ep2 = (u_char *)p + item_len;
1496 	while (cp < ep && cp < ep2) {
1497 		if (map && nmap) {
1498 			cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
1499 				map, nmap);
1500 		} else
1501 			cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
1502 	}
1503 	if (ep < ep2)
1504 		ND_PRINT((ndo,"..."));
1505 	return cp;
1506 trunc:
1507 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
1508 	return NULL;
1509 }
1510 
1511 static const u_char *
1512 ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
1513 	      const struct isakmp_gen *ext, u_int item_len _U_,
1514 	       const u_char *ep, u_int32_t phase, u_int32_t doi0,
1515 	       u_int32_t proto0 _U_, int depth)
1516 {
1517 	const struct ikev2_p *p;
1518 	struct ikev2_p prop;
1519 	const u_char *cp;
1520 
1521 	p = (struct ikev2_p *)ext;
1522 	ND_TCHECK(*p);
1523 	safememcpy(&prop, ext, sizeof(prop));
1524 	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
1525 
1526 	ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
1527 		  prop.p_no,  PROTOIDSTR(prop.prot_id),
1528 		  prop.num_t, ntohs(prop.h.len)));
1529 	if (prop.spi_size) {
1530 		ND_PRINT((ndo," spi="));
1531 		if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
1532 			goto trunc;
1533 	}
1534 
1535 	ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
1536 	ND_TCHECK(*ext);
1537 
1538 	cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1539 			     prop.prot_id, depth);
1540 
1541 	return cp;
1542 trunc:
1543 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
1544 	return NULL;
1545 }
1546 
1547 static const u_char *
1548 ikev2_sa_print(netdissect_options *ndo, u_char tpay,
1549 		const struct isakmp_gen *ext1,
1550 		u_int item_len _U_, const u_char *ep _U_,
1551 		u_int32_t phase _U_, u_int32_t doi _U_,
1552 		u_int32_t proto _U_, int depth _U_)
1553 {
1554 	struct isakmp_gen e;
1555 	int    osa_length, sa_length;
1556 
1557 	ND_TCHECK(*ext1);
1558 	safememcpy(&e, ext1, sizeof(e));
1559 	ikev2_pay_print(ndo, "sa", e.critical);
1560 
1561 	osa_length= ntohs(e.len);
1562 	sa_length = osa_length - 4;
1563 	ND_PRINT((ndo," len=%d", sa_length));
1564 
1565 	ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
1566 			ext1+1, ep,
1567 			0, 0, 0, depth);
1568 
1569 	return (u_char *)ext1 + osa_length;
1570 trunc:
1571 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1572 	return NULL;
1573 }
1574 
1575 static const u_char *
1576 ikev2_ke_print(netdissect_options *ndo, u_char tpay,
1577 		const struct isakmp_gen *ext,
1578 		u_int item_len _U_, const u_char *ep _U_,
1579 		u_int32_t phase _U_, u_int32_t doi _U_,
1580 		u_int32_t proto _U_, int depth _U_)
1581 {
1582 	struct ikev2_ke ke;
1583 	struct ikev2_ke *k;
1584 
1585 	k = (struct ikev2_ke *)ext;
1586 	ND_TCHECK(*ext);
1587 	safememcpy(&ke, ext, sizeof(ke));
1588 	ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
1589 
1590 	ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
1591 		  STR_OR_ID(ntohs(ke.ke_group), dh_p_map)));
1592 
1593 	if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) {
1594 		ND_PRINT((ndo," "));
1595 		if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8))
1596 			goto trunc;
1597 	}
1598 	return (u_char *)ext + ntohs(ke.h.len);
1599 trunc:
1600 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1601 	return NULL;
1602 }
1603 
1604 static const u_char *
1605 ikev2_ID_print(netdissect_options *ndo, u_char tpay,
1606 		const struct isakmp_gen *ext,
1607 		u_int item_len _U_, const u_char *ep _U_,
1608 		u_int32_t phase _U_, u_int32_t doi _U_,
1609 		u_int32_t proto _U_, int depth _U_)
1610 {
1611 	struct ikev2_id id;
1612 	int id_len, idtype_len, i;
1613 	unsigned int dumpascii, dumphex;
1614 	unsigned char *typedata;
1615 
1616 	ND_TCHECK(*ext);
1617 	safememcpy(&id, ext, sizeof(id));
1618 	ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
1619 
1620 	id_len = ntohs(id.h.len);
1621 
1622 	ND_PRINT((ndo," len=%d", id_len - 4));
1623 	if (2 < ndo->ndo_vflag && 4 < id_len) {
1624 		ND_PRINT((ndo," "));
1625 		if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4))
1626 			goto trunc;
1627 	}
1628 
1629 	idtype_len =id_len - sizeof(struct ikev2_id);
1630 	dumpascii = 0;
1631 	dumphex   = 0;
1632 	typedata  = (unsigned char *)(ext)+sizeof(struct ikev2_id);
1633 
1634 	switch(id.type) {
1635 	case ID_IPV4_ADDR:
1636 		ND_PRINT((ndo, " ipv4:"));
1637 		dumphex=1;
1638 		break;
1639 	case ID_FQDN:
1640 		ND_PRINT((ndo, " fqdn:"));
1641 		dumpascii=1;
1642 		break;
1643 	case ID_RFC822_ADDR:
1644 		ND_PRINT((ndo, " rfc822:"));
1645 		dumpascii=1;
1646 		break;
1647 	case ID_IPV6_ADDR:
1648 		ND_PRINT((ndo, " ipv6:"));
1649 		dumphex=1;
1650 		break;
1651 	case ID_DER_ASN1_DN:
1652 		ND_PRINT((ndo, " dn:"));
1653 		dumphex=1;
1654 		break;
1655 	case ID_DER_ASN1_GN:
1656 		ND_PRINT((ndo, " gn:"));
1657 		dumphex=1;
1658 		break;
1659 	case ID_KEY_ID:
1660 		ND_PRINT((ndo, " keyid:"));
1661 		dumphex=1;
1662 		break;
1663 	}
1664 
1665 	if(dumpascii) {
1666 		ND_TCHECK2(*typedata, idtype_len);
1667 		for(i=0; i<idtype_len; i++) {
1668 			if(isprint(typedata[i])) {
1669 				ND_PRINT((ndo, "%c", typedata[i]));
1670 			} else {
1671 				ND_PRINT((ndo, "."));
1672 			}
1673 		}
1674 	}
1675 	if(dumphex) {
1676 		if (!rawprint(ndo, (caddr_t)typedata, idtype_len))
1677 			goto trunc;
1678 	}
1679 
1680 	return (u_char *)ext + id_len;
1681 trunc:
1682 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1683 	return NULL;
1684 }
1685 
1686 static const u_char *
1687 ikev2_cert_print(netdissect_options *ndo, u_char tpay,
1688 		const struct isakmp_gen *ext,
1689 		u_int item_len _U_, const u_char *ep _U_,
1690 		u_int32_t phase _U_, u_int32_t doi _U_,
1691 		u_int32_t proto _U_, int depth _U_)
1692 {
1693 	return ikev2_gen_print(ndo, tpay, ext);
1694 }
1695 
1696 static const u_char *
1697 ikev2_cr_print(netdissect_options *ndo, u_char tpay,
1698 		const struct isakmp_gen *ext,
1699 		u_int item_len _U_, const u_char *ep _U_,
1700 		u_int32_t phase _U_, u_int32_t doi _U_,
1701 		u_int32_t proto _U_, int depth _U_)
1702 {
1703 	return ikev2_gen_print(ndo, tpay, ext);
1704 }
1705 
1706 static const u_char *
1707 ikev2_auth_print(netdissect_options *ndo, u_char tpay,
1708 		const struct isakmp_gen *ext,
1709 		u_int item_len _U_, const u_char *ep _U_,
1710 		u_int32_t phase _U_, u_int32_t doi _U_,
1711 		u_int32_t proto _U_, int depth _U_)
1712 {
1713 	struct ikev2_auth a;
1714 	const char *v2_auth[]={ "invalid", "rsasig",
1715 				"shared-secret", "dsssig" };
1716 	u_char *authdata = (u_char*)ext + sizeof(a);
1717 	unsigned int len;
1718 
1719 	ND_TCHECK(*ext);
1720 	safememcpy(&a, ext, sizeof(a));
1721 	ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
1722 	len = ntohs(a.h.len);
1723 
1724 	ND_PRINT((ndo," len=%d method=%s", len-4,
1725 		  STR_OR_ID(a.auth_method, v2_auth)));
1726 
1727 	if (1 < ndo->ndo_vflag && 4 < len) {
1728 		ND_PRINT((ndo," authdata=("));
1729 		if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a)))
1730 			goto trunc;
1731 		ND_PRINT((ndo,") "));
1732 	} else if(ndo->ndo_vflag && 4 < len) {
1733 		if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
1734 	}
1735 
1736 	return (u_char *)ext + len;
1737 trunc:
1738 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1739 	return NULL;
1740 }
1741 
1742 static const u_char *
1743 ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
1744 		const struct isakmp_gen *ext,
1745 		u_int item_len _U_, const u_char *ep _U_,
1746 		u_int32_t phase _U_, u_int32_t doi _U_,
1747 		u_int32_t proto _U_, int depth _U_)
1748 {
1749 	struct isakmp_gen e;
1750 
1751 	ND_TCHECK(*ext);
1752 	safememcpy(&e, ext, sizeof(e));
1753 	ikev2_pay_print(ndo, "nonce", e.critical);
1754 
1755 	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1756 	if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1757 		ND_PRINT((ndo," nonce=("));
1758 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1759 			goto trunc;
1760 		ND_PRINT((ndo,") "));
1761 	} else if(ndo->ndo_vflag && 4 < ntohs(e.len)) {
1762 		if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
1763 	}
1764 
1765 	return (u_char *)ext + ntohs(e.len);
1766 trunc:
1767 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1768 	return NULL;
1769 }
1770 
1771 /* notify payloads */
1772 static const u_char *
1773 ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
1774 		const struct isakmp_gen *ext,
1775 		u_int item_len _U_, const u_char *ep _U_,
1776 		u_int32_t phase _U_, u_int32_t doi _U_,
1777 		u_int32_t proto _U_, int depth _U_)
1778 {
1779 	struct ikev2_n *p, n;
1780 	const u_char *cp;
1781 	u_char showspi, showdata, showsomedata;
1782 	const char *notify_name;
1783 	u_int32_t type;
1784 
1785 	p = (struct ikev2_n *)ext;
1786 	ND_TCHECK(*p);
1787 	safememcpy(&n, ext, sizeof(n));
1788 	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
1789 
1790 	showspi = 1;
1791 	showdata = 0;
1792 	showsomedata=0;
1793 	notify_name=NULL;
1794 
1795 	ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id)));
1796 
1797 	type = ntohs(n.type);
1798 
1799 	/* notify space is annoying sparse */
1800 	switch(type) {
1801 	case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD:
1802 		notify_name = "unsupported_critical_payload";
1803 		showspi = 0;
1804 		break;
1805 
1806 	case IV2_NOTIFY_INVALID_IKE_SPI:
1807 		notify_name = "invalid_ike_spi";
1808 		showspi = 1;
1809 		break;
1810 
1811 	case IV2_NOTIFY_INVALID_MAJOR_VERSION:
1812 		notify_name = "invalid_major_version";
1813 		showspi = 0;
1814 		break;
1815 
1816 	case IV2_NOTIFY_INVALID_SYNTAX:
1817 		notify_name = "invalid_syntax";
1818 		showspi = 1;
1819 		break;
1820 
1821 	case IV2_NOTIFY_INVALID_MESSAGE_ID:
1822 		notify_name = "invalid_message_id";
1823 		showspi = 1;
1824 		break;
1825 
1826 	case IV2_NOTIFY_INVALID_SPI:
1827 		notify_name = "invalid_spi";
1828 		showspi = 1;
1829 		break;
1830 
1831 	case IV2_NOTIFY_NO_PROPOSAL_CHOSEN:
1832 		notify_name = "no_protocol_chosen";
1833 		showspi = 1;
1834 		break;
1835 
1836 	case IV2_NOTIFY_INVALID_KE_PAYLOAD:
1837 		notify_name = "invalid_ke_payload";
1838 		showspi = 1;
1839 		break;
1840 
1841 	case IV2_NOTIFY_AUTHENTICATION_FAILED:
1842 		notify_name = "authentication_failed";
1843 		showspi = 1;
1844 		break;
1845 
1846 	case IV2_NOTIFY_SINGLE_PAIR_REQUIRED:
1847 		notify_name = "single_pair_required";
1848 		showspi = 1;
1849 		break;
1850 
1851 	case IV2_NOTIFY_NO_ADDITIONAL_SAS:
1852 		notify_name = "no_additional_sas";
1853 		showspi = 0;
1854 		break;
1855 
1856 	case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE:
1857 		notify_name = "internal_address_failure";
1858 		showspi = 0;
1859 		break;
1860 
1861 	case IV2_NOTIFY_FAILED_CP_REQUIRED:
1862 		notify_name = "failed:cp_required";
1863 		showspi = 0;
1864 		break;
1865 
1866 	case IV2_NOTIFY_INVALID_SELECTORS:
1867 		notify_name = "invalid_selectors";
1868 		showspi = 0;
1869 		break;
1870 
1871 	case IV2_NOTIFY_INITIAL_CONTACT:
1872 		notify_name = "initial_contact";
1873 		showspi = 0;
1874 		break;
1875 
1876 	case IV2_NOTIFY_SET_WINDOW_SIZE:
1877 		notify_name = "set_window_size";
1878 		showspi = 0;
1879 		break;
1880 
1881 	case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE:
1882 		notify_name = "additional_ts_possible";
1883 		showspi = 0;
1884 		break;
1885 
1886 	case IV2_NOTIFY_IPCOMP_SUPPORTED:
1887 		notify_name = "ipcomp_supported";
1888 		showspi = 0;
1889 		break;
1890 
1891 	case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP:
1892 		notify_name = "nat_detection_source_ip";
1893 		showspi = 1;
1894 		break;
1895 
1896 	case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP:
1897 		notify_name = "nat_detection_destination_ip";
1898 		showspi = 1;
1899 		break;
1900 
1901 	case IV2_NOTIFY_COOKIE:
1902 		notify_name = "cookie";
1903 		showspi = 1;
1904 		showsomedata= 1;
1905 		showdata= 0;
1906 		break;
1907 
1908 	case IV2_NOTIFY_USE_TRANSPORT_MODE:
1909 		notify_name = "use_transport_mode";
1910 		showspi = 0;
1911 		break;
1912 
1913 	case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED:
1914 		notify_name = "http_cert_lookup_supported";
1915 		showspi = 0;
1916 		break;
1917 
1918 	case IV2_NOTIFY_REKEY_SA:
1919 		notify_name = "rekey_sa";
1920 		showspi = 1;
1921 		break;
1922 
1923 	case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED:
1924 		notify_name = "tfc_padding_not_supported";
1925 		showspi = 0;
1926 		break;
1927 
1928 	case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO:
1929 		notify_name = "non_first_fragment_also";
1930 		showspi = 0;
1931 		break;
1932 
1933 	default:
1934 		if (type < 8192) {
1935 			notify_name="error";
1936 		} else if(type < 16384) {
1937 			notify_name="private-error";
1938 		} else if(type < 40960) {
1939 			notify_name="status";
1940 		} else {
1941 			notify_name="private-status";
1942 		}
1943 	}
1944 
1945 	if(notify_name) {
1946 		ND_PRINT((ndo," type=%u(%s)", type, notify_name));
1947 	}
1948 
1949 
1950 	if (showspi && n.spi_size) {
1951 		ND_PRINT((ndo," spi="));
1952 		if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
1953 			goto trunc;
1954 	}
1955 
1956 	cp = (u_char *)(p + 1) + n.spi_size;
1957 
1958 	if(3 < ndo->ndo_vflag) {
1959 		showdata = 1;
1960 	}
1961 
1962 	if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
1963 		ND_PRINT((ndo," data=("));
1964 		if (!rawprint(ndo, (caddr_t)(cp), ep - cp))
1965 			goto trunc;
1966 
1967 		ND_PRINT((ndo,")"));
1968 
1969 	} else if(showsomedata && cp < ep) {
1970 		if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
1971 	}
1972 
1973 	return (u_char *)ext + item_len;
1974 trunc:
1975 	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
1976 	return NULL;
1977 }
1978 
1979 static const u_char *
1980 ikev2_d_print(netdissect_options *ndo, u_char tpay,
1981 		const struct isakmp_gen *ext,
1982 		u_int item_len _U_, const u_char *ep _U_,
1983 		u_int32_t phase _U_, u_int32_t doi _U_,
1984 		u_int32_t proto _U_, int depth _U_)
1985 {
1986 	return ikev2_gen_print(ndo, tpay, ext);
1987 }
1988 
1989 static const u_char *
1990 ikev2_vid_print(netdissect_options *ndo, u_char tpay,
1991 		const struct isakmp_gen *ext,
1992 		u_int item_len _U_, const u_char *ep _U_,
1993 		u_int32_t phase _U_, u_int32_t doi _U_,
1994 		u_int32_t proto _U_, int depth _U_)
1995 {
1996 	struct isakmp_gen e;
1997 	const u_char *vid;
1998 	int i, len;
1999 
2000 	ND_TCHECK(*ext);
2001 	safememcpy(&e, ext, sizeof(e));
2002 	ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2003 	ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
2004 
2005 	vid = (const u_char *)(ext+1);
2006 	len = ntohs(e.len) - 4;
2007 	ND_TCHECK2(*vid, len);
2008 	for(i=0; i<len; i++) {
2009 		if(isprint(vid[i])) ND_PRINT((ndo, "%c", vid[i]));
2010 		else ND_PRINT((ndo, "."));
2011 	}
2012 	if (2 < ndo->ndo_vflag && 4 < len) {
2013 		ND_PRINT((ndo," "));
2014 		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
2015 			goto trunc;
2016 	}
2017 	return (u_char *)ext + ntohs(e.len);
2018 trunc:
2019 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2020 	return NULL;
2021 }
2022 
2023 static const u_char *
2024 ikev2_TS_print(netdissect_options *ndo, u_char tpay,
2025 		const struct isakmp_gen *ext,
2026 		u_int item_len _U_, const u_char *ep _U_,
2027 		u_int32_t phase _U_, u_int32_t doi _U_,
2028 		u_int32_t proto _U_, int depth _U_)
2029 {
2030 	return ikev2_gen_print(ndo, tpay, ext);
2031 }
2032 
2033 static const u_char *
2034 ikev2_e_print(netdissect_options *ndo,
2035 #ifndef HAVE_LIBCRYPTO
2036 	      _U_
2037 #endif
2038 	      struct isakmp *base,
2039 	      u_char tpay,
2040 	      const struct isakmp_gen *ext,
2041 	      u_int item_len _U_, const u_char *ep _U_,
2042 #ifndef HAVE_LIBCRYPTO
2043 	      _U_
2044 #endif
2045 	      u_int32_t phase,
2046 #ifndef HAVE_LIBCRYPTO
2047 	      _U_
2048 #endif
2049 	      u_int32_t doi,
2050 #ifndef HAVE_LIBCRYPTO
2051 	      _U_
2052 #endif
2053 	      u_int32_t proto,
2054 #ifndef HAVE_LIBCRYPTO
2055 	      _U_
2056 #endif
2057 	      int depth)
2058 {
2059 	struct isakmp_gen e;
2060 	u_char *dat;
2061 	volatile int dlen;
2062 
2063 	ND_TCHECK(*ext);
2064 	safememcpy(&e, ext, sizeof(e));
2065 	ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2066 
2067 	dlen = ntohs(e.len)-4;
2068 
2069 	ND_PRINT((ndo," len=%d", dlen));
2070 	if (2 < ndo->ndo_vflag && 4 < dlen) {
2071 		ND_PRINT((ndo," "));
2072 		if (!rawprint(ndo, (caddr_t)(ext + 1), dlen))
2073 			goto trunc;
2074 	}
2075 
2076 	dat = (u_char *)(ext+1);
2077 	ND_TCHECK2(*dat, dlen);
2078 
2079 #ifdef HAVE_LIBCRYPTO
2080 	/* try to decypt it! */
2081 	if(esp_print_decrypt_buffer_by_ikev2(ndo,
2082 					     base->flags & ISAKMP_FLAG_I,
2083 					     base->i_ck, base->r_ck,
2084 					     dat, dat+dlen)) {
2085 
2086 		ext = (const struct isakmp_gen *)ndo->ndo_packetp;
2087 
2088 		/* got it decrypted, print stuff inside. */
2089 		ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
2090 				phase, doi, proto, depth+1);
2091 	}
2092 #endif
2093 
2094 
2095 	/* always return NULL, because E must be at end, and NP refers
2096 	 * to what was inside.
2097 	 */
2098 	return NULL;
2099 trunc:
2100 	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2101 	return NULL;
2102 }
2103 
2104 static const u_char *
2105 ikev2_cp_print(netdissect_options *ndo, u_char tpay,
2106 		const struct isakmp_gen *ext,
2107 		u_int item_len _U_, const u_char *ep _U_,
2108 		u_int32_t phase _U_, u_int32_t doi _U_,
2109 		u_int32_t proto _U_, int depth _U_)
2110 {
2111 	return ikev2_gen_print(ndo, tpay, ext);
2112 }
2113 
2114 static const u_char *
2115 ikev2_eap_print(netdissect_options *ndo, u_char tpay,
2116 		const struct isakmp_gen *ext,
2117 		u_int item_len _U_, const u_char *ep _U_,
2118 		u_int32_t phase _U_, u_int32_t doi _U_,
2119 		u_int32_t proto _U_, int depth _U_)
2120 {
2121 	return ikev2_gen_print(ndo, tpay, ext);
2122 }
2123 
2124 static const u_char *
2125 ike_sub0_print(netdissect_options *ndo,
2126 		 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2127 
2128 	       u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
2129 {
2130 	const u_char *cp;
2131 	struct isakmp_gen e;
2132 	u_int item_len;
2133 
2134 	cp = (u_char *)ext;
2135 	ND_TCHECK(*ext);
2136 	safememcpy(&e, ext, sizeof(e));
2137 
2138 	/*
2139 	 * Since we can't have a payload length of less than 4 bytes,
2140 	 * we need to bail out here if the generic header is nonsensical
2141 	 * or truncated, otherwise we could loop forever processing
2142 	 * zero-length items or otherwise misdissect the packet.
2143 	 */
2144 	item_len = ntohs(e.len);
2145 	if (item_len <= 4)
2146 		return NULL;
2147 
2148 	if (NPFUNC(np)) {
2149 		/*
2150 		 * XXX - what if item_len is too short, or too long,
2151 		 * for this payload type?
2152 		 */
2153 		cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth);
2154 	} else {
2155 		ND_PRINT((ndo,"%s", NPSTR(np)));
2156 		cp += item_len;
2157 	}
2158 
2159 	return cp;
2160 trunc:
2161 	ND_PRINT((ndo," [|isakmp]"));
2162 	return NULL;
2163 }
2164 
2165 static const u_char *
2166 ikev1_sub_print(netdissect_options *ndo,
2167 		u_char np, const struct isakmp_gen *ext, const u_char *ep,
2168 		u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
2169 {
2170 	const u_char *cp;
2171 	int i;
2172 	struct isakmp_gen e;
2173 
2174 	cp = (const u_char *)ext;
2175 
2176 	while (np) {
2177 		ND_TCHECK(*ext);
2178 
2179 		safememcpy(&e, ext, sizeof(e));
2180 
2181 		ND_TCHECK2(*ext, ntohs(e.len));
2182 
2183 		depth++;
2184 		ND_PRINT((ndo,"\n"));
2185 		for (i = 0; i < depth; i++)
2186 			ND_PRINT((ndo,"    "));
2187 		ND_PRINT((ndo,"("));
2188 		cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth);
2189 		ND_PRINT((ndo,")"));
2190 		depth--;
2191 
2192 		if (cp == NULL) {
2193 			/* Zero-length subitem */
2194 			return NULL;
2195 		}
2196 
2197 		np = e.np;
2198 		ext = (struct isakmp_gen *)cp;
2199 	}
2200 	return cp;
2201 trunc:
2202 	ND_PRINT((ndo," [|%s]", NPSTR(np)));
2203 	return NULL;
2204 }
2205 
2206 static char *
2207 numstr(int x)
2208 {
2209 	static char buf[20];
2210 	snprintf(buf, sizeof(buf), "#%d", x);
2211 	return buf;
2212 }
2213 
2214 /*
2215  * some compiler tries to optimize memcpy(), using the alignment constraint
2216  * on the argument pointer type.  by using this function, we try to avoid the
2217  * optimization.
2218  */
2219 static void
2220 safememcpy(void *p, const void *q, size_t l)
2221 {
2222 	memcpy(p, q, l);
2223 }
2224 
2225 static void
2226 ikev1_print(netdissect_options *ndo,
2227 	    const u_char *bp,  u_int length,
2228 	    const u_char *bp2, struct isakmp *base)
2229 {
2230 	const struct isakmp *p;
2231 	const u_char *ep;
2232 	u_char np;
2233 	int i;
2234 	int phase;
2235 	uint32_t msgid;
2236 
2237 	p = (const struct isakmp *)bp;
2238 	ep = ndo->ndo_snapend;
2239 
2240 	memcpy(&msgid, base->msgid, sizeof(msgid));
2241 	phase = (msgid == 0) ? 1 : 2;
2242 	if (phase == 1)
2243 		ND_PRINT((ndo," phase %d", phase));
2244 	else
2245 		ND_PRINT((ndo," phase %d/others", phase));
2246 
2247 	i = cookie_find(&base->i_ck);
2248 	if (i < 0) {
2249 		if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) {
2250 			/* the first packet */
2251 			ND_PRINT((ndo," I"));
2252 			if (bp2)
2253 				cookie_record(&base->i_ck, bp2);
2254 		} else
2255 			ND_PRINT((ndo," ?"));
2256 	} else {
2257 		if (bp2 && cookie_isinitiator(i, bp2))
2258 			ND_PRINT((ndo," I"));
2259 		else if (bp2 && cookie_isresponder(i, bp2))
2260 			ND_PRINT((ndo," R"));
2261 		else
2262 			ND_PRINT((ndo," ?"));
2263 	}
2264 
2265 	ND_PRINT((ndo," %s", ETYPESTR(base->etype)));
2266 	if (base->flags) {
2267 		ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "",
2268 			  base->flags & ISAKMP_FLAG_C ? "C" : ""));
2269 	}
2270 
2271 	if (ndo->ndo_vflag) {
2272 		const struct isakmp_gen *ext;
2273 
2274 		ND_PRINT((ndo,":"));
2275 
2276 		/* regardless of phase... */
2277 		if (base->flags & ISAKMP_FLAG_E) {
2278 			/*
2279 			 * encrypted, nothing we can do right now.
2280 			 * we hope to decrypt the packet in the future...
2281 			 */
2282 			ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np)));
2283 			goto done;
2284 		}
2285 
2286 		CHECKLEN(p + 1, base->np);
2287 		np = base->np;
2288 		ext = (struct isakmp_gen *)(p + 1);
2289 		ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
2290 	}
2291 
2292 done:
2293 	if (ndo->ndo_vflag) {
2294 		if (ntohl(base->len) != length) {
2295 			ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)",
2296 				  (u_int32_t)ntohl(base->len), length));
2297 		}
2298 	}
2299 }
2300 
2301 static const u_char *
2302 ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
2303 		 u_char np, int pcount,
2304 		 const struct isakmp_gen *ext, const u_char *ep,
2305 		 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
2306 {
2307 	const u_char *cp;
2308 	struct isakmp_gen e;
2309 	u_int item_len;
2310 
2311 	cp = (u_char *)ext;
2312 	ND_TCHECK(*ext);
2313 	safememcpy(&e, ext, sizeof(e));
2314 
2315 	/*
2316 	 * Since we can't have a payload length of less than 4 bytes,
2317 	 * we need to bail out here if the generic header is nonsensical
2318 	 * or truncated, otherwise we could loop forever processing
2319 	 * zero-length items or otherwise misdissect the packet.
2320 	 */
2321 	item_len = ntohs(e.len);
2322 	if (item_len <= 4)
2323 		return NULL;
2324 
2325 	if(np == ISAKMP_NPTYPE_P) {
2326 		cp = ikev2_p_print(ndo, np, pcount, ext, item_len,
2327 				   ep, phase, doi, proto, depth);
2328 	} else if(np == ISAKMP_NPTYPE_T) {
2329 		cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
2330 				   ep, phase, doi, proto, depth);
2331 	} else if(np == ISAKMP_NPTYPE_v2E) {
2332 		cp = ikev2_e_print(ndo, base, np, ext, item_len,
2333 				   ep, phase, doi, proto, depth);
2334 	} else if (NPFUNC(np)) {
2335 		/*
2336 		 * XXX - what if item_len is too short, or too long,
2337 		 * for this payload type?
2338 		 */
2339 		cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len,
2340 				   ep, phase, doi, proto, depth);
2341 	} else {
2342 		ND_PRINT((ndo,"%s", NPSTR(np)));
2343 		cp += item_len;
2344 	}
2345 
2346 	return cp;
2347 trunc:
2348 	ND_PRINT((ndo," [|isakmp]"));
2349 	return NULL;
2350 }
2351 
2352 static const u_char *
2353 ikev2_sub_print(netdissect_options *ndo,
2354 		struct isakmp *base,
2355 		u_char np, const struct isakmp_gen *ext, const u_char *ep,
2356 		u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
2357 {
2358 	const u_char *cp;
2359 	int i;
2360 	int pcount;
2361 	struct isakmp_gen e;
2362 
2363 	cp = (const u_char *)ext;
2364 	pcount = 0;
2365 	while (np) {
2366 		pcount++;
2367 		ND_TCHECK(*ext);
2368 
2369 		safememcpy(&e, ext, sizeof(e));
2370 
2371 		ND_TCHECK2(*ext, ntohs(e.len));
2372 
2373 		depth++;
2374 		ND_PRINT((ndo,"\n"));
2375 		for (i = 0; i < depth; i++)
2376 			ND_PRINT((ndo,"    "));
2377 		ND_PRINT((ndo,"("));
2378 		cp = ikev2_sub0_print(ndo, base, np, pcount,
2379 				      ext, ep, phase, doi, proto, depth);
2380 		ND_PRINT((ndo,")"));
2381 		depth--;
2382 
2383 		if (cp == NULL) {
2384 			/* Zero-length subitem */
2385 			return NULL;
2386 		}
2387 
2388 		np = e.np;
2389 		ext = (struct isakmp_gen *)cp;
2390 	}
2391 	return cp;
2392 trunc:
2393 	ND_PRINT((ndo," [|%s]", NPSTR(np)));
2394 	return NULL;
2395 }
2396 
2397 static void
2398 ikev2_print(netdissect_options *ndo,
2399 	    const u_char *bp,  u_int length,
2400 	    const u_char *bp2 _U_, struct isakmp *base)
2401 {
2402 	const struct isakmp *p;
2403 	const u_char *ep;
2404 	u_char np;
2405 	int phase;
2406 	uint32_t msgid;
2407 
2408 	p = (const struct isakmp *)bp;
2409 	ep = ndo->ndo_snapend;
2410 
2411 	memcpy(&msgid, base->msgid, sizeof(msgid));
2412 	phase = (msgid == 0) ? 1 : 2;
2413 	if (phase == 1)
2414 		ND_PRINT((ndo, " parent_sa"));
2415 	else
2416 		ND_PRINT((ndo, " child_sa "));
2417 
2418 	ND_PRINT((ndo, " %s", ETYPESTR(base->etype)));
2419 	if (base->flags) {
2420 		ND_PRINT((ndo, "[%s%s%s]",
2421 			  base->flags & ISAKMP_FLAG_I ? "I" : "",
2422 			  base->flags & ISAKMP_FLAG_V ? "V" : "",
2423 			  base->flags & ISAKMP_FLAG_R ? "R" : ""));
2424 	}
2425 
2426 	if (ndo->ndo_vflag) {
2427 		const struct isakmp_gen *ext;
2428 
2429 		ND_PRINT((ndo, ":"));
2430 
2431 		/* regardless of phase... */
2432 		if (base->flags & ISAKMP_FLAG_E) {
2433 			/*
2434 			 * encrypted, nothing we can do right now.
2435 			 * we hope to decrypt the packet in the future...
2436 			 */
2437 			ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np)));
2438 			goto done;
2439 		}
2440 
2441 		CHECKLEN(p + 1, base->np)
2442 
2443 		np = base->np;
2444 		ext = (struct isakmp_gen *)(p + 1);
2445 		ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
2446 	}
2447 
2448 done:
2449 	if (ndo->ndo_vflag) {
2450 		if (ntohl(base->len) != length) {
2451 			ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)",
2452 				  (u_int32_t)ntohl(base->len), length));
2453 		}
2454 	}
2455 }
2456 
2457 void
2458 isakmp_print(netdissect_options *ndo,
2459 	     const u_char *bp, u_int length,
2460 	     const u_char *bp2)
2461 {
2462 	const struct isakmp *p;
2463 	struct isakmp base;
2464 	const u_char *ep;
2465 	int major, minor;
2466 
2467 #ifdef HAVE_LIBCRYPTO
2468 	/* initialize SAs */
2469 	if (ndo->ndo_sa_list_head == NULL) {
2470 		if (ndo->ndo_espsecret)
2471 			esp_print_decodesecret(ndo);
2472 	}
2473 #endif
2474 
2475 	p = (const struct isakmp *)bp;
2476 	ep = ndo->ndo_snapend;
2477 
2478 	if ((struct isakmp *)ep < p + 1) {
2479 		ND_PRINT((ndo,"[|isakmp]"));
2480 		return;
2481 	}
2482 
2483 	safememcpy(&base, p, sizeof(base));
2484 
2485 	ND_PRINT((ndo,"isakmp"));
2486 	major = (base.vers & ISAKMP_VERS_MAJOR)
2487 		>> ISAKMP_VERS_MAJOR_SHIFT;
2488 	minor = (base.vers & ISAKMP_VERS_MINOR)
2489 		>> ISAKMP_VERS_MINOR_SHIFT;
2490 
2491 	if (ndo->ndo_vflag) {
2492 		ND_PRINT((ndo," %d.%d", major, minor));
2493 	}
2494 
2495 	if (ndo->ndo_vflag) {
2496 		ND_PRINT((ndo," msgid "));
2497 		hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
2498 	}
2499 
2500 	if (1 < ndo->ndo_vflag) {
2501 		ND_PRINT((ndo," cookie "));
2502 		hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
2503 		ND_PRINT((ndo,"->"));
2504 		hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
2505 	}
2506 	ND_PRINT((ndo,":"));
2507 
2508 	switch(major) {
2509 	case IKEv1_MAJOR_VERSION:
2510 		ikev1_print(ndo, bp, length, bp2, &base);
2511 		break;
2512 
2513 	case IKEv2_MAJOR_VERSION:
2514 		ikev2_print(ndo, bp, length, bp2, &base);
2515 		break;
2516 	}
2517 }
2518 
2519 void
2520 isakmp_rfc3948_print(netdissect_options *ndo,
2521 		     const u_char *bp, u_int length,
2522 		     const u_char *bp2)
2523 {
2524 	if(length == 1 && bp[0]==0xff) {
2525 		ND_PRINT((ndo, "isakmp-nat-keep-alive"));
2526 		return;
2527 	}
2528 
2529 	if(length < 4) {
2530 		goto trunc;
2531 	}
2532 
2533 	/*
2534 	 * see if this is an IKE packet
2535 	 */
2536 	if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) {
2537 		ND_PRINT((ndo, "NONESP-encap: "));
2538 		isakmp_print(ndo, bp+4, length-4, bp2);
2539 		return;
2540 	}
2541 
2542 	/* must be an ESP packet */
2543 	{
2544 		int nh, enh, padlen;
2545 		int advance;
2546 
2547 		ND_PRINT((ndo, "UDP-encap: "));
2548 
2549 		advance = esp_print(ndo, bp, length, bp2, &enh, &padlen);
2550 		if(advance <= 0)
2551 			return;
2552 
2553 		bp += advance;
2554 		length -= advance + padlen;
2555 		nh = enh & 0xff;
2556 
2557 		ip_print_inner(ndo, bp, length, nh, bp2);
2558 		return;
2559 	}
2560 
2561 trunc:
2562 	ND_PRINT((ndo,"[|isakmp]"));
2563 	return;
2564 }
2565 
2566 /*
2567  * Local Variables:
2568  * c-style: whitesmith
2569  * c-basic-offset: 8
2570  * End:
2571  */
2572 
2573 
2574 
2575 
2576