source: rtems-libbsd/freebsd/contrib/tcpdump/print-isakmp.c @ 8440506

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on 06/15/15 at 07:42:23

Add tcpdump and libpcap.

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