]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-tcp.c
Correct TCP option Kind value for TCP Auth and add SCPS-TP.
[tcpdump] / print-tcp.c
index a97fc1ca2e36ae79a53e750636d3c127a796c4fe..35b18492f8cb018c08cd8e5cb4f5e1b62ca15a60 100644 (file)
@@ -23,6 +23,8 @@
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
+/* \summary: TCP printer */
+
 #ifndef lint
 #else
 __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
@@ -44,9 +46,7 @@ __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
 #include "tcp.h"
 
 #include "ip.h"
-#ifdef INET6
 #include "ip6.h"
-#endif
 #include "ipproto.h"
 #include "rpc_auth.h"
 #include "rpc_msg.h"
@@ -80,7 +80,6 @@ struct tcp_seq_hash {
         tcp_seq ack;
 };
 
-#ifdef INET6
 struct tha6 {
         struct in6_addr src;
         struct in6_addr dst;
@@ -93,7 +92,6 @@ struct tcp_seq_hash6 {
         tcp_seq seq;
         tcp_seq ack;
 };
-#endif
 
 #define TSEQ_HASHSIZE 919
 
@@ -101,9 +99,7 @@ struct tcp_seq_hash6 {
 #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)
 
 static struct tcp_seq_hash tcp_seq_hash4[TSEQ_HASHSIZE];
-#ifdef INET6
 static struct tcp_seq_hash6 tcp_seq_hash6[TSEQ_HASHSIZE];
-#endif
 
 static const struct tok tcp_flag_values[] = {
         { TH_FIN, "F" },
@@ -131,8 +127,9 @@ static const struct tok tcp_option_values[] = {
         { TCPOPT_CCNEW, "ccnew" },
         { TCPOPT_CCECHO, "" },
         { TCPOPT_SIGNATURE, "md5" },
-        { TCPOPT_AUTH, "enhanced auth" },
+        { TCPOPT_SCPS, "scps" },
         { TCPOPT_UTO, "uto" },
+        { TCPOPT_AUTH, "enhanced auth" },
         { TCPOPT_MPTCP, "mptcp" },
         { TCPOPT_FASTOPEN, "tfo" },
         { TCPOPT_EXPERIMENT2, "exp" },
@@ -149,6 +146,16 @@ tcp_cksum(netdissect_options *ndo,
                                IPPROTO_TCP);
 }
 
+static int
+tcp6_cksum(netdissect_options *ndo,
+           register const struct ip6_hdr *ip6,
+           register const struct tcphdr *tp,
+           register u_int len)
+{
+       return nextproto6_cksum(ndo, ip6, (const uint8_t *)tp, len, len,
+                               IPPROTO_TCP);
+}
+
 void
 tcp_print(netdissect_options *ndo,
           register const u_char *bp, register u_int length,
@@ -164,18 +171,14 @@ tcp_print(netdissect_options *ndo,
         u_int utoval;
         uint16_t magic;
         register int rev;
-#ifdef INET6
         register const struct ip6_hdr *ip6;
-#endif
 
         tp = (const struct tcphdr *)bp;
         ip = (const struct ip *)bp2;
-#ifdef INET6
         if (IP_V(ip) == 6)
                 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]",
@@ -189,7 +192,6 @@ tcp_print(netdissect_options *ndo,
 
         hlen = TH_OFF(tp) * 4;
 
-#ifdef INET6
         if (ip6) {
                 if (ip6->ip6_nxt == IPPROTO_TCP) {
                         ND_PRINT((ndo, "%s.%s > %s.%s: ",
@@ -201,9 +203,7 @@ tcp_print(netdissect_options *ndo,
                         ND_PRINT((ndo, "%s > %s: ",
                                      tcpport_string(ndo, sport), tcpport_string(ndo, dport)));
                 }
-        } else
-#endif /*INET6*/
-        {
+        } else {
                 if (ip->ip_p == IPPROTO_TCP) {
                         ND_PRINT((ndo, "%s.%s > %s.%s: ",
                                      ipaddr_string(ndo, &ip->ip_src),
@@ -249,7 +249,6 @@ tcp_print(netdissect_options *ndo,
                  * both directions).
                  */
                 rev = 0;
-#ifdef INET6
                 if (ip6) {
                         register struct tcp_seq_hash6 *th;
                         struct tcp_seq_hash6 *tcp_seq_hash;
@@ -305,30 +304,24 @@ tcp_print(netdissect_options *ndo,
                         thseq = th->seq;
                         thack = th->ack;
                 } else {
-#else  /*INET6*/
-                {
-#endif /*INET6*/
                         register struct tcp_seq_hash *th;
                         struct tcp_seq_hash *tcp_seq_hash;
-                        const struct in_addr *src, *dst;
                         struct tha tha;
 
                         tcp_seq_hash = tcp_seq_hash4;
-                        src = &ip->ip_src;
-                        dst = &ip->ip_dst;
                         if (sport > dport)
                                 rev = 1;
                         else if (sport == dport) {
-                                if (UNALIGNED_MEMCMP(src, dst, sizeof ip->ip_dst) > 0)
+                                if (UNALIGNED_MEMCMP(&ip->ip_src, &ip->ip_dst, sizeof ip->ip_dst) > 0)
                                         rev = 1;
                         }
                         if (rev) {
-                                UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip->ip_dst);
-                                UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip->ip_src);
+                                UNALIGNED_MEMCPY(&tha.src, &ip->ip_dst, sizeof ip->ip_dst);
+                                UNALIGNED_MEMCPY(&tha.dst, &ip->ip_src, sizeof ip->ip_src);
                                 tha.port = dport << 16 | sport;
                         } else {
-                                UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip->ip_dst);
-                                UNALIGNED_MEMCPY(&tha.src, src, sizeof ip->ip_src);
+                                UNALIGNED_MEMCPY(&tha.dst, &ip->ip_dst, sizeof ip->ip_dst);
+                                UNALIGNED_MEMCPY(&tha.src, &ip->ip_src, sizeof ip->ip_src);
                                 tha.port = sport << 16 | dport;
                         }
 
@@ -388,12 +381,9 @@ tcp_print(netdissect_options *ndo,
                                 else
                                         ND_PRINT((ndo, " (correct)"));
                         }
-                }
-#ifdef INET6
-                else if (IP_V(ip) == 6 && ip6->ip6_plen) {
+                } else if (IP_V(ip) == 6 && ip6->ip6_plen) {
                         if (ND_TTEST2(tp->th_sport, length)) {
-                                sum = nextproto6_cksum(ip6, (const uint8_t *)tp,
-                                                       length, length, IPPROTO_TCP);
+                                sum = tcp6_cksum(ndo, ip6, tp, length);
                                 tcp_sum = EXTRACT_16BITS(&tp->th_sum);
 
                                 ND_PRINT((ndo, ", cksum 0x%04x", tcp_sum));
@@ -405,7 +395,6 @@ tcp_print(netdissect_options *ndo,
 
                         }
                 }
-#endif
         }
 
         length -= hlen;
@@ -476,7 +465,7 @@ tcp_print(netdissect_options *ndo,
                         case TCPOPT_SACK:
                                 datalen = len - 2;
                                 if (datalen % 8 != 0) {
-                                        ND_PRINT((ndo, "invalid sack"));
+                                        ND_PRINT((ndo, " invalid sack"));
                                 } else {
                                         uint32_t s, e;
 
@@ -524,6 +513,7 @@ tcp_print(netdissect_options *ndo,
                         case TCPOPT_SIGNATURE:
                                 datalen = TCP_SIGLEN;
                                 LENCHECK(datalen);
+                                ND_PRINT((ndo, " "));
 #ifdef HAVE_LIBCRYPTO
                                 switch (tcp_verify_signature(ndo, ip, tp,
                                                              bp + TH_OFF(tp) * 4, length, cp)) {
@@ -548,8 +538,14 @@ tcp_print(netdissect_options *ndo,
 #endif
                                 break;
 
+                        case TCPOPT_SCPS:
+                                datalen = 2;
+                                LENCHECK(datalen);
+                                ND_PRINT((ndo, " cap %02x id %u", cp[0], cp[1]));
+                                break;
+
                         case TCPOPT_AUTH:
-                                ND_PRINT((ndo, "keyid %d", *cp++));
+                                ND_PRINT((ndo, " keyid %d", *cp++));
                                 datalen = len - 3;
                                 for (i = 0; i < datalen; ++i) {
                                         LENCHECK(i);
@@ -571,7 +567,7 @@ tcp_print(netdissect_options *ndo,
                                 datalen = 2;
                                 LENCHECK(datalen);
                                 utoval = EXTRACT_16BITS(cp);
-                                ND_PRINT((ndo, "0x%x", utoval));
+                                ND_PRINT((ndo, " 0x%x", utoval));
                                 if (utoval & 0x0001)
                                         utoval = (utoval >> 1) * 60;
                                 else
@@ -589,6 +585,7 @@ tcp_print(netdissect_options *ndo,
                         case TCPOPT_FASTOPEN:
                                 datalen = len - 2;
                                 LENCHECK(datalen);
+                                ND_PRINT((ndo, " "));
                                 print_tcp_fastopen_option(ndo, cp, datalen, FALSE);
                                 break;
 
@@ -664,57 +661,59 @@ tcp_print(netdissect_options *ndo,
                 case PT_ZMTP1:
                         zmtp1_print(ndo, bp, length);
                         break;
+                case PT_RESP:
+                        resp_print(ndo, bp, length);
+                        break;
                 }
                 return;
         }
 
-        if (sport == TELNET_PORT || dport == TELNET_PORT) {
+        if (IS_SRC_OR_DST_PORT(TELNET_PORT)) {
                 telnet_print(ndo, bp, length);
-        } else if (sport == SMTP_PORT || dport == SMTP_PORT) {
+        } else if (IS_SRC_OR_DST_PORT(SMTP_PORT)) {
                 ND_PRINT((ndo, ": "));
                 smtp_print(ndo, bp, length);
-        } else if (sport == BGP_PORT || dport == BGP_PORT)
+        } else if (IS_SRC_OR_DST_PORT(BGP_PORT))
                 bgp_print(ndo, bp, length);
-        else if (sport == PPTP_PORT || dport == PPTP_PORT)
+        else if (IS_SRC_OR_DST_PORT(PPTP_PORT))
                 pptp_print(ndo, bp);
-#ifdef TCPDUMP_DO_SMB
-        else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT)
+        else if (IS_SRC_OR_DST_PORT(REDIS_PORT))
+                resp_print(ndo, bp, length);
+#ifdef ENABLE_SMB
+        else if (IS_SRC_OR_DST_PORT(NETBIOS_SSN_PORT))
                 nbt_tcp_print(ndo, bp, length);
-       else if (sport == SMB_PORT || dport == SMB_PORT)
+       else if (IS_SRC_OR_DST_PORT(SMB_PORT))
                smb_tcp_print(ndo, bp, length);
 #endif
-        else if (sport == BEEP_PORT || dport == BEEP_PORT)
+        else if (IS_SRC_OR_DST_PORT(BEEP_PORT))
                 beep_print(ndo, bp, length);
-        else if (sport == OPENFLOW_PORT_OLD || dport == OPENFLOW_PORT_OLD ||
-                 sport == OPENFLOW_PORT_IANA || dport == 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 (sport == FTP_PORT || dport == FTP_PORT) {
+        else if (IS_SRC_OR_DST_PORT(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) {
+        } else if (IS_SRC_OR_DST_PORT(HTTP_PORT) || IS_SRC_OR_DST_PORT(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) {
+        } else if (IS_SRC_OR_DST_PORT(RTSP_PORT) || IS_SRC_OR_DST_PORT(RTSP_PORT_ALT)) {
                 ND_PRINT((ndo, ": "));
                 rtsp_print(ndo, bp, length);
         } else if (length > 2 &&
-                 (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT)) {
+                 (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) {
                 /*
                  * TCP DNS query has 2byte length at the head.
                  * XXX packet could be unaligned, it can go strange
                  */
                 ns_print(ndo, bp + 2, length - 2, 0);
-        } else if (sport == MSDP_PORT || dport == MSDP_PORT) {
+        } else if (IS_SRC_OR_DST_PORT(MSDP_PORT)) {
                 msdp_print(ndo, bp, length);
-        } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) {
+        } else if (IS_SRC_OR_DST_PORT(RPKI_RTR_PORT)) {
                 rpki_rtr_print(ndo, bp, length);
         }
-        else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
+        else if (length > 0 && (IS_SRC_OR_DST_PORT(LDP_PORT))) {
                 ldp_print(ndo, bp, length);
         }
-        else if ((sport == NFS_PORT || dport == NFS_PORT) &&
+        else if ((IS_SRC_OR_DST_PORT(NFS_PORT)) &&
                  length >= 4 && ND_TTEST2(*bp, 4)) {
                 /*
                  * If data present, header length valid, and NFS port used,
@@ -784,7 +783,7 @@ print_tcp_rst_data(netdissect_options *ndo,
                 ND_PRINT((ndo, "+"));                  /* indicate we truncate */
         }
         ND_PRINT((ndo, " "));
-        while (length-- && sp <= ndo->ndo_snapend) {
+        while (length-- && sp < ndo->ndo_snapend) {
                 c = *sp++;
                 safeputchar(ndo, c);
         }
@@ -827,11 +826,9 @@ tcp_verify_signature(netdissect_options *ndo,
         char zero_proto = 0;
         MD5_CTX ctx;
         uint16_t savecsum, tlen;
-#ifdef INET6
         const struct ip6_hdr *ip6;
         uint32_t len32;
         uint8_t nxt;
-#endif
 
        if (data + length > ndo->ndo_snapend) {
                ND_PRINT((ndo, "snaplen too short, "));
@@ -857,7 +854,6 @@ tcp_verify_signature(netdissect_options *ndo,
                 tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4;
                 tlen = htons(tlen);
                 MD5_Update(&ctx, (const char *)&tlen, sizeof(tlen));
-#ifdef INET6
         } else if (IP_V(ip) == 6) {
                 ip6 = (const struct ip6_hdr *)ip;
                 MD5_Update(&ctx, (const char *)&ip6->ip6_src, sizeof(ip6->ip6_src));
@@ -870,13 +866,8 @@ tcp_verify_signature(netdissect_options *ndo,
                 MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt));
                 nxt = IPPROTO_TCP;
                 MD5_Update(&ctx, (const char *)&nxt, sizeof(nxt));
-#endif
         } else {
-#ifdef INET6
                ND_PRINT((ndo, "IP version not 4 or 6, "));
-#else
-               ND_PRINT((ndo, "IP version not 4, "));
-#endif
                 return (CANT_CHECK_SIGNATURE);
         }