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