--- tcpshow.c.orig	Sun Jul 19 09:00:00 1998
+++ tcpshow.c	Fri Feb 22 00:13:57 2002
@@ -189,6 +189,7 @@
 /****==========------------------------------------------------==========****/
 #endif
 
+/* tm020221: modification of Tomo.M on 2002/02/21 */ 
 
 #include <sys/types.h>                 // mr971021 Next four includes
 #include <sys/socket.h>
@@ -362,18 +363,20 @@
 #if !defined(NOETHERNAMES)
 // mr980118 ether_ntohost() and related functions aren't prototyped in the
 // standard include directory.
+#ifndef __FreeBSD__
 extern struct ether_addr *ether_aton(char *);
 extern int ether_ntohost(char *, struct ether_addr *);
 #endif
+#endif
 
 
-void main(int, char **);
+int main(int, char **);
 
 
 static boolean noBflag = FALSE;
 static char *cookArgs[MAXCOOKARGS+1];
 static boolean cookedFlag = FALSE;
-static uint2 dataLen = 0;
+static int2 dataLen = 0;               // tm020221 must be 'signed'.
 static char *dfltCookArgs[] = {
    COOKER, "-enx", "-s10240", "-r-", (char *)NULL
 };
@@ -512,7 +515,9 @@
       return "";
    }
 
-   delta = currTime - *prevTime;
+   // tm020221 delta should be positive value, but ...
+   delta = currTime >= *prevTime ? currTime - *prevTime
+              : multiplier * 86400 + currTime - *prevTime;
    *prevTime = currTime;
 
    // Convert the delta time to daytime representation.
@@ -790,25 +795,39 @@
    static boolean beenHereAlready = FALSE;
    static char pktBuf[MAXPKT+1];
 
-
+ nextline:
    if (fgets(pktBuf, MAXPKT+1, stdin) == (char *)NULL) {
       if (nPktsShown > 0) prSep();
       exit(0);
    }
 
-   /* Line without leading <tab> means start of new packet.                 */
-   if (*pktBuf == '\t')
-      return pkt = rmWSpace(pktBuf);
-   elif (!beenHereAlready) {           /* setjmp() won't have been called   */
-      beenHereAlready = TRUE;          /*  before reading 1st packet        */
-      return pkt = pktBuf;
-   }
-   else {
-      if (dataLen > 0)
-         printf("\n\t<*** Rest of data missing from packet dump ***>\n");
-      pkt = pktBuf;
-      longjmp(jmpBuf, 1);
+   // tm020221
+   // In these days, tcpdump produces much of irregular outputs.
+   // I had a work around by making logical change to original.
+   //  + check lines in its pattern.
+   //  + HEADER pattern triggers next showPkt();
+
+#define PTN_HEAD(buf)  (buf[2] == ':' && buf[5] == ':' && buf[8] == '.')
+#define PTN_DATA(buf)  (buf[0] == '\t' && buf[1] == '\t' \
+                                && buf[2] == '\t' && buf[3] == ' ')
+
+   if (PTN_HEAD(pktBuf)) {
+     if (beenHereAlready == FALSE) {
+       beenHereAlready = TRUE;
+       return pkt = pktBuf;
+     } else {
+       putchar('\n');
+       if (dataLen > 0)
+	 printf("\n\t<*** Rest of data missing from packet dump ***>\n");
+       pkt = pktBuf;
+       longjmp(jmpBuf, 1);
+     }
+   }
+   elif (PTN_DATA(pktBuf)) {
+     if (nPktsShown > 0)
+       return pkt = rmWSpace(pktBuf);
    }
+   goto nextline;
 
 }
 
