X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/2b753f80585fd13b547c3b6797806301d9cef5d6..71d0745d3d13d2c58126ebfeeeff0f1c8e745335:/print-tcp.c diff --git a/print-tcp.c b/print-tcp.c index 5d726af7..5374e8a4 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -28,7 +28,6 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #endif -#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -52,11 +51,9 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $"); #include "rpc_auth.h" #include "rpc_msg.h" -#include "nameser.h" - #ifdef HAVE_LIBCRYPTO #include -#include +#include "signature.h" static int tcp_verify_signature(netdissect_options *ndo, const struct ip *ip, const struct tcphdr *tp, @@ -64,6 +61,8 @@ static int tcp_verify_signature(netdissect_options *ndo, #endif static void print_tcp_rst_data(netdissect_options *, register const u_char *sp, u_int length); +static void print_tcp_fastopen_option(netdissect_options *ndo, register const u_char *cp, + u_int datalen, int exp); #define MAX_RST_DATA_LEN 30 @@ -135,6 +134,7 @@ static const struct tok tcp_option_values[] = { { TCPOPT_AUTH, "enhanced auth" }, { TCPOPT_UTO, "uto" }, { TCPOPT_MPTCP, "mptcp" }, + { TCPOPT_FASTOPEN, "tfo" }, { TCPOPT_EXPERIMENT2, "exp" }, { 0, NULL } }; @@ -145,7 +145,7 @@ tcp_cksum(netdissect_options *ndo, register const struct tcphdr *tp, register u_int len) { - return nextproto4_cksum(ndo, ip, (const u_int8_t *)tp, len, len, + return nextproto4_cksum(ndo, ip, (const uint8_t *)tp, len, len, IPPROTO_TCP); } @@ -159,28 +159,28 @@ tcp_print(netdissect_options *ndo, register u_char flags; register u_int hlen; register char ch; - u_int16_t sport, dport, win, urp; - u_int32_t seq, ack, thseq, thack; + uint16_t sport, dport, win, urp; + uint32_t seq, ack, thseq, thack; u_int utoval; - u_int16_t magic; + uint16_t magic; register int rev; #ifdef INET6 register const struct ip6_hdr *ip6; #endif - tp = (struct tcphdr *)bp; - ip = (struct ip *)bp2; + tp = (const struct tcphdr *)bp; + ip = (const struct ip *)bp2; #ifdef INET6 if (IP_V(ip) == 6) - ip6 = (struct ip6_hdr *)bp2; + ip6 = (const struct ip6_hdr *)bp2; else ip6 = NULL; #endif /*INET6*/ ch = '\0'; if (!ND_TTEST(tp->th_dport)) { ND_PRINT((ndo, "%s > %s: [|tcp]", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst))); + ipaddr_string(ndo, &ip->ip_src), + ipaddr_string(ndo, &ip->ip_dst))); return; } @@ -193,9 +193,9 @@ tcp_print(netdissect_options *ndo, if (ip6) { if (ip6->ip6_nxt == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", - ip6addr_string(&ip6->ip6_src), + ip6addr_string(ndo, &ip6->ip6_src), tcpport_string(sport), - ip6addr_string(&ip6->ip6_dst), + ip6addr_string(ndo, &ip6->ip6_dst), tcpport_string(dport))); } else { ND_PRINT((ndo, "%s > %s: ", @@ -206,9 +206,9 @@ tcp_print(netdissect_options *ndo, { if (ip->ip_p == IPPROTO_TCP) { ND_PRINT((ndo, "%s.%s > %s.%s: ", - ipaddr_string(&ip->ip_src), + ipaddr_string(ndo, &ip->ip_src), tcpport_string(sport), - ipaddr_string(&ip->ip_dst), + ipaddr_string(ndo, &ip->ip_dst), tcpport_string(dport))); } else { ND_PRINT((ndo, "%s > %s: ", @@ -287,7 +287,8 @@ tcp_print(netdissect_options *ndo, th->nxt = (struct tcp_seq_hash6 *) calloc(1, sizeof(*th)); if (th->nxt == NULL) - error("tcp_print: calloc"); + (*ndo->ndo_error)(ndo, + "tcp_print: calloc"); } th->addr = tha; if (rev) @@ -343,7 +344,8 @@ tcp_print(netdissect_options *ndo, th->nxt = (struct tcp_seq_hash *) calloc(1, sizeof(*th)); if (th->nxt == NULL) - error("tcp_print: calloc"); + (*ndo->ndo_error)(ndo, + "tcp_print: calloc"); } th->addr = tha; if (rev) @@ -372,7 +374,7 @@ tcp_print(netdissect_options *ndo, if (ndo->ndo_vflag && !ndo->ndo_Kflag && !fragmented) { /* Check the checksum, if possible. */ - u_int16_t sum, tcp_sum; + uint16_t sum, tcp_sum; if (IP_V(ip) == 4) { if (ND_TTEST2(tp->th_sport, length)) { @@ -390,7 +392,7 @@ tcp_print(netdissect_options *ndo, #ifdef INET6 else if (IP_V(ip) == 6 && ip6->ip6_plen) { if (ND_TTEST2(tp->th_sport, length)) { - sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, + sum = nextproto6_cksum(ip6, (const uint8_t *)tp, length, length, IPPROTO_TCP); tcp_sum = EXTRACT_16BITS(&tp->th_sum); @@ -476,7 +478,7 @@ tcp_print(netdissect_options *ndo, if (datalen % 8 != 0) { ND_PRINT((ndo, "malformed sack")); } else { - u_int32_t s, e; + uint32_t s, e; ND_PRINT((ndo, " %d ", datalen / 8)); for (i = 0; i < datalen; i += 8) { @@ -584,6 +586,12 @@ tcp_print(netdissect_options *ndo, goto bad; break; + case TCPOPT_FASTOPEN: + datalen = len - 2; + LENCHECK(datalen); + print_tcp_fastopen_option(ndo, cp, datalen, FALSE); + break; + case TCPOPT_EXPERIMENT2: datalen = len - 2; LENCHECK(datalen); @@ -595,21 +603,8 @@ tcp_print(netdissect_options *ndo, switch(magic) { - case 0xf989: - /* TCP Fast Open: draft-ietf-tcpm-fastopen-04 */ - if (datalen == 2) { - /* Fast Open Cookie Request */ - ND_PRINT((ndo, "tfo cookiereq")); - } else { - /* Fast Open Cookie */ - if (datalen % 2 != 0 || datalen < 6 || datalen > 18) { - ND_PRINT((ndo, "tfo malformed")); - } else { - ND_PRINT((ndo, "tfo cookie ")); - for (i = 2; i < datalen; ++i) - ND_PRINT((ndo, "%02x", cp[i])); - } - } + case 0xf989: /* TCP Fast Open RFC 7413 */ + print_tcp_fastopen_option(ndo, cp + 2, datalen - 2, TRUE); break; default: @@ -674,8 +669,10 @@ tcp_print(netdissect_options *ndo, } if (sport == TELNET_PORT || dport == TELNET_PORT) { - if (!ndo->ndo_qflag && ndo->ndo_vflag) - telnet_print(ndo, bp, length); + telnet_print(ndo, bp, length); + } else if (sport == SMTP_PORT || dport == SMTP_PORT) { + ND_PRINT((ndo, ": ")); + smtp_print(ndo, bp, length); } else if (sport == BGP_PORT || dport == BGP_PORT) bgp_print(ndo, bp, length); else if (sport == PPTP_PORT || dport == PPTP_PORT) @@ -691,9 +688,19 @@ tcp_print(netdissect_options *ndo, else if (sport == OPENFLOW_PORT_OLD || dport == OPENFLOW_PORT_OLD || sport == OPENFLOW_PORT_IANA || dport == OPENFLOW_PORT_IANA) openflow_print(ndo, bp, length); - else if (length > 2 && - (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT || - sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) { + else if (sport == FTP_PORT || dport == FTP_PORT) { + ND_PRINT((ndo, ": ")); + ftp_print(ndo, bp, length); + } else if (sport == HTTP_PORT || dport == HTTP_PORT || + sport == HTTP_PORT_ALT || dport == HTTP_PORT_ALT) { + ND_PRINT((ndo, ": ")); + http_print(ndo, bp, length); + } else if (sport == RTSP_PORT || dport == RTSP_PORT || + sport == RTSP_PORT_ALT || dport == RTSP_PORT_ALT) { + ND_PRINT((ndo, ": ")); + rtsp_print(ndo, bp, length); + } else if (length > 2 && + (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT)) { /* * TCP DNS query has 2byte length at the head. * XXX packet could be unaligned, it can go strange @@ -715,24 +722,24 @@ tcp_print(netdissect_options *ndo, * Pass offset of data plus 4 bytes for RPC TCP msg length * to NFS print routines. */ - u_int32_t fraglen; - register struct sunrpc_msg *rp; + uint32_t fraglen; + register const struct sunrpc_msg *rp; enum sunrpc_msg_type direction; fraglen = EXTRACT_32BITS(bp) & 0x7FFFFFFF; if (fraglen > (length) - 4) fraglen = (length) - 4; - rp = (struct sunrpc_msg *)(bp + 4); + rp = (const struct sunrpc_msg *)(bp + 4); if (ND_TTEST(rp->rm_direction)) { direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction); if (dport == NFS_PORT && direction == SUNRPC_CALL) { ND_PRINT((ndo, ": NFS request xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreq_print_noaddr(ndo, (u_char *)rp, fraglen, (u_char *)ip); + nfsreq_print_noaddr(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); return; } if (sport == NFS_PORT && direction == SUNRPC_REPLY) { ND_PRINT((ndo, ": NFS reply xid %u ", EXTRACT_32BITS(&rp->rm_xid))); - nfsreply_print_noaddr(ndo, (u_char *)rp, fraglen, (u_char *)ip); + nfsreply_print_noaddr(ndo, (const u_char *)rp, fraglen, (const u_char *)ip); return; } } @@ -784,6 +791,30 @@ print_tcp_rst_data(netdissect_options *ndo, ND_PRINT((ndo, "]")); } +static void +print_tcp_fastopen_option(netdissect_options *ndo, register const u_char *cp, + u_int datalen, int exp) +{ + u_int i; + + if (exp) + ND_PRINT((ndo, "tfo")); + + if (datalen == 0) { + /* Fast Open Cookie Request */ + ND_PRINT((ndo, " cookiereq")); + } else { + /* Fast Open Cookie */ + if (datalen % 2 != 0 || datalen < 4 || datalen > 16) { + ND_PRINT((ndo, " malformed")); + } else { + ND_PRINT((ndo, " cookie ")); + for (i = 0; i < datalen; ++i) + ND_PRINT((ndo, "%02x", cp[i])); + } + } +} + #ifdef HAVE_LIBCRYPTO USES_APPLE_DEPRECATED_API static int @@ -795,11 +826,11 @@ tcp_verify_signature(netdissect_options *ndo, u_char sig[TCP_SIGLEN]; char zero_proto = 0; MD5_CTX ctx; - u_int16_t savecsum, tlen; + uint16_t savecsum, tlen; #ifdef INET6 - struct ip6_hdr *ip6; - u_int32_t len32; - u_int8_t nxt; + const struct ip6_hdr *ip6; + uint32_t len32; + uint8_t nxt; #endif if (data + length > ndo->ndo_snapend) { @@ -810,8 +841,8 @@ tcp_verify_signature(netdissect_options *ndo, tp1 = *tp; if (ndo->ndo_sigsecret == NULL) { - ND_PRINT((ndo, "shared secret not supplied with -M, "); - return (CANT_CHECK_SIGNATURE)); + ND_PRINT((ndo, "shared secret not supplied with -M, ")); + return (CANT_CHECK_SIGNATURE); } MD5_Init(&ctx); @@ -819,26 +850,26 @@ tcp_verify_signature(netdissect_options *ndo, * Step 1: Update MD5 hash with IP pseudo-header. */ if (IP_V(ip) == 4) { - MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src)); - MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst)); - MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto)); - MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p)); + MD5_Update(&ctx, (const char *)&ip->ip_src, sizeof(ip->ip_src)); + MD5_Update(&ctx, (const char *)&ip->ip_dst, sizeof(ip->ip_dst)); + MD5_Update(&ctx, (const char *)&zero_proto, sizeof(zero_proto)); + MD5_Update(&ctx, (const char *)&ip->ip_p, sizeof(ip->ip_p)); tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4; tlen = htons(tlen); - MD5_Update(&ctx, (char *)&tlen, sizeof(tlen)); + MD5_Update(&ctx, (const char *)&tlen, sizeof(tlen)); #ifdef INET6 } else if (IP_V(ip) == 6) { - ip6 = (struct ip6_hdr *)ip; - MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); - MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); + ip6 = (const struct ip6_hdr *)ip; + MD5_Update(&ctx, (const char *)&ip6->ip6_src, sizeof(ip6->ip6_src)); + MD5_Update(&ctx, (const char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst)); len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen)); - MD5_Update(&ctx, (char *)&len32, sizeof(len32)); + MD5_Update(&ctx, (const char *)&len32, sizeof(len32)); nxt = 0; - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); nxt = IPPROTO_TCP; - MD5_Update(&ctx, (char *)&nxt, sizeof(nxt)); + MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt)); #endif } else { #ifdef INET6 @@ -855,7 +886,7 @@ tcp_verify_signature(netdissect_options *ndo, */ savecsum = tp1.th_sum; tp1.th_sum = 0; - MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr)); + MD5_Update(&ctx, (const char *)&tp1, sizeof(struct tcphdr)); tp1.th_sum = savecsum; /* * Step 3: Update MD5 hash with TCP segment data, if present.