X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/c6d12aeb6cd432560b53d05d662825743842787d..e2f07d68a62a30a8023d4dea2d50428bd3eabf7e:/print-isakmp.c diff --git a/print-isakmp.c b/print-isakmp.c index 142d30bb..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.45 2004-03-12 01:26:59 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 @@ -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,9 +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, u_int item_len, - 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; @@ -428,6 +430,7 @@ isakmp_sa_print(const struct isakmp_gen *ext, u_int item_len, 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); @@ -454,23 +457,28 @@ isakmp_sa_print(const struct isakmp_gen *ext, u_int item_len, 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, u_int item_len, - 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; @@ -479,20 +487,26 @@ isakmp_p_print(const struct isakmp_gen *ext, u_int item_len, 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[] = { @@ -567,6 +581,7 @@ isakmp_t_print(const struct isakmp_gen *ext, u_int item_len, printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); p = (struct isakmp_pl_t *)ext; + TCHECK(*p); safememcpy(&t, ext, sizeof(t)); switch (proto) { @@ -613,30 +628,38 @@ isakmp_t_print(const struct isakmp_gen *ext, u_int item_len, 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, u_int item_len, - const u_char *ep, 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, u_int item_len, - const u_char *ep, 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; @@ -655,6 +678,7 @@ isakmp_id_print(const struct isakmp_gen *ext, u_int item_len, printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); p = (struct isakmp_pl_id *)ext; + TCHECK(*p); safememcpy(&id, ext, sizeof(id)); if (sizeof(*p) < item_len) { data = (u_char *)(p + 1); @@ -687,6 +711,7 @@ isakmp_id_print(const struct isakmp_gen *ext, u_int item_len, 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) { @@ -706,9 +731,15 @@ isakmp_id_print(const struct isakmp_gen *ext, u_int item_len, 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: @@ -724,39 +755,60 @@ isakmp_id_print(const struct isakmp_gen *ext, u_int item_len, 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*/ @@ -772,16 +824,21 @@ isakmp_id_print(const struct isakmp_gen *ext, u_int item_len, 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 + item_len; +trunc: + printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID)); + return NULL; } static const u_char * -isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len, - const u_char *ep, 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; @@ -794,20 +851,25 @@ isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len, printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); printf(" len=%d", item_len - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); if (2 < vflag && 4 < item_len) { printf(" "); - rawprint((caddr_t)(ext + 1), item_len - 4); + if (!rawprint((caddr_t)(ext + 1), item_len - 4)) + goto trunc; } 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, u_int item_len, - const u_char *ep, 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; @@ -820,68 +882,90 @@ isakmp_cr_print(const struct isakmp_gen *ext, u_int item_len, printf("%s:", NPSTR(ISAKMP_NPTYPE_CR)); p = (struct isakmp_pl_cert *)ext; + TCHECK(*p); safememcpy(&cert, ext, sizeof(cert)); printf(" len=%d", item_len - 4); printf(" type=%s", STR_OR_ID((cert.encode), certstr)); if (2 < vflag && 4 < item_len) { printf(" "); - rawprint((caddr_t)(ext + 1), item_len - 4); + if (!rawprint((caddr_t)(ext + 1), item_len - 4)) + goto trunc; } 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, u_int item_len, - const u_char *ep, 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, u_int item_len, - const u_char *ep, 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, u_int item_len, - const u_char *ep, 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 * @@ -943,6 +1027,7 @@ isakmp_n_print(const struct isakmp_gen *ext, u_int item_len, 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; @@ -959,7 +1044,8 @@ isakmp_n_print(const struct isakmp_gen *ext, u_int item_len, 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; } @@ -978,7 +1064,8 @@ isakmp_n_print(const struct isakmp_gen *ext, u_int item_len, 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; @@ -1009,18 +1096,22 @@ isakmp_n_print(const struct isakmp_gen *ext, u_int item_len, break; default: /* NULL is dummy */ - isakmp_print(cp, item_len - sizeof(*p) - n.spi_size, - NULL); + isakmp_print(gndo, cp, + item_len - sizeof(*p) - n.spi_size, + NULL); } printf(")"); } 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, u_int item_len, - const u_char *ep, 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; @@ -1032,6 +1123,7 @@ isakmp_d_print(const struct isakmp_gen *ext, u_int item_len, 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; @@ -1049,28 +1141,38 @@ isakmp_d_print(const struct isakmp_gen *ext, u_int item_len, 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, u_int item_len, - const u_char *ep, 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 * @@ -1082,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)); /* @@ -1099,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, item_len, 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 * @@ -1119,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++) @@ -1147,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; } @@ -1170,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; @@ -1181,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]"); @@ -1280,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: + */ + + + +