Merge branch 'vendor/TCPDUMP'
[dragonfly.git] / contrib / tcpdump / print-isakmp.c
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