]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-tcp.c
Travis CI: Revert to libpcap master branch (updated)
[tcpdump] / print-tcp.c
index 7a04a6ff70b1081a65b95d3ec4b77733fe5e0478..b80a2f264d456992a0ffd6c7b2bf68632fa65ffc 100644 (file)
@@ -127,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_TCPAO, "tcp-ao" },
         { TCPOPT_MPTCP, "mptcp" },
         { TCPOPT_FASTOPEN, "tfo" },
         { TCPOPT_EXPERIMENT2, "exp" },
@@ -189,8 +190,6 @@ tcp_print(netdissect_options *ndo,
         sport = EXTRACT_16BITS(&tp->th_sport);
         dport = EXTRACT_16BITS(&tp->th_dport);
 
-        hlen = TH_OFF(tp) * 4;
-
         if (ip6) {
                 if (ip6->ip6_nxt == IPPROTO_TCP) {
                         ND_PRINT((ndo, "%s.%s > %s.%s: ",
@@ -215,14 +214,16 @@ tcp_print(netdissect_options *ndo,
                 }
         }
 
+        ND_TCHECK(*tp);
+
+        hlen = TH_OFF(tp) * 4;
+
         if (hlen < sizeof(*tp)) {
                 ND_PRINT((ndo, " tcp %d [bad hdr length %u - too short, < %lu]",
                              length - hlen, hlen, (unsigned long)sizeof(*tp)));
                 return;
         }
 
-        ND_TCHECK(*tp);
-
         seq = EXTRACT_32BITS(&tp->th_seq);
         ack = EXTRACT_32BITS(&tp->th_ack);
         win = EXTRACT_16BITS(&tp->th_win);
@@ -266,11 +267,11 @@ tcp_print(netdissect_options *ndo,
                         if (rev) {
                                 UNALIGNED_MEMCPY(&tha.src, dst, sizeof ip6->ip6_dst);
                                 UNALIGNED_MEMCPY(&tha.dst, src, sizeof ip6->ip6_src);
-                                tha.port = dport << 16 | sport;
+                                tha.port = ((u_int)dport) << 16 | sport;
                         } else {
                                 UNALIGNED_MEMCPY(&tha.dst, dst, sizeof ip6->ip6_dst);
                                 UNALIGNED_MEMCPY(&tha.src, src, sizeof ip6->ip6_src);
-                                tha.port = sport << 16 | dport;
+                                tha.port = ((u_int)sport) << 16 | dport;
                         }
 
                         for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
@@ -317,11 +318,11 @@ tcp_print(netdissect_options *ndo,
                         if (rev) {
                                 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;
+                                tha.port = ((u_int)dport) << 16 | sport;
                         } else {
                                 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;
+                                tha.port = ((u_int)sport) << 16 | dport;
                         }
 
                         for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
@@ -537,15 +538,35 @@ tcp_print(netdissect_options *ndo,
 #endif
                                 break;
 
-                        case TCPOPT_AUTH:
-                                ND_PRINT((ndo, " keyid %d", *cp++));
-                                datalen = len - 3;
-                                for (i = 0; i < datalen; ++i) {
-                                        LENCHECK(i);
-                                        ND_PRINT((ndo, "%02x", cp[i]));
-                                }
+                        case TCPOPT_SCPS:
+                                datalen = 2;
+                                LENCHECK(datalen);
+                                ND_PRINT((ndo, " cap %02x id %u", cp[0], cp[1]));
                                 break;
 
+                        case TCPOPT_TCPAO:
+                                datalen = len - 2;
+                                /* RFC 5925 Section 2.2:
+                                 * "The Length value MUST be greater than or equal to 4."
+                                 * (This includes the Kind and Length fields already processed
+                                 * at this point.)
+                                 */
+                                if (datalen < 2) {
+                                        ND_PRINT((ndo, " invalid"));
+                                } else {
+                                        LENCHECK(1);
+                                        ND_PRINT((ndo, " keyid %u", cp[0]));
+                                        LENCHECK(2);
+                                        ND_PRINT((ndo, " rnextkeyid %u", cp[1]));
+                                        if (datalen > 2) {
+                                                ND_PRINT((ndo, " mac 0x"));
+                                                for (i = 2; i < datalen; i++) {
+                                                        LENCHECK(i + 1);
+                                                        ND_PRINT((ndo, "%02x", cp[i]));
+                                                }
+                                        }
+                                }
+                                break;
 
                         case TCPOPT_EOL:
                         case TCPOPT_NOP:
@@ -609,7 +630,7 @@ tcp_print(netdissect_options *ndo,
                                 if (datalen)
                                         ND_PRINT((ndo, " 0x"));
                                 for (i = 0; i < datalen; ++i) {
-                                        LENCHECK(i);
+                                        LENCHECK(i + 1);
                                         ND_PRINT((ndo, "%02x", cp[i]));
                                 }
                                 break;
@@ -693,6 +714,12 @@ tcp_print(netdissect_options *ndo,
                 rtsp_print(ndo, bp, length);
         } else if (length > 2 &&
                  (IS_SRC_OR_DST_PORT(NAMESERVER_PORT))) {
+                /* domain_print() assumes it does not have to prepend a space before its
+                 * own output to separate it from the output of the calling function. This
+                 * works well with udp_print(), but requires a small prop here.
+                 */
+                ND_PRINT((ndo, " "));
+
                 /*
                  * TCP DNS query has 2byte length at the head.
                  * XXX packet could be unaligned, it can go strange