]> The Tcpdump Group git mirrors - tcpdump/commitdiff
change the TCP printer to print new-style order:
authorhannes <hannes>
Mon, 29 Jan 2007 09:59:42 +0000 (09:59 +0000)
committerhannes <hannes>
Mon, 29 Jan 2007 09:59:42 +0000 (09:59 +0000)
  - seperate fields by comma
  - use [] for flags and options sets
  - print a trailing length field

make use of tok2str() and bitttok2str()
move port definitions into tcp.h

netdissect.h
print-tcp.c
tcp.h
util.c

index cfe086e36f90b89c9ba05f83930134fbb89a30e4..fc8dfbabf4fb6d6c590555d3eaed7d294e80be3f 100644 (file)
@@ -21,7 +21,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.22 2006-05-05 23:13:00 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.23 2007-01-29 09:59:42 hannes Exp $ (LBL)
  */
 
 #ifndef netdissect_h
@@ -77,6 +77,7 @@ extern const char *tok2strbuf(const struct tok *, const char *, int,
 /* tok2str is deprecated */
 extern const char *tok2str(const struct tok *, const char *, int);
 extern char *bittok2str(const struct tok *, const char *, int);
+extern char *bittok2str_nosep(const struct tok *, const char *, int);
 
 
 typedef struct netdissect_options netdissect_options;
index 2846b246f12f8754e3c382558bcf5e8e3eaea46f..ada96b556e805dba122f75f14688fe7c213a0c9f 100644 (file)
@@ -23,7 +23,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.126 2006-11-02 08:56:16 hannes Exp $ (LBL)";
+"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.127 2007-01-29 09:59:42 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -60,7 +60,7 @@ static const char rcsid[] _U_ =
 #define CANT_CHECK_SIGNATURE   2
 
 static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
-    const u_char *data, int length, const u_char *rcvsig);
+                                const u_char *data, int length, const u_char *rcvsig);
 #endif
 
 static void print_tcp_rst_data(register const u_char *sp, u_int length);
@@ -70,20 +70,20 @@ static void print_tcp_rst_data(register const u_char *sp, u_int length);
 
 struct tha {
 #ifndef INET6
-       struct in_addr src;
-       struct in_addr dst;
+        struct in_addr src;
+        struct in_addr dst;
 #else
-       struct in6_addr src;
-       struct in6_addr dst;
+        struct in6_addr src;
+        struct in6_addr dst;
 #endif /*INET6*/
-       u_int port;
+        u_int port;
 };
 
 struct tcp_seq_hash {
-       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;
 };
 
 #define TSEQ_HASHSIZE 919
@@ -93,83 +93,95 @@ struct tcp_seq_hash {
 
 static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
 
+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 }
+};
 
-#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 }
+};
 
 static int tcp_cksum(register const struct ip *ip,
                     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]);
+        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]);
 }
 
 #ifdef INET6
 static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
