X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/dc0208fc9837a247b47be0eb00c8bfb859119b98..01fe0ebe27b2fe957f699ffa4dbdedc46e12f85b:/print-isakmp.c diff --git a/print-isakmp.c b/print-isakmp.c index 163f3262..3db9ec41 100644 --- a/print-isakmp.c +++ b/print-isakmp.c @@ -30,7 +30,7 @@ #ifndef lint static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.43 2004-01-23 09:35:41 guy Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.51 2005-04-07 00:28:17 mcr Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -60,31 +60,31 @@ static const char rcsid[] _U_ = #endif static const u_char *isakmp_sa_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_p_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_t_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_ke_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_id_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_cert_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_cr_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_sig_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_hash_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_nonce_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_n_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_d_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_vid_print(const struct isakmp_gen *, - const u_char *, u_int32_t, u_int32_t, u_int32_t, int); + u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_sub0_print(u_char, const struct isakmp_gen *, const u_char *, u_int32_t, u_int32_t, u_int32_t, int); static const u_char *isakmp_sub_print(u_char, const struct isakmp_gen *, @@ -112,8 +112,8 @@ static const char *npstr[] = { }; /* isakmp->np */ -static const u_char *(*npfunc[])(const struct isakmp_gen *, const u_char *, - u_int32_t, u_int32_t, u_int32_t, int) = { +static const u_char *(*npfunc[])(const struct isakmp_gen *, u_int, + const u_char *, u_int32_t, u_int32_t, u_int32_t, int) = { NULL, isakmp_sa_print, isakmp_p_print, @@ -321,7 +321,7 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator) return 0; } -static void +static int rawprint(caddr_t loc, size_t len) { static u_char *p; @@ -332,8 +332,9 @@ rawprint(caddr_t loc, size_t len) p = (u_char *)loc; for (i = 0; i < len; i++) printf("%02x", p[i] & 0xff); + return 1; trunc: - + return 0; } struct attrmap { @@ -414,8 +415,10 @@ isakmp_attr_print(const u_char *p, const u_char *ep) } static const u_char * -isakmp_sa_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, - u_int32_t doi0 _U_, u_int32_t proto0, int depth) +isakmp_sa_print(const struct isakmp_gen *ext, + u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0, int depth) { const struct isakmp_pl_sa *p; struct isakmp_pl_sa sa; @@ -427,6 +430,7 @@ isakmp_sa_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); p = (struct isakmp_pl_sa *)ext; + TCHECK(*p); safememcpy(&sa, ext, sizeof(sa)); doi = ntohl(sa.doi); sit = ntohl(sa.sit); @@ -453,22 +457,28 @@ isakmp_sa_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, np = (u_char *)ext + sizeof(sa); if (sit != 0x01) { + TCHECK2(*(ext + 1), sizeof(ident)); safememcpy(&ident, ext + 1, sizeof(ident)); printf(" ident=%u", (u_int32_t)ntohl(ident)); np += sizeof(ident); } ext = (struct isakmp_gen *)np; + TCHECK(*ext); cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, depth); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA)); + return NULL; } static const u_char * -isakmp_p_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, - u_int32_t doi0, u_int32_t proto0 _U_, int depth) +isakmp_p_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep, u_int32_t phase, u_int32_t doi0, + u_int32_t proto0 _U_, int depth) { const struct isakmp_pl_p *p; struct isakmp_pl_p prop; @@ -477,20 +487,26 @@ isakmp_p_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); p = (struct isakmp_pl_p *)ext; + TCHECK(*p); safememcpy(&prop, ext, sizeof(prop)); printf(" #%d protoid=%s transform=%d", prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t); if (prop.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), prop.spi_size); + if (!rawprint((caddr_t)(p + 1), prop.spi_size)) + goto trunc; } ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); + TCHECK(*ext); cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, prop.prot_id, depth); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P)); + return NULL; } static const char *isakmp_p_map[] = { @@ -550,9 +566,9 @@ const struct attrmap oakley_t_map[] = { }; static const u_char * -isakmp_t_print(const struct isakmp_gen *ext, const u_char *ep, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto, - int depth _U_) +isakmp_t_print(const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, + u_int32_t proto, int depth _U_) { const struct isakmp_pl_t *p; struct isakmp_pl_t t; @@ -565,6 +581,7 @@ isakmp_t_print(const struct isakmp_gen *ext, const u_char *ep, printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); p = (struct isakmp_pl_t *)ext; + TCHECK(*p); safememcpy(&t, ext, sizeof(t)); switch (proto) { @@ -600,7 +617,7 @@ isakmp_t_print(const struct isakmp_gen *ext, const u_char *ep, else printf(" #%d id=%d ", t.t_no, t.t_id); cp = (u_char *)(p + 1); - ep2 = (u_char *)p + ntohs(t.h.len); + ep2 = (u_char *)p + item_len; while (cp < ep && cp < ep2) { if (map && nmap) { cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2, @@ -611,30 +628,38 @@ isakmp_t_print(const struct isakmp_gen *ext, const u_char *ep, if (ep < ep2) printf("..."); return cp; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T)); + return NULL; } static const u_char * -isakmp_ke_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_ke_print(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_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_KE)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" key len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE)); + return NULL; } static const u_char * -isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_id_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_, + u_int32_t proto _U_, int depth _U_) { #define USE_IPSECDOI_IN_PHASE1 1 const struct isakmp_pl_id *p; @@ -653,12 +678,15 @@ isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); p = (struct isakmp_pl_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); - if (sizeof(*p) < id.h.len) + if (sizeof(*p) < item_len) { data = (u_char *)(p + 1); - else + len = item_len - sizeof(*p); + } else { data = NULL; - len = ntohs(id.h.len) - sizeof(*p); + len = 0; + } #if 0 /*debug*/ printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto); @@ -683,6 +711,7 @@ isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, struct protoent *pe; p = (struct ipsecdoi_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)); if (id.proto_id) { @@ -702,9 +731,15 @@ isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, printf(" port=%d", ntohs(id.port)); if (!len) break; + if (data == NULL) + goto trunc; + TCHECK2(*data, len); switch (id.type) { case IPSECDOI_ID_IPV4_ADDR: - printf(" len=%d %s", len, ipaddr_string(data)); + if (len < 4) + printf(" len=%d [bad: < 4]", len); + else + printf(" len=%d %s", len, ipaddr_string(data)); len = 0; break; case IPSECDOI_ID_FQDN: @@ -720,39 +755,60 @@ isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, case IPSECDOI_ID_IPV4_ADDR_SUBNET: { const u_char *mask; - mask = data + sizeof(struct in_addr); - printf(" len=%d %s/%u.%u.%u.%u", len, - ipaddr_string(data), - mask[0], mask[1], mask[2], mask[3]); + if (len < 8) + printf(" len=%d [bad: < 8]", len); + else { + mask = data + sizeof(struct in_addr); + printf(" len=%d %s/%u.%u.%u.%u", len, + ipaddr_string(data), + mask[0], mask[1], mask[2], mask[3]); + } len = 0; break; } #ifdef INET6 case IPSECDOI_ID_IPV6_ADDR: - printf(" len=%d %s", len, ip6addr_string(data)); + if (len < 16) + printf(" len=%d [bad: < 16]", len); + else + printf(" len=%d %s", len, ip6addr_string(data)); len = 0; break; case IPSECDOI_ID_IPV6_ADDR_SUBNET: { const u_int32_t *mask; - mask = (u_int32_t *)(data + sizeof(struct in6_addr)); - /*XXX*/ - printf(" len=%d %s/0x%08x%08x%08x%08x", len, - ip6addr_string(data), - mask[0], mask[1], mask[2], mask[3]); + if (len < 20) + printf(" len=%d [bad: < 20]", len); + else { + mask = (u_int32_t *)(data + sizeof(struct in6_addr)); + /*XXX*/ + printf(" len=%d %s/0x%08x%08x%08x%08x", len, + ip6addr_string(data), + mask[0], mask[1], mask[2], mask[3]); + } len = 0; break; } #endif /*INET6*/ case IPSECDOI_ID_IPV4_ADDR_RANGE: - printf(" len=%d %s-%s", len, ipaddr_string(data), - ipaddr_string(data + sizeof(struct in_addr))); + if (len < 8) + printf(" len=%d [bad: < 8]", len); + else { + printf(" len=%d %s-%s", len, + ipaddr_string(data), + ipaddr_string(data + sizeof(struct in_addr))); + } len = 0; break; #ifdef INET6 case IPSECDOI_ID_IPV6_ADDR_RANGE: - printf(" len=%d %s-%s", len, ip6addr_string(data), - ip6addr_string(data + sizeof(struct in6_addr))); + if (len < 32) + printf(" len=%d [bad: < 32]", len); + else { + printf(" len=%d %s-%s", len, + ip6addr_string(data), + ip6addr_string(data + sizeof(struct in6_addr))); + } len = 0; break; #endif /*INET6*/ @@ -768,16 +824,21 @@ isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_, printf(" len=%d", len); if (2 < vflag) { printf(" "); - rawprint((caddr_t)data, len); + if (!rawprint((caddr_t)data, len)) + goto trunc; } } - return (u_char *)ext + ntohs(id.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID)); + return NULL; } static const u_char * -isakmp_cert_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_, - int depth _U_) +isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, + u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) { const struct isakmp_pl_cert *p; struct isakmp_pl_cert cert; @@ -790,20 +851,25 @@ isakmp_cert_print(const struct isakmp_gen *ext, const u_char *ep _U_, printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); - printf(" len=%d", ntohs(cert.h.len) - 4); + printf(" len=%d", item_len - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); - if (2 < vflag && 4 < ntohs(cert.h.len)) { + if (2 < vflag && 4 < item_len) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); + if (!rawprint((caddr_t)(ext + 1), item_len - 4)) + goto trunc; } - return (u_char *)ext + ntohs(cert.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)); + return NULL; } static const u_char * -isakmp_cr_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_, - int depth _U_) +isakmp_cr_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) { const struct isakmp_pl_cert *p; struct isakmp_pl_cert cert; @@ -816,73 +882,96 @@ isakmp_cr_print(const struct isakmp_gen *ext, const u_char *ep _U_, printf("%s:", NPSTR(ISAKMP_NPTYPE_CR)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); - printf(" len=%d", ntohs(cert.h.len) - 4); + printf(" len=%d", item_len - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); - if (2 < vflag && 4 < ntohs(cert.h.len)) { + if (2 < vflag && 4 < item_len) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); + if (!rawprint((caddr_t)(ext + 1), item_len - 4)) + goto trunc; } - return (u_char *)ext + ntohs(cert.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR)); + return NULL; } static const u_char * -isakmp_hash_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_hash_print(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_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)); + return NULL; } static const u_char * -isakmp_sig_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_sig_print(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_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)); + return NULL; } static const u_char * -isakmp_nonce_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_nonce_print(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_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" n len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)); + return NULL; } static const u_char * -isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, - u_int32_t doi0 _U_, u_int32_t proto0 _U_, int depth) +isakmp_n_print(const struct isakmp_gen *ext, u_int item_len, + const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth) { struct isakmp_pl_n *p, n; const u_char *cp; @@ -938,6 +1027,7 @@ isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, printf("%s:", NPSTR(ISAKMP_NPTYPE_N)); p = (struct isakmp_pl_n *)ext; + TCHECK(*p); safememcpy(&n, ext, sizeof(n)); doi = ntohl(n.doi); proto = n.prot_id; @@ -954,7 +1044,8 @@ isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, printf(" type=%s", numstr(ntohs(n.type))); if (n.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), n.spi_size); + if (!rawprint((caddr_t)(p + 1), n.spi_size)) + goto trunc; } return (u_char *)(p + 1) + n.spi_size; } @@ -973,11 +1064,12 @@ isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, printf(" type=%s", numstr(ntohs(n.type))); if (n.spi_size) { printf(" spi="); - rawprint((caddr_t)(p + 1), n.spi_size); + if (!rawprint((caddr_t)(p + 1), n.spi_size)) + goto trunc; } cp = (u_char *)(p + 1) + n.spi_size; - ep2 = (u_char *)p + ntohs(n.h.len); + ep2 = (u_char *)p + item_len; if (cp < ep) { printf(" orig=("); @@ -1004,19 +1096,22 @@ isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase, break; default: /* NULL is dummy */ - isakmp_print(cp, - ntohs(n.h.len) - sizeof(*p) - n.spi_size, - NULL); + isakmp_print(gndo, cp, + item_len - sizeof(*p) - n.spi_size, + NULL); } printf(")"); } - return (u_char *)ext + ntohs(n.h.len); + return (u_char *)ext + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N)); + return NULL; } static const u_char * -isakmp_d_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_, - int depth _U_) +isakmp_d_print(const struct isakmp_gen *ext, u_int item_len _U_, + const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, + u_int32_t proto0 _U_, int depth _U_) { const struct isakmp_pl_d *p; struct isakmp_pl_d d; @@ -1028,6 +1123,7 @@ isakmp_d_print(const struct isakmp_gen *ext, const u_char *ep _U_, printf("%s:", NPSTR(ISAKMP_NPTYPE_D)); p = (struct isakmp_pl_d *)ext; + TCHECK(*p); safememcpy(&d, ext, sizeof(d)); doi = ntohl(d.doi); proto = d.prot_id; @@ -1045,28 +1141,38 @@ isakmp_d_print(const struct isakmp_gen *ext, const u_char *ep _U_, for (i = 0; i < ntohs(d.num_spi); i++) { if (i != 0) printf(","); - rawprint((caddr_t)q, d.spi_size); + if (!rawprint((caddr_t)q, d.spi_size)) + goto trunc; q += d.spi_size; } return q; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D)); + return NULL; } static const u_char * -isakmp_vid_print(const struct isakmp_gen *ext, const u_char *ep _U_, - u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_, - int depth _U_) +isakmp_vid_print(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_) { struct isakmp_gen e; printf("%s:", NPSTR(ISAKMP_NPTYPE_VID)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); printf(" len=%d", ntohs(e.len) - 4); if (2 < vflag && 4 < ntohs(e.len)) { printf(" "); - rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); + if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4)) + goto trunc; } return (u_char *)ext + ntohs(e.len); +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID)); + return NULL; } static const u_char * @@ -1078,6 +1184,7 @@ isakmp_sub0_print(u_char np, const struct isakmp_gen *ext, const u_char *ep, u_int item_len; cp = (u_char *)ext; + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); /* @@ -1095,13 +1202,16 @@ isakmp_sub0_print(u_char np, const struct isakmp_gen *ext, const u_char *ep, * XXX - what if item_len is too short, or too long, * for this payload type? */ - cp = (*NPFUNC(np))(ext, ep, phase, doi, proto, depth); + cp = (*npfunc[np])(ext, item_len, ep, phase, doi, proto, depth); } else { printf("%s", NPSTR(np)); cp += item_len; } return cp; +trunc: + printf(" [|isakmp]"); + return NULL; } static const u_char * @@ -1115,15 +1225,12 @@ isakmp_sub_print(u_char np, const struct isakmp_gen *ext, const u_char *ep, cp = (const u_char *)ext; while (np) { - TCHECK2(*ext, sizeof(e)); + TCHECK(*ext); safememcpy(&e, ext, sizeof(e)); - if (ep < (u_char *)ext + ntohs(e.len)) { - printf(" [|%s]", NPSTR(np)); - cp = ep + 1; - break; - } + TCHECK2(*ext, ntohs(e.len)); + depth++; printf("\n"); for (i = 0; i < depth; i++) @@ -1143,6 +1250,7 @@ isakmp_sub_print(u_char np, const struct isakmp_gen *ext, const u_char *ep, } return cp; trunc: + printf(" [|%s]", NPSTR(np)); return NULL; } @@ -1166,7 +1274,9 @@ safememcpy(void *p, const void *q, size_t l) } void -isakmp_print(const u_char *bp, u_int length, const u_char *bp2) +isakmp_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) { const struct isakmp *p; struct isakmp base; @@ -1177,7 +1287,7 @@ isakmp_print(const u_char *bp, u_int length, const u_char *bp2) int major, minor; p = (const struct isakmp *)bp; - ep = snapend; + ep = ndo->ndo_snapend; if ((struct isakmp *)ep < p + 1) { printf("[|isakmp]"); @@ -1276,3 +1386,64 @@ done: } } } + +void +isakmp_rfc3948_print(netdissect_options *ndo, + const u_char *bp, u_int length, + const u_char *bp2) +{ + const u_char *ep; + ep = ndo->ndo_snapend; + + if(length == 1 && bp[0]==0xff) { + ND_PRINT((ndo, "isakmp-nat-keep-alive")); + return; + } + + if(length < 4) { + goto trunc; + } + + /* + * see if this is an IKE packet + */ + if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) { + ND_PRINT((ndo, "NONESP-encap: ")); + isakmp_print(ndo, bp+4, length-4, bp2); + return; + } + + /* must be an ESP packet */ + { + int nh, enh, padlen; + int advance; + + ND_PRINT((ndo, "UDP-encap: ")); + + advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); + if(advance <= 0) + return; + + bp += advance; + length -= advance + padlen; + nh = enh & 0xff; + + ip_print_inner(ndo, bp, length, nh, bp2); + return; + } + +trunc: + printf("[|isakmp]"); + return; +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ + + + +