diff options
author | Guy Harris <guy@alum.mit.edu> | 2019-03-28 11:45:43 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2019-03-28 11:45:43 -0700 |
commit | 48644533f2fba9a9b4d6e72d3f21f3b5cbcfe438 (patch) | |
tree | c5886b1845c760a1c6b84fe2675ad3305110bfa9 | |
parent | 400643120a48eca33973f6a47b34f0dcfde4d20a (diff) | |
download | tcpdump-48644533f2fba9a9b4d6e72d3f21f3b5cbcfe438.tar.gz |
Have esp_print() handle printing its payload.
That cleans things up a bit, including removing some duplicate code.
Clean up some other things, and add a length check, while we're at it.
-rw-r--r-- | netdissect.h | 2 | ||||
-rw-r--r-- | print-esp.c | 75 | ||||
-rw-r--r-- | print-ip-demux.c | 23 | ||||
-rw-r--r-- | print-isakmp.c | 18 |
4 files changed, 56 insertions, 62 deletions
diff --git a/netdissect.h b/netdissect.h index 68094c7c..3bcef726 100644 --- a/netdissect.h +++ b/netdissect.h @@ -541,7 +541,7 @@ extern void dvmrp_print(netdissect_options *, const u_char *, u_int); extern void eap_print(netdissect_options *, const u_char *, u_int); extern void egp_print(netdissect_options *, const u_char *, u_int); extern void eigrp_print(netdissect_options *, const u_char *, u_int); -extern int esp_print(netdissect_options *, const u_char *, const int, const u_char *, u_int *, u_int *); +extern void esp_print(netdissect_options *, const u_char *, u_int, const u_char *, u_int, int, u_int); extern u_int ether_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *); extern u_int ether_print_hdr_len(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *, u_int); extern int ethertype_print(netdissect_options *, u_short, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *); diff --git a/print-esp.c b/print-esp.c index 3b238933..4d86022f 100644 --- a/print-esp.c +++ b/print-esp.c @@ -657,25 +657,21 @@ void esp_print_decodesecret(netdissect_options *ndo) #endif #ifdef HAVE_LIBCRYPTO +#define USED_IF_LIBCRYPTO +#else +#define USED_IF_LIBCRYPTO _U_ +#endif + +#ifdef HAVE_LIBCRYPTO USES_APPLE_DEPRECATED_API #endif -int +void esp_print(netdissect_options *ndo, - const u_char *bp, const int length, const u_char *bp2 -#ifndef HAVE_LIBCRYPTO - _U_ -#endif - , - u_int *nhdr -#ifndef HAVE_LIBCRYPTO - _U_ -#endif - , - u_int *padlen -#ifndef HAVE_LIBCRYPTO - _U_ -#endif - ) + const u_char *bp, u_int length, + const u_char *bp2 USED_IF_LIBCRYPTO, + u_int ver USED_IF_LIBCRYPTO, + int fragmented USED_IF_LIBCRYPTO, + u_int ttl_hl USED_IF_LIBCRYPTO) { const struct newesp *esp; const u_char *ep; @@ -692,6 +688,8 @@ esp_print(netdissect_options *ndo, EVP_CIPHER_CTX *ctx; unsigned int block_size, buffer_size; u_char *input_buffer, *output_buffer; + u_int padlen; + u_int nh; #endif ndo->ndo_protocol = "esp"; @@ -712,25 +710,23 @@ esp_print(netdissect_options *ndo, if ((const u_char *)(esp + 1) >= ep) { nd_print_trunc(ndo); - goto fail; + return; } ND_PRINT("ESP(spi=0x%08x", GET_BE_U_4(esp->esp_spi)); ND_PRINT(",seq=0x%x)", GET_BE_U_4(esp->esp_seq)); ND_PRINT(", length %u", length); -#ifndef HAVE_LIBCRYPTO - goto fail; -#else +#ifdef HAVE_LIBCRYPTO /* initiailize SAs */ if (ndo->ndo_sa_list_head == NULL) { if (!ndo->ndo_espsecret) - goto fail; + return; esp_print_decodesecret(ndo); } if (ndo->ndo_sa_list_head == NULL) - goto fail; + return; ip = (const struct ip *)bp2; switch (IP_V(ip)) { @@ -738,7 +734,7 @@ esp_print(netdissect_options *ndo, ip6 = (const struct ip6_hdr *)bp2; /* we do not attempt to decrypt jumbograms */ if (!GET_BE_U_2(ip6->ip6_plen)) - goto fail; + return; /* if we can't get nexthdr, we do not need to decrypt it */ len = sizeof(struct ip6_hdr) + GET_BE_U_2(ip6->ip6_plen); @@ -755,7 +751,7 @@ esp_print(netdissect_options *ndo, case 4: /* nexthdr & padding are in the last fragment */ if (GET_BE_U_2(ip->ip_off) & IP_MF) - goto fail; + return; len = GET_BE_U_2(ip->ip_len); /* see if we can find the SA, and if so, decode it */ @@ -769,7 +765,7 @@ esp_print(netdissect_options *ndo, } break; default: - goto fail; + return; } /* if we didn't find the specific one, then look for @@ -780,11 +776,11 @@ esp_print(netdissect_options *ndo, /* if not found fail */ if (sa == NULL) - goto fail; + return; /* if we can't get nexthdr, we do not need to decrypt it */ if (ep - bp2 < len) - goto fail; + return; if (ep - bp2 > len) { /* FCS included at end of frame (NetBSD 1.6 or later) */ ep = bp2 + len; @@ -860,21 +856,26 @@ esp_print(netdissect_options *ndo, advance = sizeof(struct newesp); /* sanity check for pad length */ - if (ep - bp < GET_U_1(ep - 2)) - goto fail; + padlen = GET_U_1(ep - 2); + if (ep - bp < padlen) + return; - if (padlen) - *padlen = GET_U_1(ep - 2) + 2; + /* + * Sanity check for payload length; +2 is for the pad length + * and next header fields. + */ + if (length <= advance + padlen + 2) + return; + bp += advance; + length -= advance + padlen + 2; - if (nhdr) - *nhdr = GET_U_1(ep - 1); + nh = GET_U_1(ep - 1); ND_PRINT(": "); - return advance; -#endif -fail: - return -1; + /* Now print the payload. */ + ip_print_demux(ndo, bp, length, ver, fragmented, ttl_hl, nh, bp2); +#endif } #ifdef HAVE_LIBCRYPTO USES_APPLE_RST diff --git a/print-ip-demux.c b/print-ip-demux.c index 265658e7..2dae30d2 100644 --- a/print-ip-demux.c +++ b/print-ip-demux.c @@ -66,15 +66,14 @@ again: case IPPROTO_ESP: { - u_int enh, padlen; - advance = esp_print(ndo, bp, length, - iph, &enh, &padlen); - if (advance <= 0) - break; - bp += advance; - length -= advance + padlen; - nh = enh & 0xff; - goto again; + esp_print(ndo, bp, length, iph, ver, fragmented, ttl_hl); + /* + * Either this has decrypted the payload and + * printed it, in which case there's nothing more + * to do, or it hasn't, in which case there's + * nothing more to do. + */ + break; } case IPPROTO_IPCOMP: @@ -111,7 +110,7 @@ again: case IPPROTO_ICMPV6: icmp6_print(ndo, bp, length, iph, fragmented); - return; + break; case IPPROTO_PIGP: /* @@ -156,10 +155,8 @@ again: case IPPROTO_IPV4: /* ipv4-in-ip encapsulation */ ip_print(ndo, bp, length); - if (! ndo->ndo_vflag) { + if (! ndo->ndo_vflag) ND_PRINT(" (ipip-proto-4)"); - return; - } break; case IPPROTO_IPV6: diff --git a/print-isakmp.c b/print-isakmp.c index 0acab5a3..8ad8a60f 100644 --- a/print-isakmp.c +++ b/print-isakmp.c @@ -3124,20 +3124,16 @@ isakmp_rfc3948_print(netdissect_options *ndo, /* must be an ESP packet */ { - u_int nh, enh, padlen; - int advance; - ND_PRINT("UDP-encap: "); - advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); - if(advance <= 0) - return; - - bp += advance; - length -= advance + padlen; - nh = enh & 0xff; + esp_print(ndo, bp, length, bp2, ver, fragmented, ttl_hl); - ip_print_demux(ndo, bp, length, ver, fragmented, ttl_hl, nh, bp2); + /* + * Either this has decrypted the payload and + * printed it, in which case there's nothing more + * to do, or it hasn't, in which case there's + * nothing more to do. + */ return; } |