]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-isakmp.c
Merge pull request #4 from infrastation/master
[tcpdump] / print-isakmp.c
index 36d69c0dbf0b033eee8c086d67136d602f1fcf42..4f96afe38115032fc2b753261e055c5d2d1c1db1 100644 (file)
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.55 2007-08-29 02:58:43 mcr Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)";
 #endif
 
+#define NETDISSECT_REWORKED
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -93,16 +94,27 @@ DECLARE_PRINTER(v2_n);
 DECLARE_PRINTER(v2_d);
 DECLARE_PRINTER(v2_vid);
 DECLARE_PRINTER(v2_TS);
-DECLARE_PRINTER(v2_e);
 DECLARE_PRINTER(v2_cp);
 DECLARE_PRINTER(v2_eap);
 
+static const u_char *ikev2_e_print(netdissect_options *ndo,
+                                  struct isakmp *base,
+                                  u_char tpay,
+                                  const struct isakmp_gen *ext,
+                                  u_int item_len,      
+                                  const u_char *end_pointer, 
+                                  u_int32_t phase,
+                                  u_int32_t doi0, 
+                                  u_int32_t proto0, int depth);
+
+
 static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
        const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
 static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
        const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
 
 static const u_char *ikev2_sub_print(netdissect_options *ndo,
+                                    struct isakmp *base,
                                     u_char np, const struct isakmp_gen *ext,
                                     const u_char *ep, u_int32_t phase,
                                     u_int32_t doi, u_int32_t proto,
@@ -184,7 +196,7 @@ static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
        ikev2_vid_print,                /* 43 */
        ikev2_TS_print,                 /* 44 */
        ikev2_TS_print,                 /* 45 */
-       ikev2_e_print,                  /* 46 */
+       NULL, /* ikev2_e_print,*/       /* 46 - special */
        ikev2_cp_print,                 /* 47 */
        ikev2_eap_print,                /* 48 */
 };
@@ -390,22 +402,29 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator)
        return 0;
 }
 
-static int
-rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
+static void
+hexprint(netdissect_options *ndo, caddr_t loc, size_t len)
 {
-       static u_char *p;
+       u_char *p;
        size_t i;
 
-       TCHECK2(*loc, len);
-       
        p = (u_char *)loc;
        for (i = 0; i < len; i++)
                ND_PRINT((ndo,"%02x", p[i] & 0xff));
+}
+
+static int
+rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
+{
+       ND_TCHECK2(*loc, len);
+
+       hexprint(ndo, loc, len);
        return 1;
 trunc:
        return 0;
 }
 
+
 /*
  * returns false if we run out of data buffer
  */
@@ -534,7 +553,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));
 
        p = (struct ikev1_pl_sa *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&sa, ext, sizeof(sa));
        doi = ntohl(sa.doi);
        sit = ntohl(sa.sit);
@@ -561,14 +580,14 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
 
        np = (u_char *)ext + sizeof(sa);
        if (sit != 0x01) {
-               TCHECK2(*(ext + 1), sizeof(ident));
+               ND_TCHECK2(*(ext + 1), sizeof(ident));
                safememcpy(&ident, ext + 1, sizeof(ident));
                ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident)));
                np += sizeof(ident);
        }
 
        ext = (struct isakmp_gen *)np;
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
 
        cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
                depth);
@@ -592,7 +611,7 @@ ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));
 
        p = (struct ikev1_pl_p *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&prop, ext, sizeof(prop));
        ND_PRINT((ndo," #%d protoid=%s transform=%d",
                  prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
@@ -603,7 +622,7 @@ ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
        }
 
        ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        
        cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
                             prop.prot_id, depth);