-       u_int len)
+                      u_int len)
 {
-       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;
-
-       /* 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;
-
-       for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
-               sum += phu.pa[i];
-
-       return in_cksum((u_short *)tp, len, sum);
+        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;
+
+        /* 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;
+
+        for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
+                sum += phu.pa[i];
+
+        return in_cksum((u_short *)tp, len, sum);
 }
 #endif
 
@@ -177,516 +189,490 @@ void
 tcp_print(register const u_char *bp, register u_int length,
          register const u_char *bp2, int fragmented)
 {
-       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;
 #ifdef INET6
-       register const struct ip6_hdr *ip6;
+        register const struct ip6_hdr *ip6;
 #endif
 
-       tp = (struct tcphdr *)bp;
-       ip = (struct ip *)bp2;
+        tp = (struct tcphdr *)bp;
+        ip = (struct ip *)bp2;
 #ifdef INET6
-       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;
 #endif /*INET6*/
-       ch = '\0';
-       if (!TTEST(tp->th_dport)) {
-               (void)printf("%s > %s: [|tcp]",
-                       ipaddr_string(&ip->ip_src),
-                       ipaddr_string(&ip->ip_dst));
-               return;
-       }
-
-       sport = EXTRACT_16BITS(&tp->th_sport);
-       dport = EXTRACT_16BITS(&tp->th_dport);
-
-       hlen = TH_OFF(tp) * 4;
-
-       /*
-        * If data present, header length valid, and NFS port used,
-        * assume NFS.
-        * Pass offset of data plus 4 bytes for RPC TCP msg length
-        * to NFS print routines.
-        */
-       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;
-               }
-       }
+        ch = '\0';
+        if (!TTEST(tp->th_dport)) {
+                (void)printf("%s > %s: [|tcp]",
+                             ipaddr_string(&ip->ip_src),
+                             ipaddr_string(&ip->ip_dst));
+                return;
+        }
+
+        sport = EXTRACT_16BITS(&tp->th_sport);
+        dport = EXTRACT_16BITS(&tp->th_dport);
+
+        hlen = TH_OFF(tp) * 4;
+
+        /*
+         * If data present, header length valid, and NFS port used,
+         * assume NFS.
+         * Pass offset of data plus 4 bytes for RPC TCP msg length
+         * to NFS print routines.
+         */
+        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;
+                }
+        }
 #ifdef INET6
-       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
 #endif /*INET6*/
-       {
-               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 (hlen < sizeof(*tp)) {
-               (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
-                   length - hlen, hlen, (unsigned long)sizeof(*tp));
-               return;
-       }
-
-       TCHECK(*tp);
-
-       seq = EXTRACT_32BITS(&tp->th_seq);
-       ack = EXTRACT_32BITS(&tp->th_ack);
-       win = EXTRACT_16BITS(&tp->th_win);
-       urp = EXTRACT_16BITS(&tp->th_urp);
-
-       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 (!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).
-                */
+        {
+                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 (hlen < sizeof(*tp)) {
+                (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
+                             length - hlen, hlen, (unsigned long)sizeof(*tp));
+                return;
+        }
+
+        TCHECK(*tp);
+
+        seq = EXTRACT_32BITS(&tp->th_seq);
+        ack = EXTRACT_32BITS(&tp->th_ack);
+        win = EXTRACT_16BITS(&tp->th_win);
+        urp = EXTRACT_16BITS(&tp->th_urp);
+
+        if (qflag) {
+                (void)printf("tcp %d", length - hlen);
+                if (hlen > length) {
+                        (void)printf(" [bad hdr length %u - too long, > %u]",
+                                     hlen, length);
+                }
+                return;
+        }
+
+        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).
+                 */
 #ifdef INET6
-               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;
+                        }
+                }
 #else
-               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;
+                }
 #endif
 
-               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;
-
-               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;
-               }
-
-               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;
-       }
-
-       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);
+                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;
+
+                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;
+                }
+
+                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;
+        }
+
+        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);
 
                         (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
-                       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),");
+                }
+        }
 #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 = 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);
                         (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
-                       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),");
+
+                }
+        }
 #endif
 
