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