/* * TCPVIEW * * Author: Martin Hunt * Networks and Distributed Computing * Computing & Communications * University of Washington * Administration Building, AG-44 * Seattle, WA 98195 * Internet: martinh@cac.washington.edu * * * Copyright 1992 by the University of Washington * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appears in all copies and that both the * above copyright notice and this permission notice appear in supporting * documentation, and that the name of the University of Washington not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. This software is made * available "as is", and * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ /* * Copyright (c) 1988-1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static char rcsid[] = "@(#) $Header: /usr/staff/martinh/tcpview/RCS/util.c,v 1.2 1993/04/22 20:38:20 martinh Exp $ (UW)"; #endif #include #ifdef __STDC__ #include #endif #include #include #include #include #include #include #include "interface.h" #ifdef TCPVIEW #undef putchar #endif /* Hex digit to integer. */ static inline int xdtoi(c) { if (isdigit(c)) return c - '0'; else if (islower(c)) return c - 'a' + 10; else return c - 'A' + 10; } /* * Convert string to integer. Just like atoi(), but checks for * preceding 0x or 0 and uses hex or octal instead of decimal. */ int stoi(s) char *s; { int base = 10; int n = 0; if (*s == '0') { if (s[1] == 'x' || s[1] == 'X') { s += 2; base = 16; } else { base = 8; s += 1; } } while (*s) n = n * base + xdtoi(*s++); return n; } /* * Print out a filename (or other ascii string). * Return true if truncated. */ int printfn(s, ep) register u_char *s, *ep; { register u_char c; putchar('"'); while (c = *s++) { if (s > ep) { putchar('"'); return(1); } if (!isascii(c)) { c = toascii(c); putchar('M'); putchar('-'); } if (!isprint(c)) { c ^= 0x40; /* DEL to ?, others to alpha */ putchar('^'); } putchar(c); } putchar('"'); return(0); } /* * Print the timestamp */ void ts_print(tvp) register struct timeval *tvp; { register long i,j; static long sec=0,usec=0; static long first_sec=0,first_usec=0; static u_int line=1; #ifdef TCPVIEW extern struct timeval Timeout; extern u_short Line_Flag; /* print line numbers */ extern u_short HighlightTimeout; /* highlight timeouts? */ extern u_short HighlightPacket; /* highlight this packet? */ #else struct timeval Timeout; u_short HighlightTimeout=0; u_short Line_Flag = 0; u_short HighlightPacket; #endif /* if called with 0, reset static counters */ if(tvp==0) { first_sec = first_usec = 0; sec = usec = 0; line = 1; return; } if( Line_Flag ) (void)printf("%05d ",line++); if( HighlightTimeout ) { if (sec) { i = tvp->tv_sec - sec; j = tvp->tv_usec - usec; if ( j<0 ) { j += 1000000; i -= 1; } } else i = j = 0; if( i > Timeout.tv_sec ) HighlightPacket=1; else if( i == Timeout.tv_sec && j > Timeout.tv_usec ) HighlightPacket=1; sec = tvp->tv_sec; usec = tvp->tv_usec; } switch(tflag) { case 1: /* don't print time */ break; case 2: /* Unix timeval style */ (void)printf("%d.%06d ", tvp->tv_sec, tvp->tv_usec); break; case 3: /* Delta times */ if( !HighlightTimeout ) { if (sec) { i = tvp->tv_sec - sec; j = tvp->tv_usec - usec; if ( j<0 ) { j += 1000000; i -= 1; } } else i = j = 0; sec = tvp->tv_sec; usec = tvp->tv_usec; } (void)printf("%d.%06d ", i,j); break; case 4: /* relative times */ if (first_sec==0) { first_sec = tvp->tv_sec; first_usec = tvp->tv_usec; } i = tvp->tv_sec - first_sec; j = tvp->tv_usec - first_usec; if ( j<0 ) { j += 1000000; i -= 1; } (void)printf("%d.%06d ", i,j); break; default: /* Default */ i = (tvp->tv_sec + thiszone) % 86400; (void)printf("%02d:%02d:%02d.%06d ", i / 3600, (i % 3600) / 60, i % 60, tvp->tv_usec); } } #ifdef NOVFPRINTF /* * Stock 4.3 doesn't have vfprintf. * This routine is due to Chris Torek. */ vfprintf(f, fmt, args) FILE *f; char *fmt; va_list args; { int ret; if ((f->_flag & _IOWRT) == 0) { if (f->_flag & _IORW) f->_flag |= _IOWRT; else return EOF; } ret = _doprnt(fmt, args, f); return ferror(f) ? EOF : ret; } #endif static char * stripdir(s) register char *s; { register char *cp; char *rindex(); cp = rindex(s, '/'); return (cp != 0) ? cp + 1 : s; } void error(char *cp, ...) { va_list ap; (void)fprintf(stderr, "%s: ", stripdir(program_name)); va_start(ap, cp); (void)vfprintf(stderr, cp, ap); va_end(ap); if (*cp) { cp += strlen(cp); if (cp[-1] != '\n') (void)fputc('\n', stderr); } exit(1); /* NOTREACHED */ } /* VARARGS */ void warning(char *cp, ...) { va_list ap; (void)fprintf(stderr, "%s: warning: ", stripdir(program_name)); va_start(ap, cp); (void)vfprintf(stderr, cp, ap); va_end(ap); if (*cp) { cp += strlen(cp); if (cp[-1] != '\n') (void)fputc('\n', stderr); } } #ifndef TCPVIEW /* * Copy arg vector into a new buffer, concatenating arguments with spaces. */ char * copy_argv(argv) register char **argv; { register char **p; register int len = 0; char *buf; char *src, *dst; p = argv; if (*p == 0) return 0; while (*p) len += strlen(*p++) + 1; buf = malloc(len); p = argv; dst = buf; while (src = *p++) { while (*dst++ = *src++) ; dst[-1] = ' '; } dst[-1] = '\0'; return buf; } char * read_infile(fname) char *fname; { struct stat buf; int fd; char *p; fd = open(fname, O_RDONLY); if (fd < 0) error("can't open '%s'", fname); if (fstat(fd, &buf) < 0) error("can't state '%s'", fname); p = malloc((unsigned)buf.st_size); if (read(fd, p, (int)buf.st_size) != buf.st_size) error("problem reading '%s'", fname); return p; } #endif /* TCPVIEW */ /* * Left justify 'addr' and return its resulting network mask. */ u_long net_mask(addr) u_long *addr; { register u_long m = 0xffffffff; if (*addr) while ((*addr & 0xff000000) == 0) *addr <<= 8, m <<= 8; return m; }