-       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);
-
-       (void)printf(" win %d", win);
-
-       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);
-               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;
+        length -= hlen;
+        if (vflag > 1 || flags & (TH_SYN | TH_FIN | TH_RST)) {
+                (void)printf(", seq %u", seq);
+
+                if (length > 0) {
+                        (void)printf(":%u", seq + length);
+                }
+        }
+
+        if (flags & TH_ACK) {
+                (void)printf(", ack %u", ack);
+        }
+
+        (void)printf(", win %d", win);
+
+        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) {
+                        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;
 
 /* Bail if "l" bytes of data are not left or were not captured  */
 #define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }
 
-                       switch (opt) {
-
-                       case TCPOPT_MAXSEG:
-                               (void)printf("mss");
-                               datalen = 2;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", EXTRACT_16BITS(cp));
-
-                               break;
-
-                       case TCPOPT_EOL:
-                               (void)printf("eol");
-                               break;
-
-                       case TCPOPT_NOP:
-                               (void)printf("nop");
-                               break;
-
-                       case TCPOPT_WSCALE:
-                               (void)printf("wscale");
-                               datalen = 1;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", *cp);
-                               break;
-
-                       case TCPOPT_SACKOK:
-                               (void)printf("sackOK");
-                               break;
-
-                       case TCPOPT_SACK:
-                               datalen = len - 2;
-                               if (datalen % 8 != 0) {
-                                       (void)printf("malformed sack");
-                               } else {
-                                       u_int32_t s, e;
-
-                                       (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;
-
-                       case TCPOPT_ECHO:
-                               (void)printf("echo");
-                               datalen = 4;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", EXTRACT_32BITS(cp));
-                               break;
-
-                       case TCPOPT_ECHOREPLY:
-                               (void)printf("echoreply");
-                               datalen = 4;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", EXTRACT_32BITS(cp));
-                               break;
-
-                       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 TCPOPT_CC:
-                               (void)printf("cc");
-                               datalen = 4;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", EXTRACT_32BITS(cp));
-                               break;
-
-                       case TCPOPT_CCNEW:
-                               (void)printf("ccnew");
-                               datalen = 4;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", EXTRACT_32BITS(cp));
-                               break;
-
-                       case TCPOPT_CCECHO:
-                               (void)printf("ccecho");
-                               datalen = 4;
-                               LENCHECK(datalen);
-                               (void)printf(" %u", EXTRACT_32BITS(cp));
-                               break;
-
-                       case TCPOPT_SIGNATURE:
-                               (void)printf("md5:");
-                               datalen = TCP_SIGLEN;
-                               LENCHECK(datalen);
+
+                        printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));
+
+                        switch (opt) {
+
+                        case TCPOPT_MAXSEG:
+                                datalen = 2;
+                                LENCHECK(datalen);
+                                (void)printf(" %u", EXTRACT_16BITS(cp));
+                                break;
+
+                        case TCPOPT_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;
+
+                                        (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;
+
+                        case TCPOPT_CC:
+                        case TCPOPT_CCNEW:
+                        case TCPOPT_CCECHO:
+                        case TCPOPT_ECHO:
+                        case TCPOPT_ECHOREPLY:
+
+                                /*
+                                 * those options share their semantics.
+                                 * fall through
+                                 */
+                                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;
+
+                        case TCPOPT_SIGNATURE:
+                                datalen = TCP_SIGLEN;
+                                LENCHECK(datalen);
 #ifdef HAVE_LIBCRYPTO
-                               switch (tcp_verify_signature(ip, tp,
-                                   bp + TH_OFF(tp) * 4, length, cp)) {
-
-                               case SIGNATURE_VALID:
-                                       (void)printf("valid");
-                                       break;
-
-                               case SIGNATURE_INVALID:
-                                       (void)printf("invalid");
-                                       break;
-
-                               case CANT_CHECK_SIGNATURE:
-                                       (void)printf("can't check - ");
-                                       for (i = 0; i < TCP_SIGLEN; ++i)
-                                               (void)printf("%02x", cp[i]);
-                                       break;
-                               }
+                                switch (tcp_verify_signature(ip, tp,
+                                                             bp + TH_OFF(tp) * 4, length, cp)) {
+
+                                case SIGNATURE_VALID:
+                                        (void)printf("valid");
+                                        break;
+
+                                case SIGNATURE_INVALID:
+                                        (void)printf("invalid");
+                                        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]);
+                                for (i = 0; i < TCP_SIGLEN; ++i)
+                                        (void)printf("%02x", cp[i]);
 #endif
-                               break;
+                                break;
 
                         case TCPOPT_AUTH:
-                                (void)printf("Enhanced Auth: keyid %d", *cp++);
+                                (void)printf("keyid %d", *cp++);
                                 datalen = len - 3;
                                 for (i = 0; i < datalen; ++i) {
-                                    LENCHECK(i);
-                                    (void)printf("%02x", cp[i]);
+                                        LENCHECK(i);
+                                        (void)printf("%02x", cp[i]);
                                 }
-                            break;
-
-                       default:
-                               (void)printf("opt-%u:", opt);
-                               datalen = len - 2;
-                               for (i = 0; i < datalen; ++i) {
-                                       LENCHECK(i);
-                                       (void)printf("%02x", cp[i]);
-                               }
-                               break;
-                       }
-
-                       /* Account for data printed */
-                       cp += datalen;
-                       hlen -= datalen;
-
-                       /* 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;
-
-       /*
-        * 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);
+                                break;
+
+
+                        case TCPOPT_EOL:
+                        case TCPOPT_NOP:
+                        case TCPOPT_SACKOK:
+                                /*
+                                 * Nothing interesting.
+                                 * fall through
+                                 */
+                                break;
+
+                        default:
+                                datalen = len - 2;
+                                for (i = 0; i < datalen; ++i) {
+                                        LENCHECK(i);
+                                        (void)printf("%02x", cp[i]);
+                                }
+                                break;
+                        }
+
+                        /* Account for data printed */
+                        cp += datalen;
+                        hlen -= datalen;
+
+                        /* 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(']');
+        }
+
+        /*
+         * Print length field before crawling down the stack.
+         */
+        printf(", length %u", length);
+
+        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;
+        } 
+
+        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);
 #ifdef TCPDUMP_DO_SMB
