util.c revision 56893
1184610Salfred/* 2184610Salfred * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3184610Salfred * The Regents of the University of California. All rights reserved. 4184610Salfred * 5184610Salfred * Redistribution and use in source and binary forms, with or without 6184610Salfred * modification, are permitted provided that: (1) source code distributions 7184610Salfred * retain the above copyright notice and this paragraph in its entirety, (2) 8184610Salfred * distributions including binary code include the above copyright notice and 9184610Salfred * this paragraph in its entirety in the documentation or other materials 10184610Salfred * provided with the distribution, and (3) all advertising materials mentioning 11184610Salfred * features or use of this software display the following acknowledgement: 12184610Salfred * ``This product includes software developed by the University of California, 13184610Salfred * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14184610Salfred * the University nor the names of its contributors may be used to endorse 15184610Salfred * or promote products derived from this software without specific prior 16184610Salfred * written permission. 17184610Salfred * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18184610Salfred * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19184610Salfred * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20184610Salfred */ 21184610Salfred 22184610Salfred#ifndef lint 23184610Salfredstatic const char rcsid[] = 24184610Salfred "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.62 1999/12/15 06:58:03 fenner Exp $ (LBL)"; 25184610Salfred#endif 26184610Salfred 27246122Shselasky#ifdef HAVE_CONFIG_H 28246122Shselasky#include "config.h" 29246122Shselasky#endif 30194677Sthompsa 31194677Sthompsa#include <sys/types.h> 32194677Sthompsa#include <sys/time.h> 33194677Sthompsa#include <sys/file.h> 34194677Sthompsa#include <sys/stat.h> 35194677Sthompsa 36194677Sthompsa#include <ctype.h> 37194677Sthompsa#include <errno.h> 38194677Sthompsa#ifdef HAVE_FCNTL_H 39194677Sthompsa#include <fcntl.h> 40194677Sthompsa#endif 41194677Sthompsa#ifdef HAVE_MALLOC_H 42194677Sthompsa#include <malloc.h> 43194677Sthompsa#endif 44194677Sthompsa#include <pcap.h> 45194677Sthompsa#include <stdio.h> 46194677Sthompsa#if __STDC__ 47194677Sthompsa#include <stdarg.h> 48184610Salfred#else 49194677Sthompsa#include <varargs.h> 50194677Sthompsa#endif 51246122Shselasky#include <stdlib.h> 52184610Salfred#include <string.h> 53188048Sthompsa#ifdef TIME_WITH_SYS_TIME 54188048Sthompsa#include <time.h> 55188076Sthompsa#endif 56188076Sthompsa#include <unistd.h> 57188076Sthompsa 58188076Sthompsa#include "interface.h" 59188076Sthompsa 60188048Sthompsa/* 61188048Sthompsa * Print out a filename (or other ascii string). 62188048Sthompsa * If ep is NULL, assume no truncation check is needed. 63188076Sthompsa * Return true if truncated. 64188048Sthompsa */ 65188048Sthompsaint 66188048Sthompsafn_print(register const u_char *s, register const u_char *ep) 67188076Sthompsa{ 68188076Sthompsa register int ret; 69188076Sthompsa register u_char c; 70188048Sthompsa 71188076Sthompsa ret = 1; /* assume truncated */ 72188076Sthompsa while (ep == NULL || s < ep) { 73188076Sthompsa c = *s++; 74188076Sthompsa if (c == '\0') { 75188048Sthompsa ret = 0; 76188048Sthompsa break; 77188076Sthompsa } 78188076Sthompsa if (!isascii(c)) { 79188076Sthompsa c = toascii(c); 80188076Sthompsa putchar('M'); 81188076Sthompsa putchar('-'); 82188076Sthompsa } 83188048Sthompsa if (!isprint(c)) { 84188076Sthompsa c ^= 0x40; /* DEL to ?, others to alpha */ 85184610Salfred putchar('^'); 86194228Sthompsa } 87184610Salfred putchar(c); 88184610Salfred } 89184610Salfred return(ret); 90184610Salfred} 91194228Sthompsa 92184610Salfred/* 93188048Sthompsa * Print out a counted filename (or other ascii string). 94184610Salfred * If ep is NULL, assume no truncation check is needed. 95 * Return true if truncated. 96 */ 97int 98fn_printn(register const u_char *s, register u_int n, 99 register const u_char *ep) 100{ 101 register int ret; 102 register u_char c; 103 104 ret = 1; /* assume truncated */ 105 while (ep == NULL || s < ep) { 106 if (n-- <= 0) { 107 ret = 0; 108 break; 109 } 110 c = *s++; 111 if (!isascii(c)) { 112 c = toascii(c); 113 putchar('M'); 114 putchar('-'); 115 } 116 if (!isprint(c)) { 117 c ^= 0x40; /* DEL to ?, others to alpha */ 118 putchar('^'); 119 } 120 putchar(c); 121 } 122 return(ret); 123} 124 125/* 126 * Print the timestamp 127 */ 128void 129ts_print(register const struct timeval *tvp) 130{ 131 register int s; 132 133 if (tflag > 0) { 134 /* Default */ 135 s = (tvp->tv_sec + thiszone) % 86400; 136 (void)printf("%02d:%02d:%02d.%06u ", 137 s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); 138 } else if (tflag < 0) { 139 if (tflag < -1) { 140 static unsigned b_sec; 141 static unsigned b_usec; 142 if (b_sec == 0) { 143 printf("000000 "); 144 } else { 145 int d_usec = tvp->tv_usec - b_usec; 146 int d_sec = tvp->tv_sec - b_sec; 147 148 while (d_usec < 0) { 149 d_usec += 1000000; 150 d_sec--; 151 } 152 if (d_sec) 153 printf("%d. ", d_sec); 154 printf("%06d ", d_usec); 155 } 156 b_sec = tvp->tv_sec; 157 b_usec = tvp->tv_usec; 158 } else { 159 /* Unix timeval style */ 160 (void)printf("%u.%06u ", 161 (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec); 162 } 163 } 164} 165 166/* 167 * Print a relative number of seconds (e.g. hold time, prune timer) 168 * in the form 5m1s. This does no truncation, so 32230861 seconds 169 * is represented as 1y1w1d1h1m1s. 170 */ 171void 172relts_print(int secs) 173{ 174 static char *lengths[]={"y","w","d","h","m","s"}; 175 static int seconds[]={31536000,604800,86400,3600,60,1}; 176 char **l = lengths; 177 int *s = seconds; 178 179 if (secs == 0) { 180 (void)printf("0s"); 181 return; 182 } 183 while (secs) { 184 if (secs >= *s) { 185 (void)printf("%d%s", secs / *s, *l); 186 secs -= (secs / *s) * *s; 187 } 188 s++; l++; 189 } 190} 191 192/* 193 * Convert a token value to a string; use "fmt" if not found. 194 */ 195const char * 196tok2str(register const struct tok *lp, register const char *fmt, 197 register int v) 198{ 199 static char buf[128]; 200 201 while (lp->s != NULL) { 202 if (lp->v == v) 203 return (lp->s); 204 ++lp; 205 } 206 if (fmt == NULL) 207 fmt = "#%d"; 208 (void)sprintf(buf, fmt, v); 209 return (buf); 210} 211 212 213/* VARARGS */ 214__dead void 215#if __STDC__ 216error(const char *fmt, ...) 217#else 218error(fmt, va_alist) 219 const char *fmt; 220 va_dcl 221#endif 222{ 223 va_list ap; 224 225 (void)fprintf(stderr, "%s: ", program_name); 226#if __STDC__ 227 va_start(ap, fmt); 228#else 229 va_start(ap); 230#endif 231 (void)vfprintf(stderr, fmt, ap); 232 va_end(ap); 233 if (*fmt) { 234 fmt += strlen(fmt); 235 if (fmt[-1] != '\n') 236 (void)fputc('\n', stderr); 237 } 238 exit(1); 239 /* NOTREACHED */ 240} 241 242/* VARARGS */ 243void 244#if __STDC__ 245warning(const char *fmt, ...) 246#else 247warning(fmt, va_alist) 248 const char *fmt; 249 va_dcl 250#endif 251{ 252 va_list ap; 253 254 (void)fprintf(stderr, "%s: WARNING: ", program_name); 255#if __STDC__ 256 va_start(ap, fmt); 257#else 258 va_start(ap); 259#endif 260 (void)vfprintf(stderr, fmt, ap); 261 va_end(ap); 262 if (*fmt) { 263 fmt += strlen(fmt); 264 if (fmt[-1] != '\n') 265 (void)fputc('\n', stderr); 266 } 267} 268 269/* 270 * Copy arg vector into a new buffer, concatenating arguments with spaces. 271 */ 272char * 273copy_argv(register char **argv) 274{ 275 register char **p; 276 register u_int len = 0; 277 char *buf; 278 char *src, *dst; 279 280 p = argv; 281 if (*p == 0) 282 return 0; 283 284 while (*p) 285 len += strlen(*p++) + 1; 286 287 buf = (char *)malloc(len); 288 if (buf == NULL) 289 error("copy_argv: malloc"); 290 291 p = argv; 292 dst = buf; 293 while ((src = *p++) != NULL) { 294 while ((*dst++ = *src++) != '\0') 295 ; 296 dst[-1] = ' '; 297 } 298 dst[-1] = '\0'; 299 300 return buf; 301} 302 303char * 304read_infile(char *fname) 305{ 306 register int fd, cc; 307 register char *cp; 308 struct stat buf; 309 310 fd = open(fname, O_RDONLY); 311 if (fd < 0) 312 error("can't open %s: %s", fname, pcap_strerror(errno)); 313 314 if (fstat(fd, &buf) < 0) 315 error("can't stat %s: %s", fname, pcap_strerror(errno)); 316 317 cp = malloc((u_int)buf.st_size + 1); 318 cc = read(fd, cp, (int)buf.st_size); 319 if (cc < 0) 320 error("read %s: %s", fname, pcap_strerror(errno)); 321 if (cc != buf.st_size) 322 error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); 323 cp[(int)buf.st_size] = '\0'; 324 325 return (cp); 326} 327