1/* 2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and --- 7 unchanged lines hidden (view full) --- 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22#ifndef lint 23static const char rcsid[] _U_ = |
24 "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.109 2007-01-29 09:59:42 hannes Exp $ (LBL)"; |
25#endif 26 27#ifdef HAVE_CONFIG_H 28#include "config.h" 29#endif 30 31#include <tcpdump-stdinc.h> 32 --- 6 unchanged lines hidden (view full) --- 39#include <pcap.h> 40#include <stdio.h> 41#include <stdarg.h> 42#include <stdlib.h> 43#include <string.h> 44 45#include "interface.h" 46 |
47char * ts_format(register int, register int); 48 |
49/* 50 * Print out a null-terminated filename (or other ascii string). 51 * If ep is NULL, assume no truncation check is needed. 52 * Return true if truncated. 53 */ 54int 55fn_print(register const u_char *s, register const u_char *ep) 56{ --- 79 unchanged lines hidden (view full) --- 136 putchar('^'); 137 } 138 putchar(c); 139 } 140 return (n == 0) ? 0 : ret; 141} 142 143/* |
144 * Format the timestamp 145 */ 146char * 147ts_format(register int sec, register int usec) 148{ 149 static char buf[sizeof("00:00:00.000000")]; 150 (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u", 151 sec / 3600, (sec % 3600) / 60, sec % 60, usec); 152 153 return buf; 154} 155 156/* |
157 * Print the timestamp 158 */ 159void 160ts_print(register const struct timeval *tvp) 161{ 162 register int s; 163 struct tm *tm; 164 time_t Time; 165 static unsigned b_sec; 166 static unsigned b_usec; |
167 int d_usec; 168 int d_sec; |
169 170 switch (tflag) { 171 172 case 0: /* Default */ 173 s = (tvp->tv_sec + thiszone) % 86400; |
174 (void)printf("%s ", ts_format(s, tvp->tv_usec)); |
175 break; 176 177 case 1: /* No time stamp */ 178 break; 179 180 case 2: /* Unix timeval style */ 181 (void)printf("%u.%06u ", 182 (unsigned)tvp->tv_sec, 183 (unsigned)tvp->tv_usec); 184 break; 185 186 case 3: /* Microseconds since previous packet */ |
187 case 5: /* Microseconds since first packet */ |
188 if (b_sec == 0) { |
189 /* init timestamp for first packet */ 190 b_usec = tvp->tv_usec; 191 b_sec = tvp->tv_sec; 192 } |
193 |
194 d_usec = tvp->tv_usec - b_usec; 195 d_sec = tvp->tv_sec - b_sec; 196 197 while (d_usec < 0) { 198 d_usec += 1000000; 199 d_sec--; 200 } 201 202 (void)printf("%s ", ts_format(d_sec, d_usec)); 203 204 if (tflag == 3) { /* set timestamp for last packet */ 205 b_sec = tvp->tv_sec; 206 b_usec = tvp->tv_usec; 207 } |
208 break; 209 210 case 4: /* Default + Date*/ 211 s = (tvp->tv_sec + thiszone) % 86400; 212 Time = (tvp->tv_sec + thiszone) - s; 213 tm = gmtime (&Time); 214 if (!tm) 215 printf("Date fail "); 216 else |
217 printf("%04d-%02d-%02d %s ", 218 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, 219 ts_format(s, tvp->tv_usec)); |
220 break; 221 } 222} 223 224/* 225 * Print a relative number of seconds (e.g. hold time, prune timer) 226 * in the form 5m1s. This does no truncation, so 32230861 seconds 227 * is represented as 1y1w1d1h1m1s. --- 83 unchanged lines hidden (view full) --- 311 312 ret = buf[idx]; 313 idx = (idx+1) & 3; 314 return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0])); 315} 316 317/* 318 * Convert a bit token value to a string; use "fmt" if not found. |
319 * this is useful for parsing bitfields, the output strings are seperated 320 * if the s field is positive. |
321 */ |
322static char * 323bittok2str_internal(register const struct tok *lp, register const char *fmt, 324 register int v, register int sep) |
325{ 326 static char buf[256]; /* our stringbuffer */ 327 int buflen=0; 328 register int rotbit; /* this is the bit we rotate through all bitpositions */ 329 register int tokval; 330 331 while (lp->s != NULL && lp != NULL) { 332 tokval=lp->v; /* load our first value */ 333 rotbit=1; 334 while (rotbit != 0) { 335 /* 336 * lets AND the rotating bit with our token value 337 * and see if we have got a match 338 */ 339 if (tokval == (v&rotbit)) { 340 /* ok we have found something */ |
341 buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s", 342 lp->s, sep ? ", " : ""); |
343 break; 344 } 345 rotbit=rotbit<<1; /* no match - lets shift and try again */ 346 } 347 lp++; 348 } 349 |
350 /* user didn't want string seperation - no need to cut off trailing seperators */ 351 if (!sep) { 352 return (buf); 353 } 354 |
355 if (buflen != 0) { /* did we find anything */ 356 /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */ 357 buf[buflen-2] = '\0'; 358 return (buf); 359 } 360 else { 361 /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */ 362 if (fmt == NULL) 363 fmt = "#%d"; 364 (void)snprintf(buf, sizeof(buf), fmt, v); 365 return (buf); 366 } 367} 368 369/* |
370 * Convert a bit token value to a string; use "fmt" if not found. 371 * this is useful for parsing bitfields, the output strings are not seperated. 372 */ 373char * 374bittok2str_nosep(register const struct tok *lp, register const char *fmt, 375 register int v) 376{ 377 return (bittok2str_internal(lp, fmt, v, 0)); 378} 379 380/* 381 * Convert a bit token value to a string; use "fmt" if not found. 382 * this is useful for parsing bitfields, the output strings are comma seperated. 383 */ 384char * 385bittok2str(register const struct tok *lp, register const char *fmt, 386 register int v) 387{ 388 return (bittok2str_internal(lp, fmt, v, 1)); 389} 390 391/* |
392 * Convert a value to a string using an array; the macro 393 * tok2strary() in <interface.h> is the public interface to 394 * this function and ensures that the second argument is 395 * correct for bounds-checking. 396 */ 397const char * 398tok2strary_internal(register const char **lp, int n, register const char *fmt, 399 register int v) --- 152 unchanged lines hidden (view full) --- 552 } 553 cp[cc] = '\0'; 554 return (cp); 555} 556 557void 558safeputs(const char *s, int maxlen) 559{ |
560 int idx = 0; 561 |
562 while (*s && idx < maxlen) { 563 safeputchar(*s); 564 idx++; 565 s++; 566 } 567} 568 569void 570safeputchar(int c) 571{ 572 unsigned char ch; 573 574 ch = (unsigned char)(c & 0xff); 575 if (ch < 0x80 && isprint(ch)) 576 printf("%c", ch); 577 else |
578 printf("\\0x%02x", ch); |
579} |