-               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);
 #endif
-               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('>');
 }
 
 /*
@@ -707,96 +693,103 @@ trunc:
 static void
 print_tcp_rst_data(register const u_char *sp, u_int length)
 {
-       int c;
-
-       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(']');
+        int c;
+
+        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(']');
 }
 
 #ifdef HAVE_LIBCRYPTO
 static int
 tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
-    const u_char *data, int length, const u_char *rcvsig)
+                     const u_char *data, int length, const u_char *rcvsig)
 {
         struct tcphdr tp1;
-       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;
 #ifdef INET6
-       struct ip6_hdr *ip6;
+        struct ip6_hdr *ip6;
 #endif
-       u_int32_t len32;
-       u_int8_t nxt;
-
-       tp1 = *tp;
-
-       if (tcpmd5secret == NULL)
-               return (CANT_CHECK_SIGNATURE);
-
-       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));
+        u_int32_t len32;
+        u_int8_t nxt;
+
+        tp1 = *tp;
+
+        if (tcpmd5secret == NULL)
+                return (CANT_CHECK_SIGNATURE);
+
+        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));
 #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));
-               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));
 #endif
-       } else
-               return (CANT_CHECK_SIGNATURE);
-
-       /*
-        * 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);
-
-       if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0)
-               return (SIGNATURE_VALID);
-       else
-               return (SIGNATURE_INVALID);
+        } else
+                return (CANT_CHECK_SIGNATURE);
+
+        /*
+         * 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);
+
+        if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0)
+                return (SIGNATURE_VALID);
+        else
+                return (SIGNATURE_INVALID);
 }
 #endif /* HAVE_LIBCRYPTO */
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/tcp.h b/tcp.h
index 287ad2239796886d5f6eca9e877495759b70482b..0f945ec96f367f3fb34033bd52715fc440d5b602 100644 (file)
--- a/tcp.h
+++ b/tcp.h
@@ -1,4 +1,4 @@
-/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.12 2005-11-29 09:07:47 hannes Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.13 2007-01-29 09:59:42 hannes Exp $ (LBL) */
 /*
  * Copyright (c) 1982, 1986, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -45,21 +45,25 @@ struct tcphdr {
        tcp_seq         th_seq;                 /* sequence number */
        tcp_seq         th_ack;                 /* acknowledgement number */
        u_int8_t        th_offx2;               /* data offset, rsvd */
-#define TH_OFF(th)     (((th)->th_offx2 & 0xf0) >> 4)
        u_int8_t        th_flags;