@@ -759,7 +778,7 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T)));
 
        p = (struct ikev1_pl_t *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&t, ext, sizeof(t));
 
        switch (proto) {
@@ -821,10 +840,10 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
 
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
-       if (2 < vflag && 4 < ntohs(e.len)) {
+       if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -858,7 +877,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID)));
 
        p = (struct ikev1_pl_id *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&id, ext, sizeof(id));
        if (sizeof(*p) < item_len) {
                data = (u_char *)(p + 1);
@@ -891,7 +910,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
                struct protoent *pe;
 
                p = (struct ipsecdoi_id *)ext;
-               TCHECK(*p);
+               ND_TCHECK(*p);
                safememcpy(&id, ext, sizeof(id));
                ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)));
                if (id.proto_id) {
@@ -913,7 +932,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
                        break;
                if (data == NULL)
                        goto trunc;
-               TCHECK2(*data, len);
+               ND_TCHECK2(*data, len);
                switch (id.type) {
                case IPSECDOI_ID_IPV4_ADDR:
                        if (len < 4)
@@ -1002,7 +1021,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
        }
        if (data && len) {
                ND_PRINT((ndo," len=%d", len));
-               if (2 < vflag) {
+               if (2 < ndo->ndo_vflag) {
                        ND_PRINT((ndo," "));
                        if (!rawprint(ndo, (caddr_t)data, len))
                                goto trunc;
@@ -1032,11 +1051,11 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT)));
 
        p = (struct ikev1_pl_cert *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&cert, ext, sizeof(cert));
        ND_PRINT((ndo," len=%d", item_len - 4));
        ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
-       if (2 < vflag && 4 < item_len) {
+       if (2 < ndo->ndo_vflag && 4 < item_len) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
                        goto trunc;
@@ -1064,11 +1083,11 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR)));
 
        p = (struct ikev1_pl_cert *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&cert, ext, sizeof(cert));
        ND_PRINT((ndo," len=%d", item_len - 4));
        ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
-       if (2 < vflag && 4 < item_len) {
+       if (2 < ndo->ndo_vflag && 4 < item_len) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
                        goto trunc;
@@ -1089,10 +1108,10 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
 
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
-       if (2 < vflag && 4 < ntohs(e.len)) {
+       if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1113,10 +1132,10 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
 
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
-       if (2 < vflag && 4 < ntohs(e.len)) {
+       if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1139,14 +1158,14 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
 
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
-       if (2 < vflag && 4 < ntohs(e.len)) {
+       if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
-       } else if (1 < vflag && 4 < ntohs(e.len)) {
+       } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep))
                        goto trunc;
@@ -1217,7 +1236,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N)));
 
        p = (struct ikev1_pl_n *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&n, ext, sizeof(n));
        doi = ntohl(n.doi);
        proto = n.prot_id;
@@ -1286,7 +1305,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
                        break;
                default:
                        /* NULL is dummy */
-                       isakmp_print(gndo, cp,
+                       isakmp_print(ndo, cp,
                                     item_len - sizeof(*p) - n.spi_size,
                                     NULL);
                }
@@ -1314,7 +1333,7 @@ ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D)));
 
        p = (struct ikev1_pl_d *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&d, ext, sizeof(d));
        doi = ntohl(d.doi);
        proto = d.prot_id;
