--- tcpshow.c.orig Sun Mar 23 23:32:50 2003 +++ tcpshow.c Sun Mar 23 23:32:50 2003 @@ -189,6 +189,7 @@ /****==========------------------------------------------------==========****/ #endif +/* tm020221: modification of Tomo.M on 2002/02/21 */ #include // mr971021 Next four includes #include @@ -204,6 +205,7 @@ #include #include #include +#include /* Some general defines. */ @@ -362,18 +364,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 +516,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 +796,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 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 +1145,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 +1165,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; @@ -1241,6 +1263,15 @@ } +void checklocale(void) { + + char *lc; + + if ((lc = getenv("LC_CTYPE")) != NULL) setlocale(LC_CTYPE,lc); + else if ((lc = getenv("LC_ALL")) != NULL) setlocale(LC_ALL,lc); + + return; +} /****==========------------------------------------------------==========****/ /* */ @@ -1248,7 +1279,7 @@ /* */ /****==========------------------------------------------------==========****/ -void main (int argc, char **argv) { +int main (int argc, char **argv) { /* Command line options. */ while (--argc > 0 && **++argv == '-') @@ -1281,15 +1312,23 @@ } else error("Unknown command line flag"); + checklocale(); + if (!cookedFlag) forkTcpdump(argc, argv); 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 +1375,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 +1619,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 +1638,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 +1654,7 @@ if (!noEtherNames) printf(" (%s)", etherName(eTo, FALSE)); printf("\n\tEncapsulated Protocol:\t\t%s\n", etherProto(eType, 0)); } + } return getPkt(); @@ -1778,7 +1819,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 +1848,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 +1892,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 +2062,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 +2082,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",