-#define        TH_FIN  0x01
-#define        TH_SYN  0x02
-#define        TH_RST  0x04
-#define        TH_PUSH 0x08
-#define        TH_ACK  0x10
-#define        TH_URG  0x20
-#define TH_ECNECHO     0x40    /* ECN Echo */
-#define TH_CWR         0x80    /* ECN Cwnd Reduced */
        u_int16_t       th_win;                 /* window */
        u_int16_t       th_sum;                 /* checksum */
        u_int16_t       th_urp;                 /* urgent pointer */
 };
 
+#define TH_OFF(th)     (((th)->th_offx2 & 0xf0) >> 4)
+
+/* TCP flags */
+#define        TH_FIN     0x01
+#define        TH_SYN     0x02
+#define        TH_RST     0x04
+#define        TH_PUSH    0x08
+#define        TH_ACK     0x10
+#define        TH_URG     0x20
+#define TH_ECNECHO 0x40        /* ECN Echo */
+#define TH_CWR    0x80 /* ECN Cwnd Reduced */
+
+
 #define        TCPOPT_EOL              0
 #define        TCPOPT_NOP              1
 #define        TCPOPT_MAXSEG           2
@@ -82,3 +86,20 @@ struct tcphdr {
 
 #define TCPOPT_TSTAMP_HDR      \
     (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+#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
diff --git a/util.c b/util.c
index 963a2dc0d176739e9903b86195cd8fc6aacd8c2a..6b723e543c603c4314af3053c1d28f89db2fb252 100644 (file)
--- a/util.c
+++ b/util.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.108 2006-08-19 06:47:39 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.109 2007-01-29 09:59:42 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -316,11 +316,12 @@ tok2str(register const struct tok *lp, register const char *fmt,
 
 /*
  * Convert a bit token value to a string; use "fmt" if not found.
- * this is useful for parsing bitfields, the output strings are comma seperated
+ * this is useful for parsing bitfields, the output strings are seperated
+ * if the s field is positive.
  */
-char *
-bittok2str(register const struct tok *lp, register const char *fmt,
-          register int v)
+static char *
+bittok2str_internal(register const struct tok *lp, register const char *fmt,
+          register int v, register int sep)
 {
         static char buf[256]; /* our stringbuffer */
         int buflen=0;
@@ -337,7 +338,8 @@ bittok2str(register const struct tok *lp, register const char *fmt,
                  */
                if (tokval == (v&rotbit)) {
                     /* ok we have found something */
-                    buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s, ",lp->s);
+                    buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
+                                     lp->s, sep ? ", " : "");
                     break;
                 }
                 rotbit=rotbit<<1; /* no match - lets shift and try again */
@@ -345,6 +347,11 @@ bittok2str(register const struct tok *lp, register const char *fmt,
             lp++;
        }
 
+        /* user didn't want string seperation - no need to cut off trailing seperators */
+        if (!sep) {
+            return (buf);
+        }
+
         if (buflen != 0) { /* did we find anything */
             /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */
             buf[buflen-2] = '\0';
@@ -359,6 +366,28 @@ bittok2str(register const struct tok *lp, register const char *fmt,
         }
 }
 
+/*
+ * Convert a bit token value to a string; use "fmt" if not found.
+ * this is useful for parsing bitfields, the output strings are not seperated.
+ */
+char *
+bittok2str_nosep(register const struct tok *lp, register const char *fmt,
+          register int v)
+{
+    return (bittok2str_internal(lp, fmt, v, 0));
+}
+
+/*
+ * Convert a bit token value to a string; use "fmt" if not found.
+ * this is useful for parsing bitfields, the output strings are comma seperated.
+ */
+char *
+bittok2str(register const struct tok *lp, register const char *fmt,
+          register int v)
+{
+    return (bittok2str_internal(lp, fmt, v, 1));
+}
+
 /*
  * Convert a value to a string using an array; the macro
  * tok2strary() in <interface.h> is the public interface to