1 /* $OpenBSD: util.c,v 1.11 2001/03/05 22:34:01 jakob Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #ifndef lint 25 static const char rcsid[] = 26 "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/util.c,v 1.11 2001/03/05 22:34:01 jakob Exp $ (LBL)"; 27 #endif 28 29 #include <sys/types.h> 30 #include <sys/time.h> 31 #include <sys/file.h> 32 #include <sys/stat.h> 33 34 #include <ctype.h> 35 #include <errno.h> 36 #ifdef HAVE_FCNTL_H 37 #include <fcntl.h> 38 #endif 39 #include <pcap.h> 40 #include <stdio.h> 41 #ifdef __STDC__ 42 #include <stdarg.h> 43 #else 44 #include <varargs.h> 45 #endif 46 #include <stdlib.h> 47 #include <string.h> 48 #ifdef TIME_WITH_SYS_TIME 49 #include <time.h> 50 #endif 51 #include <unistd.h> 52 53 #include "interface.h" 54 55 /* 56 * Print out a filename (or other ascii string). 57 * If ep is NULL, assume no truncation check is needed. 58 * Return true if truncated. 59 */ 60 int 61 fn_print(register const u_char *s, register const u_char *ep) 62 { 63 register int ret; 64 register u_char c; 65 66 ret = 1; /* assume truncated */ 67 while (ep == NULL || s < ep) { 68 c = *s++; 69 if (c == '\0') { 70 ret = 0; 71 break; 72 } 73 if (!isascii(c)) { 74 c = toascii(c); 75 putchar('M'); 76 putchar('-'); 77 } 78 if (!isprint(c)) { 79 c ^= 0x40; /* DEL to ?, others to alpha */ 80 putchar('^'); 81 } 82 putchar(c); 83 } 84 return(ret); 85 } 86 87 /* 88 * Print out a counted filename (or other ascii string). 89 * If ep is NULL, assume no truncation check is needed. 90 * Return true if truncated. 91 */ 92 int 93 fn_printn(register const u_char *s, register u_int n, 94 register const u_char *ep) 95 { 96 register int ret; 97 register u_char c; 98 99 ret = 1; /* assume truncated */ 100 while (ep == NULL || s < ep) { 101 if (n-- <= 0) { 102 ret = 0; 103 break; 104 } 105 c = *s++; 106 if (!isascii(c)) { 107 c = toascii(c); 108 putchar('M'); 109 putchar('-'); 110 } 111 if (!isprint(c)) { 112 c ^= 0x40; /* DEL to ?, others to alpha */ 113 putchar('^'); 114 } 115 putchar(c); 116 } 117 return(ret); 118 } 119 120 /* 121 * Print the timestamp 122 */ 123 void 124 ts_print(register const struct timeval *tvp) 125 { 126 register int s; 127 128 if (tflag > 0) { 129 /* Default */ 130 s = (tvp->tv_sec + thiszone) % 86400; 131 (void)printf("%02d:%02d:%02d.%06u ", 132 s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec); 133 } else if (tflag < 0) { 134 /* Unix timeval style */ 135 (void)printf("%u.%06u ", 136 (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec); 137 } 138 } 139 140 /* 141 * Print a relative number of seconds (e.g. hold time, prune timer) 142 * in the form 5m1s. This does no truncation, so 32230861 seconds 143 * is represented as 1y1w1d1h1m1s. 144 */ 145 void 146 relts_print(int secs) 147 { 148 static char *lengths[] = {"y", "w", "d", "h", "m", "s"}; 149 static int seconds[] = {31536000, 604800, 86400, 3600, 60, 1}; 150 char **l = lengths; 151 int *s = seconds; 152 153 if (secs <= 0) { 154 (void)printf("0s"); 155 return; 156 } 157 while (secs > 0) { 158 if (secs >= *s) { 159 (void)printf("%d%s", secs / *s, *l); 160 secs -= (secs / *s) * *s; 161 } 162 s++; 163 l++; 164 } 165 } 166 167 /* 168 * Convert a token value to a string; use "fmt" if not found. 169 */ 170 const char * 171 tok2str(register const struct tok *lp, register const char *fmt, 172 register int v) 173 { 174 static char buf[128]; 175 176 while (lp->s != NULL) { 177 if (lp->v == v) 178 return (lp->s); 179 ++lp; 180 } 181 if (fmt == NULL) 182 fmt = "#%d"; 183 (void)snprintf(buf, sizeof(buf), fmt, v); 184 return (buf); 185 } 186 187 188 /* VARARGS */ 189 __dead void 190 #ifdef __STDC__ 191 error(const char *fmt, ...) 192 #else 193 error(fmt, va_alist) 194 const char *fmt; 195 va_dcl 196 #endif 197 { 198 va_list ap; 199 200 (void)fprintf(stderr, "%s: ", program_name); 201 #ifdef __STDC__ 202 va_start(ap, fmt); 203 #else 204 va_start(ap); 205 #endif 206 (void)vfprintf(stderr, fmt, ap); 207 va_end(ap); 208 if (*fmt) { 209 fmt += strlen(fmt); 210 if (fmt[-1] != '\n') 211 (void)fputc('\n', stderr); 212 } 213 exit(1); 214 /* NOTREACHED */ 215 } 216 217 /* VARARGS */ 218 void 219 #ifdef __STDC__ 220 warning(const char *fmt, ...) 221 #else 222 warning(fmt, va_alist) 223 const char *fmt; 224 va_dcl 225 #endif 226 { 227 va_list ap; 228 229 (void)fprintf(stderr, "%s: WARNING: ", program_name); 230 #ifdef __STDC__ 231 va_start(ap, fmt); 232 #else 233 va_start(ap); 234 #endif 235 (void)vfprintf(stderr, fmt, ap); 236 va_end(ap); 237 if (*fmt) { 238 fmt += strlen(fmt); 239 if (fmt[-1] != '\n') 240 (void)fputc('\n', stderr); 241 } 242 } 243 244 /* 245 * Copy arg vector into a new buffer, concatenating arguments with spaces. 246 */ 247 char * 248 copy_argv(register char **argv) 249 { 250 register char **p; 251 register u_int len = 0; 252 char *buf; 253 char *src, *dst; 254 255 p = argv; 256 if (*p == 0) 257 return 0; 258 259 while (*p) 260 len += strlen(*p++) + 1; 261 262 buf = (char *)malloc(len); 263 if (buf == NULL) 264 error("copy_argv: malloc"); 265 266 p = argv; 267 dst = buf; 268 while ((src = *p++) != NULL) { 269 while ((*dst++ = *src++) != '\0') 270 ; 271 dst[-1] = ' '; 272 } 273 dst[-1] = '\0'; 274 275 return buf; 276 } 277 278 char * 279 read_infile(char *fname) 280 { 281 register int fd, cc; 282 register char *cp; 283 struct stat buf; 284 285 fd = open(fname, O_RDONLY); 286 if (fd < 0) 287 error("can't open %s: %s", fname, pcap_strerror(errno)); 288 289 if (fstat(fd, &buf) < 0) 290 error("can't stat %s: %s", fname, pcap_strerror(errno)); 291 292 cp = malloc((u_int)buf.st_size + 1); 293 cc = read(fd, cp, (int)buf.st_size); 294 if (cc < 0) 295 error("read %s: %s", fname, pcap_strerror(errno)); 296 if (cc != buf.st_size) 297 error("short read %s (%d != %d)", fname, cc, (int)buf.st_size); 298 cp[(int)buf.st_size] = '\0'; 299 300 return (cp); 301 } 302 303 void 304 safeputs(const char *s) 305 { 306 while (*s) { 307 safeputchar(*s); 308 s++; 309 } 310 } 311 312 void 313 safeputchar(int c) 314 { 315 unsigned char ch; 316 317 ch = (unsigned char)(c & 0xff); 318 if (c < 0x80 && isprint(c)) 319 printf("%c", c & 0xff); 320 else 321 printf("\\%03o", c & 0xff); 322 } 323