static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
-struct tok tcp_flag_values[] = {
+static const struct tok tcp_flag_values[] = {
{ TH_FIN, "F" },
{ TH_SYN, "S" },
{ TH_RST, "R" },
{ 0, NULL }
};
-struct tok tcp_option_values[] = {
+static const struct tok tcp_option_values[] = {
{ TCPOPT_EOL, "eol" },
{ TCPOPT_NOP, "nop" },
{ TCPOPT_MAXSEG, "mss" },
{ TCPOPT_SIGNATURE, "md5" },
{ TCPOPT_AUTH, "enhanced auth" },
{ TCPOPT_UTO, "uto" },
+ { TCPOPT_MPTCP, "mptcp" },
+ { TCPOPT_EXPERIMENT2, "exp" },
{ 0, NULL }
};
register const struct tcphdr *tp,
register u_int len)
{
- union phu {
- struct phdr {
- u_int32_t src;
- u_int32_t dst;
- u_char mbz;
- u_char proto;
- u_int16_t len;
- } ph;
- u_int16_t pa[6];
- } phu;
- const u_int16_t *sp;
-
- /* pseudo-header.. */
- phu.ph.len = htons((u_int16_t)len);
- phu.ph.mbz = 0;
- phu.ph.proto = IPPROTO_TCP;
- memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
- if (IP_HL(ip) == 5)
- memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
- else
- phu.ph.dst = ip_finddst(ip);
-
- sp = &phu.pa[0];
- return in_cksum((u_short *)tp, len,
- sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
+ return (nextproto4_cksum(ip, (const u_int8_t *)tp, len,
+ IPPROTO_TCP));
}
void
u_int16_t sport, dport, win, urp;
u_int32_t seq, ack, thseq, thack;
u_int utoval;
- int threv;
+ u_int16_t magic;
+ register int rev;
#ifdef INET6
register const struct ip6_hdr *ip6;
#endif
if (!Sflag && (flags & TH_ACK)) {
register struct tcp_seq_hash *th;
const void *src, *dst;
- register int rev;
struct tha tha;
/*
* Find (or record) the initial sequence numbers for
* both directions).
*/
#ifdef INET6
- memset(&tha, 0, sizeof(tha));
rev = 0;
if (ip6) {
src = &ip6->ip6_src;
tha.port = sport << 16 | dport;
}
} else {
+ /*
+ * Zero out the tha structure; the src and dst
+ * fields are big enough to hold an IPv6
+ * address, but we only have IPv4 addresses
+ * and thus must clear out the remaining 124
+ * bits.
+ *
+ * XXX - should we just clear those bytes after
+ * copying the IPv4 addresses, rather than
+ * zeroing out the entire structure and then
+ * overwriting some of the zeroes?
+ *
+ * XXX - this could fail if we see TCP packets
+ * with an IPv6 address with the lower 124 bits
+ * all zero and also see TCP packes with an
+ * IPv4 address with the same 32 bits as the
+ * upper 32 bits of the IPv6 address in question.
+ * Can that happen? Is it likely enough to be
+ * an issue?
+ */
+ memset(&tha, 0, sizeof(tha));
src = &ip->ip_src;
dst = &ip->ip_dst;
if (sport > dport)
}
#endif
- threv = rev;
for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
th->nxt; th = th->nxt)
if (memcmp((char *)&tha, (char *)&th->addr,
thack = th->ack;
} else {
/*fool gcc*/
- thseq = thack = threv = 0;
+ thseq = thack = rev = 0;
}
if (hlen > length) {
(void)printf(" [bad hdr length %u - too long, > %u]",
return;
}
- if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) {
+ if (vflag && !Kflag && !fragmented) {
+ /* Check the checksum, if possible. */
u_int16_t sum, tcp_sum;
- if (TTEST2(tp->th_sport, length)) {
- sum = tcp_cksum(ip, tp, length);
- (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
- if (sum != 0) {
+ if (IP_V(ip) == 4) {
+ if (TTEST2(tp->th_sport, length)) {
+ sum = tcp_cksum(ip, tp, length);
tcp_sum = EXTRACT_16BITS(&tp->th_sum);
- (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
- } else
- (void)printf(" (correct)");
+
+ (void)printf(", cksum 0x%04x", tcp_sum);
+ if (sum != 0)
+ (void)printf(" (incorrect -> 0x%04x)",
+ in_cksum_shouldbe(tcp_sum, sum));
+ else
+ (void)printf(" (correct)");
+ }
}
- }
#ifdef INET6
- if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
- u_int16_t sum,tcp_sum;
- if (TTEST2(tp->th_sport, length)) {
- sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP);
- (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
- if (sum != 0) {
+ else if (IP_V(ip) == 6 && ip6->ip6_plen) {
+ if (TTEST2(tp->th_sport, length)) {
+ sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP);
tcp_sum = EXTRACT_16BITS(&tp->th_sum);
- (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
- } else
- (void)printf(" (correct)");
+ (void)printf(", cksum 0x%04x", tcp_sum);
+ if (sum != 0)
+ (void)printf(" (incorrect -> 0x%04x)",
+ in_cksum_shouldbe(tcp_sum, sum));
+ else
+ (void)printf(" (correct)");
+
+ }
}
- }
#endif
+ }
length -= hlen;
if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
s = EXTRACT_32BITS(cp + i);
LENCHECK(i + 8);
e = EXTRACT_32BITS(cp + i + 4);
- if (threv) {
+ if (rev) {
s -= thseq;
e -= thseq;
} else {
(void)printf(" %u", utoval);
break;
+ case TCPOPT_MPTCP:
+ datalen = len - 2;
+ LENCHECK(datalen);
+ if (!mptcp_print(cp-2, len, flags))
+ goto bad;
+ break;
+
+ case TCPOPT_EXPERIMENT2:
+ datalen = len - 2;
+ LENCHECK(datalen);
+ if (datalen < 2)
+ goto bad;
+ /* RFC6994 */
+ magic = EXTRACT_16BITS(cp);
+ (void)printf("-");
+
+ switch(magic) {
+
+ case 0xf989:
+ /* TCP Fast Open: draft-ietf-tcpm-fastopen-04 */
+ if (datalen == 2) {
+ /* Fast Open Cookie Request */
+ (void)printf("tfo cookiereq");
+ } else {
+ /* Fast Open Cookie */
+ if (datalen % 2 != 0 || datalen < 6 || datalen > 18) {
+ (void)printf("tfo malformed");
+ } else {
+ (void)printf("tfo cookie ");
+ for (i = 2; i < datalen; ++i)
+ (void)printf("%02x", cp[i]);
+ }
+ }
+ break;
+
+ default:
+ /* Unknown magic number */
+ (void)printf("%04x", magic);
+ break;
+ }
+ break;
+
default:
datalen = len - 2;
for (i = 0; i < datalen; ++i) {
return;
}
+ if (packettype) {
+ switch (packettype) {
+ case PT_ZMTP1:
+ zmtp1_print(bp, length);
+ break;
+ }
+ return;
+ }
+
if (sport == TELNET_PORT || dport == TELNET_PORT) {
if (!qflag && vflag)
telnet_print(bp, length);
#endif
else if (sport == BEEP_PORT || dport == BEEP_PORT)
beep_print(bp, length);
+ else if (sport == OPENFLOW_PORT || dport == OPENFLOW_PORT)
+ openflow_print(bp, length);
else if (length > 2 &&
(sport == NAMESERVER_PORT || dport == NAMESERVER_PORT ||
sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) {
ns_print(bp + 2, length - 2, 0);
} else if (sport == MSDP_PORT || dport == MSDP_PORT) {
msdp_print(bp, length);
+ } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) {
+ rpki_rtr_print(bp, length);
}
else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
ldp_print(bp, length);
}
#ifdef HAVE_LIBCRYPTO
+USES_APPLE_DEPRECATED_API
static int
tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
const u_char *data, int length, const u_char *rcvsig)
else
return (SIGNATURE_INVALID);
}
+USES_APPLE_RST
#endif /* HAVE_LIBCRYPTO */
/*