@@ -1353,10 +1372,10 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
 
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
-       if (2 < vflag && 4 < ntohs(e.len)) {
+       if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1385,12 +1404,12 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
 {
        struct isakmp_gen e;
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
 
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
-       if (2 < vflag && 4 < ntohs(e.len)) {
+       if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1417,7 +1436,7 @@ ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
        const u_char *ep2;
 
        p = (struct ikev2_t *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&t, ext, sizeof(t));
        ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
 
@@ -1490,12 +1509,13 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
        const u_char *cp;
 
        p = (struct ikev2_p *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&prop, ext, sizeof(prop));
        ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
 
-       ND_PRINT((ndo," #%u protoid=%s transform=%d",
-                 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
+       ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
+                 prop.p_no,  PROTOIDSTR(prop.prot_id),
+                 prop.num_t, ntohs(prop.h.len)));
        if (prop.spi_size) {
                ND_PRINT((ndo," spi="));
                if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
@@ -1503,9 +1523,9 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
        }
 
        ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
-       TCHECK(*ext);
-       
-       cp = ikev2_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
+       ND_TCHECK(*ext);
+
+       cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
                             prop.prot_id, depth);
        
        return cp;
@@ -1522,21 +1542,21 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
                u_int32_t proto _U_, int depth _U_)
 {
        struct isakmp_gen e;
-       int    osa_len, sa_len;
+       int    osa_length, sa_length;
 
-       TCHECK(*ext1);
+       ND_TCHECK(*ext1);
        safememcpy(&e, ext1, sizeof(e));
        ikev2_pay_print(ndo, "sa", e.critical);
 
-       osa_len= ntohs(e.len);
-       sa_len = osa_len - 4;
-       ND_PRINT((ndo," len=%d", sa_len));
+       osa_length= ntohs(e.len);
+       sa_length = osa_length - 4;
+       ND_PRINT((ndo," len=%d", sa_length));
 
-       ikev2_sub_print(ndo, ISAKMP_NPTYPE_P,
+       ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
                        ext1+1, ep,
                        0, 0, 0, depth);
 
-       return (u_char *)ext1 + osa_len;
+       return (u_char *)ext1 + osa_length;
 trunc:
        ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
        return NULL;
@@ -1553,14 +1573,14 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
        struct ikev2_ke *k;
 
        k = (struct ikev2_ke *)ext;
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&ke, ext, sizeof(ke));
        ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
 
        ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
                  STR_OR_ID(ntohs(ke.ke_group), dh_p_map)));
                 
-       if (2 < vflag && 8 < ntohs(ke.h.len)) {
+       if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8))
                        goto trunc;
@@ -1578,7 +1598,79 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
                u_int32_t phase _U_, u_int32_t doi _U_,
                u_int32_t proto _U_, int depth _U_)
 {
-       return ikev2_gen_print(ndo, tpay, ext);
+       struct ikev2_id id;
+       int id_len, idtype_len, i;
+       unsigned int dumpascii, dumphex;
+       unsigned char *typedata;
+
+       ND_TCHECK(*ext);
+       safememcpy(&id, ext, sizeof(id));
+       ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
+
+       id_len = ntohs(id.h.len);
+
+       ND_PRINT((ndo," len=%d", id_len - 4));
+       if (2 < ndo->ndo_vflag && 4 < id_len) {
+               ND_PRINT((ndo," "));
+               if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4))
+                       goto trunc;
+       }
+
+       idtype_len =id_len - sizeof(struct ikev2_id);
+       dumpascii = 0;
+       dumphex   = 0;
+       typedata  = (unsigned char *)(ext)+sizeof(struct ikev2_id);
+
+       switch(id.type) {
+       case ID_IPV4_ADDR:
+               ND_PRINT((ndo, " ipv4:"));
+               dumphex=1;
+               break;
+       case ID_FQDN:
+               ND_PRINT((ndo, " fqdn:"));
+               dumpascii=1;
+               break;
+       case ID_RFC822_ADDR:
+               ND_PRINT((ndo, " rfc822:"));
+               dumpascii=1;
+               break;
+       case ID_IPV6_ADDR:
+               ND_PRINT((ndo, " ipv6:"));
+               dumphex=1;
+               break;
+       case ID_DER_ASN1_DN:
+               ND_PRINT((ndo, " dn:"));
+               dumphex=1;
+               break;
+       case ID_DER_ASN1_GN:
+               ND_PRINT((ndo, " gn:"));
+               dumphex=1;
+               break;
+       case ID_KEY_ID:
+               ND_PRINT((ndo, " keyid:"));
+               dumphex=1;
+               break;
+       }
+
+       if(dumpascii) {
+               ND_TCHECK2(*typedata, idtype_len);
+               for(i=0; i<idtype_len; i++) {
+                       if(isprint(typedata[i])) {
+                               ND_PRINT((ndo, "%c", typedata[i]));
+                       } else {
+                               ND_PRINT((ndo, "."));
+                       }
+               }
+       }
+       if(dumphex) {
+               if (!rawprint(ndo, (caddr_t)typedata, idtype_len))
+                       goto trunc;
+       }
+
+       return (u_char *)ext + id_len;
+trunc:
+       ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+       return NULL;
 }
 
 static const u_char *
