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