Deleted Added
full compact
0a1,2
> /* $NetBSD: print-tcp.c,v 1.9 2007/07/26 18:15:12 plunky Exp $ */
>
26c28,30
< "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.120.2.3 2005/10/16 06:05:46 guy Exp $ (LBL)";
---
> "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.130.2.3 2007-12-22 03:08:45 guy Exp $ (LBL)";
> #else
> __RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
63c67
< const u_char *data, int length, const u_char *rcvsig);
---
> const u_char *data, int length, const u_char *rcvsig);
73,74c77,78
< struct in_addr src;
< struct in_addr dst;
---
> struct in_addr src;
> struct in_addr dst;
76,77c80,81
< struct in6_addr src;
< struct in6_addr dst;
---
> struct in6_addr src;
> struct in6_addr dst;
79c83
< u_int port;
---
> u_int port;
83,86c87,90
< struct tcp_seq_hash *nxt;
< struct tha addr;
< tcp_seq seq;
< tcp_seq ack;
---
> struct tcp_seq_hash *nxt;
> struct tha addr;
> tcp_seq seq;
> tcp_seq ack;
95a100,110
> struct tok tcp_flag_values[] = {
> { TH_FIN, "F" },
> { TH_SYN, "S" },
> { TH_RST, "R" },
> { TH_PUSH, "P" },
> { TH_ACK, "." },
> { TH_URG, "U" },
> { TH_ECNECHO, "E" },
> { TH_CWR, "W" },
> { 0, NULL }
> };
97,112c112,128
< #ifndef TELNET_PORT
< #define TELNET_PORT 23
< #endif
< #ifndef BGP_PORT
< #define BGP_PORT 179
< #endif
< #define NETBIOS_SSN_PORT 139
< #ifndef PPTP_PORT
< #define PPTP_PORT 1723
< #endif
< #define BEEP_PORT 10288
< #ifndef NFS_PORT
< #define NFS_PORT 2049
< #endif
< #define MSDP_PORT 639
< #define LDP_PORT 646
---
> struct tok tcp_option_values[] = {
> { TCPOPT_EOL, "eol" },
> { TCPOPT_NOP, "nop" },
> { TCPOPT_MAXSEG, "mss" },
> { TCPOPT_WSCALE, "wscale" },
> { TCPOPT_SACKOK, "sackOK" },
> { TCPOPT_SACK, "sack" },
> { TCPOPT_ECHO, "echo" },
> { TCPOPT_ECHOREPLY, "echoreply" },
> { TCPOPT_TIMESTAMP, "TS" },
> { TCPOPT_CC, "cc" },
> { TCPOPT_CCNEW, "ccnew" },
> { TCPOPT_CCECHO, "" },
> { TCPOPT_SIGNATURE, "md5" },
> { TCPOPT_AUTH, "enhanced auth" },
> { 0, NULL }
> };
118,128c134,144
< 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;
---
> 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;
130,138c146,154
< /* 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);
---
> /* 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);
140,142c156,158
< sp = &phu.pa[0];
< return in_cksum((u_short *)tp, len,
< sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
---
> sp = &phu.pa[0];
> return in_cksum((u_short *)tp, len,
> sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
147c163
< u_int len)
---
> u_int len)
149,161c165,176
< size_t i;
< register const u_int16_t *sp;
< u_int32_t sum;
< union {
< struct {
< struct in6_addr ph_src;
< struct in6_addr ph_dst;
< u_int32_t ph_len;
< u_int8_t ph_zero[3];
< u_int8_t ph_nxt;
< } ph;
< u_int16_t pa[20];
< } phu;
---
> size_t i;
> u_int32_t sum = 0;
> union {
> struct {
> struct in6_addr ph_src;
> struct in6_addr ph_dst;
> u_int32_t ph_len;
> u_int8_t ph_zero[3];
> u_int8_t ph_nxt;
> } ph;
> u_int16_t pa[20];
> } phu;
163,168c178,183
< /* pseudo-header */
< memset(&phu, 0, sizeof(phu));
< phu.ph.ph_src = ip6->ip6_src;
< phu.ph.ph_dst = ip6->ip6_dst;
< phu.ph.ph_len = htonl(len);
< phu.ph.ph_nxt = IPPROTO_TCP;
---
> /* pseudo-header */
> memset(&phu, 0, sizeof(phu));
> phu.ph.ph_src = ip6->ip6_src;
> phu.ph.ph_dst = ip6->ip6_dst;
> phu.ph.ph_len = htonl(len);
> phu.ph.ph_nxt = IPPROTO_TCP;
170,172c185,186
< sum = 0;
< for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
< sum += phu.pa[i];
---
> for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
> sum += phu.pa[i];
174,186c188
< sp = (const u_int16_t *)tp;
<
< for (i = 0; i < (len & ~1); i += 2)
< sum += *sp++;
<
< if (len & 1)
< sum += htons((*(const u_int8_t *)sp) << 8);
<
< while (sum > 0xffff)
< sum = (sum & 0xffff) + (sum >> 16);
< sum = ~sum & 0xffff;
<
< return (sum);
---
> return in_cksum((u_short *)tp, len, sum);
194,201c196,203
< register const struct tcphdr *tp;
< register const struct ip *ip;
< 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;
< int threv;
---
> register const struct tcphdr *tp;
> register const struct ip *ip;
> 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;
> int threv;
203c205
< register const struct ip6_hdr *ip6;
---
> register const struct ip6_hdr *ip6;
206,207c208,209
< tp = (struct tcphdr *)bp;
< ip = (struct ip *)bp2;
---
> tp = (struct tcphdr *)bp;
> ip = (struct ip *)bp2;
209,212c211,214
< if (IP_V(ip) == 6)
< ip6 = (struct ip6_hdr *)bp2;
< else
< ip6 = NULL;
---
> if (IP_V(ip) == 6)
> ip6 = (struct ip6_hdr *)bp2;
> else
> ip6 = NULL;
214,220c216,222
< ch = '\0';
< if (!TTEST(tp->th_dport)) {
< (void)printf("%s > %s: [|tcp]",
< ipaddr_string(&ip->ip_src),
< ipaddr_string(&ip->ip_dst));
< return;
< }
---
> ch = '\0';
> if (!TTEST(tp->th_dport)) {
> (void)printf("%s > %s: [|tcp]",
> ipaddr_string(&ip->ip_src),
> ipaddr_string(&ip->ip_dst));
> return;
> }
222,223c224,225
< sport = EXTRACT_16BITS(&tp->th_sport);
< dport = EXTRACT_16BITS(&tp->th_dport);
---
> sport = EXTRACT_16BITS(&tp->th_sport);
> dport = EXTRACT_16BITS(&tp->th_dport);
225c227
< hlen = TH_OFF(tp) * 4;
---
> hlen = TH_OFF(tp) * 4;
227c229
< /*
---
> /*
233,246c235,264
< if (!qflag && hlen >= sizeof(*tp) && hlen <= length) {
< if ((u_char *)tp + 4 + sizeof(struct sunrpc_msg) <= snapend &&
< dport == NFS_PORT) {
< nfsreq_print((u_char *)tp + hlen + 4, length - hlen,
< (u_char *)ip);
< return;
< } else if ((u_char *)tp + 4 + sizeof(struct sunrpc_msg)
< <= snapend &&
< sport == NFS_PORT) {
< nfsreply_print((u_char *)tp + hlen + 4, length - hlen,
< (u_char *)ip);
< return;
< }
< }
---
> if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
> (length - hlen) >= 4) {
> u_char *fraglenp;
> u_int32_t fraglen;
> register struct sunrpc_msg *rp;
> enum sunrpc_msg_type direction;
>
> fraglenp = (u_char *)tp + hlen;
> if (TTEST2(*fraglenp, 4)) {
> fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
> if (fraglen > (length - hlen) - 4)
> fraglen = (length - hlen) - 4;
> rp = (struct sunrpc_msg *)(fraglenp + 4);
> if (TTEST(rp->rm_direction)) {
> direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
> if (dport == NFS_PORT &&
> direction == SUNRPC_CALL) {
> nfsreq_print((u_char *)rp, fraglen,
> (u_char *)ip);
> return;
> }
> if (sport == NFS_PORT &&
> direction == SUNRPC_REPLY) {
> nfsreply_print((u_char *)rp, fraglen,
> (u_char *)ip);
> return;
> }
> }
> }
> }
248,259c266,277
< if (ip6) {
< if (ip6->ip6_nxt == IPPROTO_TCP) {
< (void)printf("%s.%s > %s.%s: ",
< ip6addr_string(&ip6->ip6_src),
< tcpport_string(sport),
< ip6addr_string(&ip6->ip6_dst),
< tcpport_string(dport));
< } else {
< (void)printf("%s > %s: ",
< tcpport_string(sport), tcpport_string(dport));
< }
< } else
---
> if (ip6) {
> if (ip6->ip6_nxt == IPPROTO_TCP) {
> (void)printf("%s.%s > %s.%s: ",
> ip6addr_string(&ip6->ip6_src),
> tcpport_string(sport),
> ip6addr_string(&ip6->ip6_dst),
> tcpport_string(dport));
> } else {
> (void)printf("%s > %s: ",
> tcpport_string(sport), tcpport_string(dport));
> }
> } else
261,272c279,290
< {
< if (ip->ip_p == IPPROTO_TCP) {
< (void)printf("%s.%s > %s.%s: ",
< ipaddr_string(&ip->ip_src),
< tcpport_string(sport),
< ipaddr_string(&ip->ip_dst),
< tcpport_string(dport));
< } else {
< (void)printf("%s > %s: ",
< tcpport_string(sport), tcpport_string(dport));
< }
< }
---
> {
> if (ip->ip_p == IPPROTO_TCP) {
> (void)printf("%s.%s > %s.%s: ",
> ipaddr_string(&ip->ip_src),
> tcpport_string(sport),
> ipaddr_string(&ip->ip_dst),
> tcpport_string(dport));
> } else {
> (void)printf("%s > %s: ",
> tcpport_string(sport), tcpport_string(dport));
> }
> }
274,278c292,296
< if (hlen < sizeof(*tp)) {
< (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
< length - hlen, hlen, (unsigned long)sizeof(*tp));
< return;
< }
---
> if (hlen < sizeof(*tp)) {
> (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
> length - hlen, hlen, (unsigned long)sizeof(*tp));
> return;
> }
280c298
< TCHECK(*tp);
---
> TCHECK(*tp);
282,285c300,303
< seq = EXTRACT_32BITS(&tp->th_seq);
< ack = EXTRACT_32BITS(&tp->th_ack);
< win = EXTRACT_16BITS(&tp->th_win);
< urp = EXTRACT_16BITS(&tp->th_urp);
---
> seq = EXTRACT_32BITS(&tp->th_seq);
> ack = EXTRACT_32BITS(&tp->th_ack);
> win = EXTRACT_16BITS(&tp->th_win);
> urp = EXTRACT_16BITS(&tp->th_urp);
287,310c305,312
< if (qflag) {
< (void)printf("tcp %d", length - hlen);
< if (hlen > length) {
< (void)printf(" [bad hdr length %u - too long, > %u]",
< hlen, length);
< }
< return;
< }
< if ((flags = tp->th_flags) & (TH_SYN|TH_FIN|TH_RST|TH_PUSH|
< TH_ECNECHO|TH_CWR)) {
< if (flags & TH_SYN)
< putchar('S');
< if (flags & TH_FIN)
< putchar('F');
< if (flags & TH_RST)
< putchar('R');
< if (flags & TH_PUSH)
< putchar('P');
< if (flags & TH_CWR)
< putchar('W'); /* congestion _W_indow reduced (ECN) */
< if (flags & TH_ECNECHO)
< putchar('E'); /* ecn _E_cho sent (ECN) */
< } else
< putchar('.');
---
> if (qflag) {
> (void)printf("tcp %d", length - hlen);
> if (hlen > length) {
> (void)printf(" [bad hdr length %u - too long, > %u]",
> hlen, length);
> }
> return;
> }
312,322c314,327
< 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
< * this conversation. (we pick an arbitrary
< * collating order so there's only one entry for
< * both directions).
< */
---
> flags = tp->th_flags;
> printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));
>
> 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
> * this conversation. (we pick an arbitrary
> * collating order so there's only one entry for
> * both directions).
> */
324,362c329,367
< memset(&tha, 0, sizeof(tha));
< rev = 0;
< if (ip6) {
< src = &ip6->ip6_src;
< dst = &ip6->ip6_dst;
< if (sport > dport)
< rev = 1;
< else if (sport == dport) {
< if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
< rev = 1;
< }
< if (rev) {
< memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
< memcpy(&tha.dst, src, sizeof ip6->ip6_src);
< tha.port = dport << 16 | sport;
< } else {
< memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
< memcpy(&tha.src, src, sizeof ip6->ip6_src);
< tha.port = sport << 16 | dport;
< }
< } else {
< src = &ip->ip_src;
< dst = &ip->ip_dst;
< if (sport > dport)
< rev = 1;
< else if (sport == dport) {
< if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
< rev = 1;
< }
< if (rev) {
< memcpy(&tha.src, dst, sizeof ip->ip_dst);
< memcpy(&tha.dst, src, sizeof ip->ip_src);
< tha.port = dport << 16 | sport;
< } else {
< memcpy(&tha.dst, dst, sizeof ip->ip_dst);
< memcpy(&tha.src, src, sizeof ip->ip_src);
< tha.port = sport << 16 | dport;
< }
< }
---
> memset(&tha, 0, sizeof(tha));
> rev = 0;
> if (ip6) {
> src = &ip6->ip6_src;
> dst = &ip6->ip6_dst;
> if (sport > dport)
> rev = 1;
> else if (sport == dport) {
> if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
> rev = 1;
> }
> if (rev) {
> memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
> memcpy(&tha.dst, src, sizeof ip6->ip6_src);
> tha.port = dport << 16 | sport;
> } else {
> memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
> memcpy(&tha.src, src, sizeof ip6->ip6_src);
> tha.port = sport << 16 | dport;
> }
> } else {
> src = &ip->ip_src;
> dst = &ip->ip_dst;
> if (sport > dport)
> rev = 1;
> else if (sport == dport) {
> if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
> rev = 1;
> }
> if (rev) {
> memcpy(&tha.src, dst, sizeof ip->ip_dst);
> memcpy(&tha.dst, src, sizeof ip->ip_src);
> tha.port = dport << 16 | sport;
> } else {
> memcpy(&tha.dst, dst, sizeof ip->ip_dst);
> memcpy(&tha.src, src, sizeof ip->ip_src);
> tha.port = sport << 16 | dport;
> }
> }
364,381c369,386
< rev = 0;
< src = &ip->ip_src;
< dst = &ip->ip_dst;
< if (sport > dport)
< rev = 1;
< else if (sport == dport) {
< if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
< rev = 1;
< }
< if (rev) {
< memcpy(&tha.src, dst, sizeof ip->ip_dst);
< memcpy(&tha.dst, src, sizeof ip->ip_src);
< tha.port = dport << 16 | sport;
< } else {
< memcpy(&tha.dst, dst, sizeof ip->ip_dst);
< memcpy(&tha.src, src, sizeof ip->ip_src);
< tha.port = sport << 16 | dport;
< }
---
> rev = 0;
> src = &ip->ip_src;
> dst = &ip->ip_dst;
> if (sport > dport)
> rev = 1;
> else if (sport == dport) {
> if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
> rev = 1;
> }
> if (rev) {
> memcpy(&tha.src, dst, sizeof ip->ip_dst);
> memcpy(&tha.dst, src, sizeof ip->ip_src);
> tha.port = dport << 16 | sport;
> } else {
> memcpy(&tha.dst, dst, sizeof ip->ip_dst);
> memcpy(&tha.src, src, sizeof ip->ip_src);
> tha.port = sport << 16 | dport;
> }
384,389c389,394
< threv = rev;
< for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
< th->nxt; th = th->nxt)
< if (memcmp((char *)&tha, (char *)&th->addr,
< sizeof(th->addr)) == 0)
< break;
---
> threv = rev;
> for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
> th->nxt; th = th->nxt)
> if (memcmp((char *)&tha, (char *)&th->addr,
> sizeof(th->addr)) == 0)
> break;
391,409c396,414
< if (!th->nxt || (flags & TH_SYN)) {
< /* didn't find it or new conversation */
< if (th->nxt == NULL) {
< th->nxt = (struct tcp_seq_hash *)
< calloc(1, sizeof(*th));
< if (th->nxt == NULL)
< error("tcp_print: calloc");
< }
< th->addr = tha;
< if (rev)
< th->ack = seq, th->seq = ack - 1;
< else
< th->seq = seq, th->ack = ack - 1;
< } else {
< if (rev)
< seq -= th->ack, ack -= th->seq;
< else
< seq -= th->seq, ack -= th->ack;
< }
---
> if (!th->nxt || (flags & TH_SYN)) {
> /* didn't find it or new conversation */
> if (th->nxt == NULL) {
> th->nxt = (struct tcp_seq_hash *)
> calloc(1, sizeof(*th));
> if (th->nxt == NULL)
> error("tcp_print: calloc");
> }
> th->addr = tha;
> if (rev)
> th->ack = seq, th->seq = ack - 1;
> else
> th->seq = seq, th->ack = ack - 1;
> } else {
> if (rev)
> seq -= th->ack, ack -= th->seq;
> else
> seq -= th->seq, ack -= th->ack;
> }
411,421c416,426
< thseq = th->seq;
< thack = th->ack;
< } else {
< /*fool gcc*/
< thseq = thack = threv = 0;
< }
< if (hlen > length) {
< (void)printf(" [bad hdr length %u - too long, > %u]",
< hlen, length);
< return;
< }
---
> thseq = th->seq;
> thack = th->ack;
> } else {
> /*fool gcc*/
> thseq = thack = threv = 0;
> }
> if (hlen > length) {
> (void)printf(" [bad hdr length %u - too long, > %u]",
> hlen, length);
> return;
> }
423,426c428,431
< if (IP_V(ip) == 4 && vflag && !fragmented) {
< u_int16_t sum, tcp_sum;
< if (TTEST2(tp->th_sport, length)) {
< sum = tcp_cksum(ip, tp, length);
---
> if (IP_V(ip) == 4 && vflag && !Kflag && !fragmented) {
> u_int16_t sum, tcp_sum;
> if (TTEST2(tp->th_sport, length)) {
> sum = tcp_cksum(ip, tp, length);
429,435c434,440
< if (sum != 0) {
< tcp_sum = EXTRACT_16BITS(&tp->th_sum);
< (void)printf(" (incorrect (-> 0x%04x),",in_cksum_shouldbe(tcp_sum, sum));
< } else
< (void)printf(" (correct),");
< }
< }
---
> if (sum != 0) {
> tcp_sum = EXTRACT_16BITS(&tp->th_sum);
> (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
> } else
> (void)printf(" (correct)");
> }
> }
437,440c442,445
< if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !fragmented) {
< u_int16_t sum,tcp_sum;
< if (TTEST2(tp->th_sport, length)) {
< sum = tcp6_cksum(ip6, tp, length);
---
> if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
> u_int16_t sum,tcp_sum;
> if (TTEST2(tp->th_sport, length)) {
> sum = tcp6_cksum(ip6, tp, length);
442,446c447,451
< if (sum != 0) {
< tcp_sum = EXTRACT_16BITS(&tp->th_sum);
< (void)printf(" (incorrect (-> 0x%04x),",in_cksum_shouldbe(tcp_sum, sum));
< } else
< (void)printf(" (correct),");
---
> if (sum != 0) {
> tcp_sum = EXTRACT_16BITS(&tp->th_sum);
> (void)printf(" (incorrect -> 0x%04x)",in_cksum_shouldbe(tcp_sum, sum));
> } else
> (void)printf(" (correct)");
448,449c453,454
< }
< }
---
> }
> }
452,456c457,459
< length -= hlen;
< if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST))
< (void)printf(" %u:%u(%u)", seq, seq + length, length);
< if (flags & TH_ACK)
< (void)printf(" ack %u", ack);
---
> length -= hlen;
> if (vflag > 1 || flags & (TH_SYN | TH_FIN | TH_RST)) {
> (void)printf(", seq %u", seq);
458c461,464
< (void)printf(" win %d", win);
---
> if (length > 0) {
> (void)printf(":%u", seq + length);
> }
> }
460,468c466,468
< if (flags & TH_URG)
< (void)printf(" urg %d", urp);
< /*
< * Handle any options.
< */
< if (hlen > sizeof(*tp)) {
< register const u_char *cp;
< register u_int i, opt, datalen;
< register u_int len;
---
> if (flags & TH_ACK) {
> (void)printf(", ack %u", ack);
> }
470,488c470
< hlen -= sizeof(*tp);
< cp = (const u_char *)tp + sizeof(*tp);
< putchar(' ');
< ch = '<';
< while (hlen > 0) {
< putchar(ch);
< TCHECK(*cp);
< opt = *cp++;
< if (ZEROLENOPT(opt))
< len = 1;
< else {
< TCHECK(*cp);
< len = *cp++; /* total including type, len */
< if (len < 2 || len > hlen)
< goto bad;
< --hlen; /* account for length byte */
< }
< --hlen; /* account for type byte */
< datalen = 0;
---
> (void)printf(", win %d", win);
489a472,501
> if (flags & TH_URG)
> (void)printf(", urg %d", urp);
> /*
> * Handle any options.
> */
> if (hlen > sizeof(*tp)) {
> register const u_char *cp;
> register u_int i, opt, datalen;
> register u_int len;
>
> hlen -= sizeof(*tp);
> cp = (const u_char *)tp + sizeof(*tp);
> printf(", options [");
> while (hlen > 0) {
> if (ch != '\0')
> putchar(ch);
> TCHECK(*cp);
> opt = *cp++;
> if (ZEROLENOPT(opt))
> len = 1;
> else {
> TCHECK(*cp);
> len = *cp++; /* total including type, len */
> if (len < 2 || len > hlen)
> goto bad;
> --hlen; /* account for length byte */
> }
> --hlen; /* account for type byte */
> datalen = 0;
>
493d504
< switch (opt) {
495,499c506
< case TCPOPT_MAXSEG:
< (void)printf("mss");
< datalen = 2;
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_16BITS(cp));
---
> printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));
501c508
< break;
---
> switch (opt) {
503,505c510,514
< case TCPOPT_EOL:
< (void)printf("eol");
< break;
---
> case TCPOPT_MAXSEG:
> datalen = 2;
> LENCHECK(datalen);
> (void)printf(" %u", EXTRACT_16BITS(cp));
> break;
507,509c516,520
< case TCPOPT_NOP:
< (void)printf("nop");
< break;
---
> case TCPOPT_WSCALE:
> datalen = 1;
> LENCHECK(datalen);
> (void)printf(" %u", *cp);
> break;
511,516c522,527
< case TCPOPT_WSCALE:
< (void)printf("wscale");
< datalen = 1;
< LENCHECK(datalen);
< (void)printf(" %u", *cp);
< break;
---
> case TCPOPT_SACK:
> datalen = len - 2;
> if (datalen % 8 != 0) {
> (void)printf("malformed sack");
> } else {
> u_int32_t s, e;
518,520c529,545
< case TCPOPT_SACKOK:
< (void)printf("sackOK");
< break;
---
> (void)printf(" %d ", datalen / 8);
> for (i = 0; i < datalen; i += 8) {
> LENCHECK(i + 4);
> s = EXTRACT_32BITS(cp + i);
> LENCHECK(i + 8);
> e = EXTRACT_32BITS(cp + i + 4);
> if (threv) {
> s -= thseq;
> e -= thseq;
> } else {
> s -= thack;
> e -= thack;
> }
> (void)printf("{%u:%u}", s, e);
> }
> }
> break;
522,527c547,551
< case TCPOPT_SACK:
< datalen = len - 2;
< if (datalen % 8 != 0) {
< (void)printf("malformed sack");
< } else {
< u_int32_t s, e;
---
> case TCPOPT_CC:
> case TCPOPT_CCNEW:
> case TCPOPT_CCECHO:
> case TCPOPT_ECHO:
> case TCPOPT_ECHOREPLY:
529,545c553,560
< (void)printf("sack %d ", datalen / 8);
< for (i = 0; i < datalen; i += 8) {
< LENCHECK(i + 4);
< s = EXTRACT_32BITS(cp + i);
< LENCHECK(i + 8);
< e = EXTRACT_32BITS(cp + i + 4);
< if (threv) {
< s -= thseq;
< e -= thseq;
< } else {
< s -= thack;
< e -= thack;
< }
< (void)printf("{%u:%u}", s, e);
< }
< }
< break;
---
> /*
> * those options share their semantics.
> * fall through
> */
> datalen = 4;
> LENCHECK(datalen);
> (void)printf(" %u", EXTRACT_32BITS(cp));
> break;
547,552c562,568
< case TCPOPT_ECHO:
< (void)printf("echo");
< datalen = 4;
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_32BITS(cp));
< break;
---
> case TCPOPT_TIMESTAMP:
> datalen = 8;
> LENCHECK(datalen);
> (void)printf(" val %u ecr %u",
> EXTRACT_32BITS(cp),
> EXTRACT_32BITS(cp + 4));
> break;
554,559c570,575
< case TCPOPT_ECHOREPLY:
< (void)printf("echoreply");
< datalen = 4;
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_32BITS(cp));
< break;
---
> case TCPOPT_SIGNATURE:
> datalen = TCP_SIGLEN;
> LENCHECK(datalen);
> #ifdef HAVE_LIBCRYPTO
> switch (tcp_verify_signature(ip, tp,
> bp + TH_OFF(tp) * 4, length, cp)) {
561,568c577,579
< case TCPOPT_TIMESTAMP:
< (void)printf("timestamp");
< datalen = 8;
< LENCHECK(4);
< (void)printf(" %u", EXTRACT_32BITS(cp));
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_32BITS(cp + 4));
< break;
---
> case SIGNATURE_VALID:
> (void)printf("valid");
> break;
570,575c581,583
< case TCPOPT_CC:
< (void)printf("cc");
< datalen = 4;
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_32BITS(cp));
< break;
---
> case SIGNATURE_INVALID:
> (void)printf("invalid");
> break;
577,582c585,595
< case TCPOPT_CCNEW:
< (void)printf("ccnew");
< datalen = 4;
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_32BITS(cp));
< break;
---
> case CANT_CHECK_SIGNATURE:
> (void)printf("can't check - ");
> for (i = 0; i < TCP_SIGLEN; ++i)
> (void)printf("%02x", cp[i]);
> break;
> }
> #else
> for (i = 0; i < TCP_SIGLEN; ++i)
> (void)printf("%02x", cp[i]);
> #endif
> break;
584,589c597,604
< case TCPOPT_CCECHO:
< (void)printf("ccecho");
< datalen = 4;
< LENCHECK(datalen);
< (void)printf(" %u", EXTRACT_32BITS(cp));
< break;
---
> case TCPOPT_AUTH:
> (void)printf("keyid %d", *cp++);
> datalen = len - 3;
> for (i = 0; i < datalen; ++i) {
> LENCHECK(i);
> (void)printf("%02x", cp[i]);
> }
> break;
591,597d605
< case TCPOPT_SIGNATURE:
< (void)printf("md5:");
< datalen = TCP_SIGLEN;
< LENCHECK(datalen);
< #ifdef HAVE_LIBCRYPTO
< switch (tcp_verify_signature(ip, tp,
< bp + TH_OFF(tp) * 4, length, cp)) {
599,601c607,614
< case SIGNATURE_VALID:
< (void)printf("valid");
< break;
---
> case TCPOPT_EOL:
> case TCPOPT_NOP:
> case TCPOPT_SACKOK:
> /*
> * Nothing interesting.
> * fall through
> */
> break;
603,605c616,623
< case SIGNATURE_INVALID:
< (void)printf("invalid");
< break;
---
> default:
> datalen = len - 2;
> for (i = 0; i < datalen; ++i) {
> LENCHECK(i);
> (void)printf("%02x", cp[i]);
> }
> break;
> }
607,617c625,627
< case CANT_CHECK_SIGNATURE:
< (void)printf("can't check - ");
< for (i = 0; i < TCP_SIGLEN; ++i)
< (void)printf("%02x", cp[i]);
< break;
< }
< #else
< for (i = 0; i < TCP_SIGLEN; ++i)
< (void)printf("%02x", cp[i]);
< #endif
< break;
---
> /* Account for data printed */
> cp += datalen;
> hlen -= datalen;
619,627c629,640
< default:
< (void)printf("opt-%u:", opt);
< datalen = len - 2;
< for (i = 0; i < datalen; ++i) {
< LENCHECK(i);
< (void)printf("%02x", cp[i]);
< }
< break;
< }
---
> /* Check specification against observed length */
> ++datalen; /* option octet */
> if (!ZEROLENOPT(opt))
> ++datalen; /* size octet */
> if (datalen != len)
> (void)printf("[len %d]", len);
> ch = ',';
> if (opt == TCPOPT_EOL)
> break;
> }
> putchar(']');
> }
629,631c642,645
< /* Account for data printed */
< cp += datalen;
< hlen -= datalen;
---
> /*
> * Print length field before crawling down the stack.
> */
> printf(", length %u", length);
633,644c647,648
< /* Check specification against observed length */
< ++datalen; /* option octet */
< if (!ZEROLENOPT(opt))
< ++datalen; /* size octet */
< if (datalen != len)
< (void)printf("[len %d]", len);
< ch = ',';
< if (opt == TCPOPT_EOL)
< break;
< }
< putchar('>');
< }
---
> if (length <= 0)
> return;
646,647c650,657
< if (length <= 0)
< return;
---
> /*
> * Decode payload if necessary.
> */
> bp += TH_OFF(tp) * 4;
> if ((flags & TH_RST) && vflag) {
> print_tcp_rst_data(bp, length);
> return;
> }
649,663c659,665
< /*
< * Decode payload if necessary.
< */
< bp += TH_OFF(tp) * 4;
< if (flags & TH_RST) {
< if (vflag)
< print_tcp_rst_data(bp, length);
< } else {
< if (sport == TELNET_PORT || dport == TELNET_PORT) {
< if (!qflag && vflag)
< telnet_print(bp, length);
< } else if (sport == BGP_PORT || dport == BGP_PORT)
< bgp_print(bp, length);
< else if (sport == PPTP_PORT || dport == PPTP_PORT)
< pptp_print(bp);
---
> if (sport == TELNET_PORT || dport == TELNET_PORT) {
> if (!qflag && vflag)
> telnet_print(bp, length);
> } else if (sport == BGP_PORT || dport == BGP_PORT)
> bgp_print(bp, length);
> else if (sport == PPTP_PORT || dport == PPTP_PORT)
> pptp_print(bp);
665,666c667,670
< else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT)
< nbt_tcp_print(bp, length);
---
> else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT)
> nbt_tcp_print(bp, length);
> else if (sport == SMB_PORT || dport == SMB_PORT)
> smb_tcp_print(bp, length);
668,694c672,698
< else if (sport == BEEP_PORT || dport == BEEP_PORT)
< beep_print(bp, length);
< else if (length > 2 &&
< (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT ||
< sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) {
< /*
< * TCP DNS query has 2byte length at the head.
< * XXX packet could be unaligned, it can go strange
< */
< ns_print(bp + 2, length - 2, 0);
< } else if (sport == MSDP_PORT || dport == MSDP_PORT) {
< msdp_print(bp, length);
< }
< else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
< ldp_print(bp, length);
< }
< }
< return;
< bad:
< fputs("[bad opt]", stdout);
< if (ch != '\0')
< putchar('>');
< return;
< trunc:
< fputs("[|tcp]", stdout);
< if (ch != '\0')
< putchar('>');
---
> else if (sport == BEEP_PORT || dport == BEEP_PORT)
> beep_print(bp, length);
> else if (length > 2 &&
> (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT ||
> sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) {
> /*
> * TCP DNS query has 2byte length at the head.
> * XXX packet could be unaligned, it can go strange
> */
> ns_print(bp + 2, length - 2, 0);
> } else if (sport == MSDP_PORT || dport == MSDP_PORT) {
> msdp_print(bp, length);
> }
> else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
> ldp_print(bp, length);
> }
>
> return;
> bad:
> fputs("[bad opt]", stdout);
> if (ch != '\0')
> putchar('>');
> return;
> trunc:
> fputs("[|tcp]", stdout);
> if (ch != '\0')
> putchar('>');
715c719
< int c;
---
> int c;
717,730c721,734
< if (TTEST2(*sp, length))
< printf(" [RST");
< else
< printf(" [!RST");
< if (length > MAX_RST_DATA_LEN) {
< length = MAX_RST_DATA_LEN; /* can use -X for longer */
< putchar('+'); /* indicate we truncate */
< }
< putchar(' ');
< while (length-- && sp <= snapend) {
< c = *sp++;
< safeputchar(c);
< }
< putchar(']');
---
> if (TTEST2(*sp, length))
> printf(" [RST");
> else
> printf(" [!RST");
> if (length > MAX_RST_DATA_LEN) {
> length = MAX_RST_DATA_LEN; /* can use -X for longer */
> putchar('+'); /* indicate we truncate */
> }
> putchar(' ');
> while (length-- && sp <= snapend) {
> c = *sp++;
> safeputchar(c);
> }
> putchar(']');
736c740
< const u_char *data, int length, const u_char *rcvsig)
---
> const u_char *data, int length, const u_char *rcvsig)
739,742c743,746
< u_char sig[TCP_SIGLEN];
< char zero_proto = 0;
< MD5_CTX ctx;
< u_int16_t savecsum, tlen;
---
> u_char sig[TCP_SIGLEN];
> char zero_proto = 0;
> MD5_CTX ctx;
> u_int16_t savecsum, tlen;
744c748,750
< struct ip6_hdr *ip6;
---
> struct ip6_hdr *ip6;
> u_int32_t len32;
> u_int8_t nxt;
746,747d751
< u_int32_t len32;
< u_int8_t nxt;
749c753
< tp1 = *tp;
---
> tp1 = *tp;
751,752c755,756
< if (tcpmd5secret == NULL)
< return (CANT_CHECK_SIGNATURE);
---
> if (tcpmd5secret == NULL)
> return (CANT_CHECK_SIGNATURE);
754,765c758,769
< MD5_Init(&ctx);
< /*
< * 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));
< tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4;
< tlen = htons(tlen);
< MD5_Update(&ctx, (char *)&tlen, sizeof(tlen));
---
> MD5_Init(&ctx);
> /*
> * 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));
> tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4;
> tlen = htons(tlen);
> MD5_Update(&ctx, (char *)&tlen, sizeof(tlen));
767,778c771,782
< } 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));
< len32 = htonl(ntohs(ip6->ip6_plen));
< MD5_Update(&ctx, (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));
< nxt = IPPROTO_TCP;
< MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
---
> } 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));
> len32 = htonl(ntohs(ip6->ip6_plen));
> MD5_Update(&ctx, (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));
> nxt = IPPROTO_TCP;
> MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
780,781c784,785
< } else
< return (CANT_CHECK_SIGNATURE);
---
> } else
> return (CANT_CHECK_SIGNATURE);
783,800c787,804
< /*
< * Step 2: Update MD5 hash with TCP header, excluding options.
< * The TCP checksum must be set to zero.
< */
< savecsum = tp1.th_sum;
< tp1.th_sum = 0;
< MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr));
< tp1.th_sum = savecsum;
< /*
< * Step 3: Update MD5 hash with TCP segment data, if present.
< */
< if (length > 0)
< MD5_Update(&ctx, data, length);
< /*
< * Step 4: Update MD5 hash with shared secret.
< */
< MD5_Update(&ctx, tcpmd5secret, strlen(tcpmd5secret));
< MD5_Final(sig, &ctx);
---
> /*
> * Step 2: Update MD5 hash with TCP header, excluding options.
> * The TCP checksum must be set to zero.
> */
> savecsum = tp1.th_sum;
> tp1.th_sum = 0;
> MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr));
> tp1.th_sum = savecsum;
> /*
> * Step 3: Update MD5 hash with TCP segment data, if present.
> */
> if (length > 0)
> MD5_Update(&ctx, data, length);
> /*
> * Step 4: Update MD5 hash with shared secret.
> */
> MD5_Update(&ctx, tcpmd5secret, strlen(tcpmd5secret));
> MD5_Final(sig, &ctx);
802,805c806,809
< if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0)
< return (SIGNATURE_VALID);
< else
< return (SIGNATURE_INVALID);
---
> if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0)
> return (SIGNATURE_VALID);
> else
> return (SIGNATURE_INVALID);
807a812,818
>
> /*
> * Local Variables:
> * c-style: whitesmith
> * c-basic-offset: 8
> * End:
> */