@@ -1608,27 +1700,30 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
                u_int32_t phase _U_, u_int32_t doi _U_,
                u_int32_t proto _U_, int depth _U_)
 {
-       struct ikev2_auth e;
+       struct ikev2_auth a;
        const char *v2_auth[]={ "invalid", "rsasig",
                                "shared-secret", "dsssig" };
+       u_char *authdata = (u_char*)ext + sizeof(a);
+       unsigned int len;
 
-       TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
-       ikev2_pay_print(ndo, NPSTR(tpay), e.h.critical);
+       ND_TCHECK(*ext);
+       safememcpy(&a, ext, sizeof(a));
+       ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
+       len = ntohs(a.h.len);
 
-       ND_PRINT((ndo," len=%d method=%s", ntohs(e.h.len) - 4, 
-                 STR_OR_ID(e.auth_method, v2_auth)));
+       ND_PRINT((ndo," len=%d method=%s", len-4, 
+                 STR_OR_ID(a.auth_method, v2_auth)));
 
-       if (1 < ndo->ndo_vflag && 4 < ntohs(e.h.len)) {
+       if (1 < ndo->ndo_vflag && 4 < len) {
                ND_PRINT((ndo," authdata=("));
-               if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.h.len) - 4))
+               if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a)))
                        goto trunc;
                ND_PRINT((ndo,") "));
-       } else if(ndo->ndo_vflag && 4 < ntohs(e.h.len)) {
-               if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
+       } else if(ndo->ndo_vflag && 4 < len) {
+               if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
        }
 
-       return (u_char *)ext + ntohs(e.h.len);
+       return (u_char *)ext + len;
 trunc:
        ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
        return NULL;
@@ -1643,7 +1738,7 @@ ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
 {
        struct isakmp_gen e;
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, "nonce", e.critical);
 
@@ -1679,7 +1774,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
        u_int32_t type;
 
        p = (struct ikev2_n *)ext;
-       TCHECK(*p);
+       ND_TCHECK(*p);
        safememcpy(&n, ext, sizeof(n));
        ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
 
@@ -1894,19 +1989,19 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
        const u_char *vid;
        int i, len;
 
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
        ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
        
        vid = (const u_char *)(ext+1);
        len = ntohs(e.len) - 4;
-       TCHECK2(*vid, len);
+       ND_TCHECK2(*vid, len);
        for(i=0; i<len; i++) {
                if(isprint(vid[i])) ND_PRINT((ndo, "%c", vid[i]));
-               else ND_PRINT((ndo, ".", vid[i]));
+               else ND_PRINT((ndo, "."));
        }