@@ -1125,7 +1144,9 @@
 static char *icmpType (uint1 type) {
 
    char *descr;
+   static char unknowntype[80];
 
+   snprintf(unknowntype, 80, "%s (%d)", unknown, type);
 
    switch (type) {
     case ECHO_REPLY:  descr = "echo-reply";              break;
@@ -1143,7 +1164,7 @@
     case INFO_REPLY:  descr = "information-reply";       break;
     case MASK_REQ:    descr = "address-mask-request";    break;
     case MASK_REPLY:  descr = "address-mask-reply";      break;
-    default:          descr = unknown;                   break;
+    default:          descr = unknowntype;               break;
    }
 
    return descr;
@@ -1248,7 +1269,7 @@
 /*                                                                          */
 /****==========------------------------------------------------==========****/
 
-void main (int argc, char **argv) {
+int main (int argc, char **argv) {
 
    /* Command line options.                                                 */
    while (--argc > 0 && **++argv == '-')
@@ -1286,10 +1307,16 @@
    elif (argc != 0)
       fprintf(stderr, "input is cooked -- ignoring tcpdump expressions\n");
 
-   pkt = getPkt();
-   for ( ; ; ) if (!setjmp(jmpBuf)) showPkt(pkt);
+   // tm020221
+   // changed setjmp/longjmp logic to trigger the showPkt()
+   for ( ; ; ) {
+     pkt = getPkt();
+     if (setjmp(jmpBuf) || nPktsShown <= 0)
+       showPkt(pkt);
+   }
 
    exit(0);
+   return 0;
 
 }
 
@@ -1336,7 +1363,7 @@
 	 name = number;
       }
    /* The crappy manpage doesn't say the port must be in net byte order.    */
-   elif (service = getservbyport((int)htons(port), proto))
+   elif ( (service = getservbyport((int)htons(port), proto)) )
       name = service->s_name;
    elif (!wantNumber)
       name = unknown;
@@ -1580,13 +1607,14 @@
    if (ppFlag) {
       (void)sscanf(p, "%s", time);
       etherType = ETHER_PROTO_IP;      /* tcpdump doesn't supply link type  */
-      if (!noLinkFlag)
+      if (!noLinkFlag) {
          if (terseFlag)
 	    printf("TIME:\t%s%s\n", time, deltaTime(&prevTime, time));
          else
 	    printf(
 	       "\tTimestamp:\t\t\t%s%s\n", time, deltaTime(&prevTime, time)
 	    );
+	}
       return getPkt();
    }
 
@@ -1598,7 +1626,7 @@
    (void)strcpy(eTo, etherAddr(eTo, 0));
    (void)strcpy(eToName, etherName(eTo, TRUE));
 
-   if (!noLinkFlag)
+   if (!noLinkFlag) {
       if (terseFlag) {
          printf("TIME:\t%s%s\n", time, deltaTime(&prevTime, time));
          printf(
@@ -1614,6 +1642,7 @@
          if (!noEtherNames) printf(" (%s)", etherName(eTo, FALSE));
          printf("\n\tEncapsulated Protocol:\t\t%s\n", etherProto(eType, 0));
       }
+   }
 
    return getPkt();
 
@@ -1778,7 +1807,7 @@
 static void showPkt (reg char *p) {
 
    char *warnMsg = "<*** No decode support for encapsulated protocol ***>";
-
+   char *warnMsg2 = "<*** No decode support for encap protocol in IPIP packet ***>";
 
    prSep();
    printf("Packet %d\n", ++nPktsShown);
@@ -1807,6 +1836,31 @@
 	 p = showIcmp(p);
 	 p = showData(p);
 	 break;
+	 
+	 // IPIP decode support by M. Nowlin (mike@argos.org) 20000321
+       case IPIP:
+	  p = showIp(p);
+	  switch(proto) {
+	   case TCP:
+	     p = showTcp(p);
+	     p = showData(p);
+	     break;
+	   case UDP:
+	     p = showUdp(p);
+	     p = showData(p);
+	     break;
+	   case ICMP:
+	     p = showIcmp(p);
+	     p = showData(p);
+	     break;
+	   default:
+	     printf("\t%s\n", warnMsg2);
+	     nextPkt();
+	     break;
+	 }
+	 
+	 break;
+	  
        default:
 	 printf("\t%s\n", warnMsg);
 	 nextPkt();                    /* Doesn't return                    */
@@ -1826,7 +1880,7 @@
    }
    /* Note that if getPkt() returns here, then the line read isn't the      */
    /* start of a new packet, i.e. there's spurious data.                    */
-   if (p = getPkt()) {
+   if ( (p = getPkt()) ) {
       if (sFlag) printf("\t<*** Spurious data at end: \"%s\" ***>\n", p);
       nextPkt();
    }
@@ -1996,10 +2050,10 @@
 
    if (terseFlag) {
       printf(
-	 " TCP:\tport %s -> %s seq=%010lu", sPortName, dPortName, seq
+	 " TCP:\tport %s -> %s seq=%010lu", sPortName, dPortName, (u_long)seq
       );
-      if (trackFlag) printf(" (expect=%010lu)", expect);
-      printf(" ack=%010lu\n", ack);
+      if (trackFlag) printf(" (expect=%010lu)", (u_long)expect);
+      printf(" ack=%010lu\n", (u_long)ack);
       printf(
          "\thlen=%d (data=%u) UAPRSF=%s%s%s%s%s%s",
          hLen, dataLen,
@@ -2016,9 +2070,9 @@
       if (!noPortNames) printf(" (%s)", portName(sPort, "tcp", FALSE));
       printf("\n\tDestination Port:\t\t%d", dPort);
       if (!noPortNames) printf(" (%s)", portName(dPort, "tcp", FALSE));
-      printf("\n\tSequence Number:\t\t%010lu\n", seq);
-      if (trackFlag) printf("\tExpect peer ACK:\t\t%010lu\n", expect);
-      printf("\tAcknowledgement Number:\t\t%010lu\n", ack);
+      printf("\n\tSequence Number:\t\t%010lu\n", (u_long)seq);
+      if (trackFlag) printf("\tExpect peer ACK:\t\t%010lu\n", (u_long)expect);
+      printf("\tAcknowledgement Number:\t\t%010lu\n", (u_long)ack);
       printf("\tHeader Length:\t\t\t%d bytes (data=%u)\n", hLen, dataLen);
       printf(
          "\tFlags:%s%s%s%s%s%s\n%s%s%s%s%s%s\n",
