X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/abc8c2d61c65757011d9d32abb01cd1e51232f3a..f67e46a634dd3bdcefa9fc09dbef6baae1b1d1ed:/print-tcp.c diff --git a/print-tcp.c b/print-tcp.c index 0c712f1f..b727dde0 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -30,9 +30,7 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #endif -#ifdef HAVE_CONFIG_H #include -#endif #include "netdissect-stdinc.h" @@ -43,6 +41,8 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #include "addrtoname.h" #include "extract.h" +#include "diag-control.h" + #include "tcp.h" #include "ip.h" @@ -125,7 +125,7 @@ static const struct tok tcp_option_values[] = { { TCPOPT_TIMESTAMP, "TS" }, { TCPOPT_CC, "cc" }, { TCPOPT_CCNEW, "ccnew" }, - { TCPOPT_CCECHO, "" }, + { TCPOPT_CCECHO, "ccecho" }, { TCPOPT_SIGNATURE, "md5" }, { TCPOPT_SCPS, "scps" }, { TCPOPT_UTO, "uto" }, @@ -172,6 +172,7 @@ tcp_print(netdissect_options *ndo, uint16_t magic; int rev; const struct ip6_hdr *ip6; + u_int header_len; /* Header length in bytes */ ndo->ndo_protocol = "tcp"; tp = (const struct tcphdr *)bp; @@ -184,12 +185,12 @@ tcp_print(netdissect_options *ndo, if (!ND_TTEST_2(tp->th_dport)) { if (ip6) { ND_PRINT("%s > %s:", - ip6addr_string(ndo, ip6->ip6_src), - ip6addr_string(ndo, ip6->ip6_dst)); + GET_IP6ADDR_STRING(ip6->ip6_src), + GET_IP6ADDR_STRING(ip6->ip6_dst)); } else { ND_PRINT("%s > %s:", - ipaddr_string(ndo, ip->ip_src), - ipaddr_string(ndo, ip->ip_dst)); + GET_IPADDR_STRING(ip->ip_src), + GET_IPADDR_STRING(ip->ip_dst)); } nd_print_trunc(ndo); return; @@ -201,9 +202,9 @@ tcp_print(netdissect_options *ndo, if (ip6) { if (GET_U_1(ip6->ip6_nxt) == IPPROTO_TCP) { ND_PRINT("%s.%s > %s.%s: ", - ip6addr_string(ndo, ip6->ip6_src), + GET_IP6ADDR_STRING(ip6->ip6_src), tcpport_string(ndo, sport), - ip6addr_string(ndo, ip6->ip6_dst), + GET_IP6ADDR_STRING(ip6->ip6_dst), tcpport_string(ndo, dport)); } else { ND_PRINT("%s > %s: ", @@ -212,9 +213,9 @@ tcp_print(netdissect_options *ndo, } else { if (GET_U_1(ip->ip_p) == IPPROTO_TCP) { ND_PRINT("%s.%s > %s.%s: ", - ipaddr_string(ndo, ip->ip_src), + GET_IPADDR_STRING(ip->ip_src), tcpport_string(ndo, sport), - ipaddr_string(ndo, ip->ip_dst), + GET_IPADDR_STRING(ip->ip_dst), tcpport_string(ndo, dport)); } else { ND_PRINT("%s > %s: ", @@ -298,7 +299,7 @@ tcp_print(netdissect_options *ndo, if (th->nxt == NULL) (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, - "tcp_print: calloc"); + "%s: calloc", __func__); } th->addr = tha; if (rev) @@ -356,7 +357,7 @@ tcp_print(netdissect_options *ndo, if (th->nxt == NULL) (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, - "tcp_print: calloc"); + "%s: calloc", __func__); } th->addr = tha; if (rev) @@ -612,11 +613,28 @@ tcp_print(netdissect_options *ndo, break; case TCPOPT_MPTCP: + { + const u_char *snapend_save; + int ret; + datalen = len - 2; LENCHECK(datalen); - if (!mptcp_print(ndo, cp-2, len, flags)) + /* Update the snapend to the end of the option + * before calling mptcp_print(). Some options + * (MPTCP or others) may be present after a + * MPTCP option. This prevents that, in + * mptcp_print(), the remaining length < the + * remaining caplen. + */ + snapend_save = ndo->ndo_snapend; + ndo->ndo_snapend = ND_MIN(cp - 2 + len, + ndo->ndo_snapend); + ret = mptcp_print(ndo, cp - 2, len, flags); + ndo->ndo_snapend = snapend_save; + if (!ret) goto bad; break; + } case TCPOPT_FASTOPEN: datalen = len - 2; @@ -680,13 +698,23 @@ tcp_print(netdissect_options *ndo, */ ND_PRINT(", length %u", length); - if (length <= 0) + if (length == 0) return; /* * Decode payload if necessary. */ - bp += TH_OFF(tp) * 4; + header_len = TH_OFF(tp) * 4; + /* + * Do a bounds check before decoding the payload. + * At least the header data is required. + */ + if (!ND_TTEST_LEN(bp, header_len)) { + ND_PRINT(" [remaining caplen(%u) < header length(%u)]", + ND_BYTES_AVAILABLE_AFTER(bp), header_len); + nd_trunc_longjmp(ndo); + } + bp += header_len; if ((flags & TH_RST) && ndo->ndo_vflag) { print_tcp_rst_data(ndo, bp, length); return; @@ -708,51 +736,58 @@ tcp_print(netdissect_options *ndo, return; } - if (IS_SRC_OR_DST_PORT(TELNET_PORT)) { + if (IS_SRC_OR_DST_PORT(FTP_PORT)) { + ND_PRINT(": "); + ftp_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(SSH_PORT)) { + ssh_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(TELNET_PORT)) { telnet_print(ndo, bp, length); } else if (IS_SRC_OR_DST_PORT(SMTP_PORT)) { ND_PRINT(": "); smtp_print(ndo, bp, length); } else if (IS_SRC_OR_DST_PORT(WHOIS_PORT)) { ND_PRINT(": "); - ndo->ndo_protocol = "whois"; /* needed by txtproto_print() */ - txtproto_print(ndo, bp, length, NULL, 0); /* RFC 3912 */ - } else if (IS_SRC_OR_DST_PORT(BGP_PORT)) - bgp_print(ndo, bp, length); - else if (IS_SRC_OR_DST_PORT(PPTP_PORT)) - pptp_print(ndo, bp); - else if (IS_SRC_OR_DST_PORT(REDIS_PORT)) - resp_print(ndo, bp, length); - else if (IS_SRC_OR_DST_PORT(SSH_PORT)) - ssh_print(ndo, bp, length); + whois_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) { + /* over_tcp: TRUE, is_mdns: FALSE */ + domain_print(ndo, bp, length, TRUE, FALSE); + } else if (IS_SRC_OR_DST_PORT(HTTP_PORT)) { + ND_PRINT(": "); + http_print(ndo, bp, length); #ifdef ENABLE_SMB - else if (IS_SRC_OR_DST_PORT(NETBIOS_SSN_PORT)) + } else if (IS_SRC_OR_DST_PORT(NETBIOS_SSN_PORT)) { nbt_tcp_print(ndo, bp, length); - else if (IS_SRC_OR_DST_PORT(SMB_PORT)) +#endif + } else if (IS_SRC_OR_DST_PORT(BGP_PORT)) { + bgp_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) { + rpki_rtr_print(ndo, bp, length); +#ifdef ENABLE_SMB + } else if (IS_SRC_OR_DST_PORT(SMB_PORT)) { smb_tcp_print(ndo, bp, length); #endif + } else if (IS_SRC_OR_DST_PORT(RTSP_PORT)) { + ND_PRINT(": "); + rtsp_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) { + msdp_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(LDP_PORT)) { + ldp_print(ndo, bp, length); + } else if (IS_SRC_OR_DST_PORT(PPTP_PORT)) + pptp_print(ndo, bp); + else if (IS_SRC_OR_DST_PORT(REDIS_PORT)) + resp_print(ndo, bp, length); else if (IS_SRC_OR_DST_PORT(BEEP_PORT)) beep_print(ndo, bp, length); - else if (IS_SRC_OR_DST_PORT(OPENFLOW_PORT_OLD) || IS_SRC_OR_DST_PORT(OPENFLOW_PORT_IANA)) + else if (IS_SRC_OR_DST_PORT(OPENFLOW_PORT_OLD) || IS_SRC_OR_DST_PORT(OPENFLOW_PORT_IANA)) { openflow_print(ndo, bp, length); - else if (IS_SRC_OR_DST_PORT(FTP_PORT)) { - ND_PRINT(": "); - ftp_print(ndo, bp, length); - } else if (IS_SRC_OR_DST_PORT(HTTP_PORT) || IS_SRC_OR_DST_PORT(HTTP_PORT_ALT)) { + } else if (IS_SRC_OR_DST_PORT(HTTP_PORT_ALT)) { ND_PRINT(": "); http_print(ndo, bp, length); - } else if (IS_SRC_OR_DST_PORT(RTSP_PORT) || IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) { + } else if (IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) { ND_PRINT(": "); rtsp_print(ndo, bp, length); - } else if (IS_SRC_OR_DST_PORT(NAMESERVER_PORT)) { - /* over_tcp: TRUE, is_mdns: FALSE */ - domain_print(ndo, bp, length, TRUE, FALSE); - } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) { - msdp_print(ndo, bp, length); - } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) { - rpki_rtr_print(ndo, bp, length); - } else if (IS_SRC_OR_DST_PORT(LDP_PORT)) { - ldp_print(ndo, bp, length); } else if ((IS_SRC_OR_DST_PORT(NFS_PORT)) && length >= 4 && ND_TTEST_4(bp)) { /* @@ -859,7 +894,7 @@ print_tcp_fastopen_option(netdissect_options *ndo, const u_char *cp, } #ifdef HAVE_LIBCRYPTO -USES_APPLE_DEPRECATED_API +DIAG_OFF_DEPRECATION static int tcp_verify_signature(netdissect_options *ndo, const struct ip *ip, const struct tcphdr *tp, @@ -939,5 +974,5 @@ tcp_verify_signature(netdissect_options *ndo, else return (SIGNATURE_INVALID); } -USES_APPLE_RST +DIAG_ON_DEPRECATION #endif /* HAVE_LIBCRYPTO */