-       if (2 < vflag && 4 < len) {
+       if (2 < ndo->ndo_vflag && 4 < len) {
                ND_PRINT((ndo," "));
                if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
                        goto trunc;
@@ -1928,13 +2023,74 @@ ikev2_TS_print(netdissect_options *ndo, u_char tpay,
 }
 
 static const u_char *
-ikev2_e_print(netdissect_options *ndo, u_char tpay, 
-               const struct isakmp_gen *ext,
-               u_int item_len _U_, const u_char *ep _U_,
-               u_int32_t phase _U_, u_int32_t doi _U_,
-               u_int32_t proto _U_, int depth _U_)
+ikev2_e_print(netdissect_options *ndo,
+#ifndef HAVE_LIBCRYPTO
+             _U_
+#endif
+             struct isakmp *base,
+             u_char tpay, 
+             const struct isakmp_gen *ext,
+             u_int item_len _U_, const u_char *ep _U_,
+#ifndef HAVE_LIBCRYPTO
+             _U_
+#endif
+             u_int32_t phase,
+#ifndef HAVE_LIBCRYPTO
+             _U_
+#endif
+             u_int32_t doi,
+#ifndef HAVE_LIBCRYPTO
+             _U_
+#endif
+             u_int32_t proto,
+#ifndef HAVE_LIBCRYPTO
+             _U_
+#endif
+             int depth)
 {
-       return ikev2_gen_print(ndo, tpay, ext);
+       struct isakmp_gen e;
+       u_char *dat;
+       volatile int dlen;
+
+       ND_TCHECK(*ext);
+       safememcpy(&e, ext, sizeof(e));
+       ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
+
+       dlen = ntohs(e.len)-4;
+
+       ND_PRINT((ndo," len=%d", dlen));
+       if (2 < ndo->ndo_vflag && 4 < dlen) {
+               ND_PRINT((ndo," "));
+               if (!rawprint(ndo, (caddr_t)(ext + 1), dlen))
+                       goto trunc;
+       }
+
+       dat = (u_char *)(ext+1);
+       ND_TCHECK2(*dat, dlen);
+       
+#ifdef HAVE_LIBCRYPTO
+       /* try to decypt it! */
+       if(esp_print_decrypt_buffer_by_ikev2(ndo,
+                                            base->flags & ISAKMP_FLAG_I,
+                                            base->i_ck, base->r_ck,
+                                            dat, dat+dlen)) {
+               
+               ext = (const struct isakmp_gen *)ndo->ndo_packetp;
+
+               /* got it decrypted, print stuff inside. */
+               ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
+                               phase, doi, proto, depth+1);
+       }
+#endif
+       
+
+       /* always return NULL, because E must be at end, and NP refers
+        * to what was inside.
+        */
+       return NULL;
+trunc:
+       ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+       return NULL;
 }
 
 static const u_char *
@@ -1960,14 +2116,15 @@ ikev2_eap_print(netdissect_options *ndo, u_char tpay,
 static const u_char *
 ike_sub0_print(netdissect_options *ndo,
                 u_char np, const struct isakmp_gen *ext, const u_char *ep,
-                u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
+
+              u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
 {
        const u_char *cp;
        struct isakmp_gen e;
        u_int item_len;
 
        cp = (u_char *)ext;
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
 
        /*
@@ -2009,11 +2166,11 @@ ikev1_sub_print(netdissect_options *ndo,
        cp = (const u_char *)ext;
 
        while (np) {
-               TCHECK(*ext);
+               ND_TCHECK(*ext);
                
                safememcpy(&e, ext, sizeof(e));
 
-               TCHECK2(*ext, ntohs(e.len));
+               ND_TCHECK2(*ext, ntohs(e.len));
 
                depth++;
                ND_PRINT((ndo,"\n"));
@@ -2057,7 +2214,7 @@ safememcpy(void *p, const void *q, size_t l)
        memcpy(p, q, l);
 }
 
-void
+static void
 ikev1_print(netdissect_options *ndo,
            const u_char *bp,  u_int length,
            const u_char *bp2, struct isakmp *base)
@@ -2101,7 +2258,7 @@ ikev1_print(netdissect_options *ndo,
                          base->flags & ISAKMP_FLAG_C ? "C" : ""));
        }
        
-       if (vflag) {
+       if (ndo->ndo_vflag) {
                const struct isakmp_gen *ext;
                int nparen;
                
@@ -2125,7 +2282,7 @@ ikev1_print(netdissect_options *ndo,
        }
        
 done:
-       if (vflag) {
+       if (ndo->ndo_vflag) {
                if (ntohl(base->len) != length) {
                        ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)",
                                  (u_int32_t)ntohl(base->len), length));
@@ -2134,7 +2291,8 @@ done:
 }
 
 static const u_char *
-ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount,
+ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
+                u_char np, int pcount,
                 const struct isakmp_gen *ext, const u_char *ep,
                 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
 {
@@ -2143,7 +2301,7 @@ ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount,
        u_int item_len;
 
        cp = (u_char *)ext;
-       TCHECK(*ext);
+       ND_TCHECK(*ext);
        safememcpy(&e, ext, sizeof(e));
 
        /*
@@ -2162,6 +2320,9 @@ ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount,
        } else if(np == ISAKMP_NPTYPE_T) {
                cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
                                   ep, phase, doi, proto, depth);
+       } else if(np == ISAKMP_NPTYPE_v2E) {
+               cp = ikev2_e_print(ndo, base, np, ext, item_len,
+                                  ep, phase, doi, proto, depth);
        } else if (NPFUNC(np)) {
                /*
                 * XXX - what if item_len is too short, or too long,
@@ -2182,6 +2343,7 @@ trunc:
 
 static const u_char *
 ikev2_sub_print(netdissect_options *ndo,
+               struct isakmp *base,
                u_char np, const struct isakmp_gen *ext, const u_char *ep,
                u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
 {
@@ -2194,18 +2356,18 @@ ikev2_sub_print(netdissect_options *ndo,
        pcount = 0;                                             
        while (np) {
                pcount++;
-               TCHECK(*ext);
+               ND_TCHECK(*ext);
                
                safememcpy(&e, ext, sizeof(e));
 
-               TCHECK2(*ext, ntohs(e.len));
+               ND_TCHECK2(*ext, ntohs(e.len));
 
                depth++;
                ND_PRINT((ndo,"\n"));
                for (i = 0; i < depth; i++)
                        ND_PRINT((ndo,"    "));
                ND_PRINT((ndo,"("));
-               cp = ikev2_sub0_print(ndo, np, pcount,
+               cp = ikev2_sub0_print(ndo, base, np, pcount,
                                      ext, ep, phase, doi, proto, depth);
                ND_PRINT((ndo,")"));
                depth--;
@@ -2245,7 +2407,7 @@ ikev2_print(netdissect_options *ndo,
 
        ND_PRINT((ndo, " %s", ETYPESTR(base->etype)));
        if (base->flags) {
-               ND_PRINT((ndo, "[%s%s]",
+               ND_PRINT((ndo, "[%s%s%s]",
                          base->flags & ISAKMP_FLAG_I ? "I" : "",
                          base->flags & ISAKMP_FLAG_V ? "V" : "",
                          base->flags & ISAKMP_FLAG_R ? "R" : ""));
@@ -2272,7 +2434,7 @@ ikev2_print(netdissect_options *ndo,
 
                np = base->np;
                ext = (struct isakmp_gen *)(p + 1);
-               ikev2_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
+               ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
        }
 
 done:
@@ -2294,6 +2456,14 @@ isakmp_print(netdissect_options *ndo,
        const u_char *ep;
        int major, minor;
 
+#ifdef HAVE_LIBCRYPTO
+       /* initialize SAs */
+       if (ndo->ndo_sa_list_head == NULL) {
+               if (ndo->ndo_espsecret)
+                       esp_print_decodesecret(ndo);
+       }
+#endif
+
        p = (const struct isakmp *)bp;
        ep = ndo->ndo_snapend;
 
@@ -2316,14 +2486,14 @@ isakmp_print(netdissect_options *ndo,
 
        if (ndo->ndo_vflag) {
                ND_PRINT((ndo," msgid "));
-               rawprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
+               hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
        }
 
        if (1 < ndo->ndo_vflag) {
                ND_PRINT((ndo," cookie "));
-               rawprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
+               hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
                ND_PRINT((ndo,"->"));
-               rawprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
+               hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
        }
        ND_PRINT((ndo,":"));