4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
5 * The Regents of the University of California. All rights reserved.
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
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.
24 #include <sys/cdefs.h>
27 static const char rcsid
[] _U_
=
28 "@(#) Header: /tcpdump/master/tcpdump/util.c,v 1.95.2.6 2006/02/08 01:40:09 hannes Exp (LBL)";
30 __RCSID("$NetBSD: tcpdump2rcsid.ex,v 1.1 2001/06/25 20:09:58 itojun Exp $");
38 #include <tcpdump-stdinc.h>
52 #include "interface.h"
55 * Print out a null-terminated filename (or other ascii string).
56 * If ep is NULL, assume no truncation check is needed.
57 * Return true if truncated.
60 fn_print(register const u_char
*s
, register const u_char
*ep
)
65 ret
= 1; /* assume truncated */
66 while (ep
== NULL
|| s
< ep
) {
78 c
^= 0x40; /* DEL to ?, others to alpha */
87 * Print out a counted filename (or other ascii string).
88 * If ep is NULL, assume no truncation check is needed.
89 * Return true if truncated.
92 fn_printn(register const u_char
*s
, register u_int n
,
93 register const u_char
*ep
)
97 while (n
> 0 && (ep
== NULL
|| s
< ep
)) {
106 c
^= 0x40; /* DEL to ?, others to alpha */
111 return (n
== 0) ? 0 : 1;
115 * Print out a null-padded filename (or other ascii string).
116 * If ep is NULL, assume no truncation check is needed.
117 * Return true if truncated.
120 fn_printzp(register const u_char
*s
, register u_int n
,
121 register const u_char
*ep
)
126 ret
= 1; /* assume truncated */
127 while (n
> 0 && (ep
== NULL
|| s
< ep
)) {
140 c
^= 0x40; /* DEL to ?, others to alpha */
145 return (n
== 0) ? 0 : ret
;
149 * Print the timestamp
152 ts_print(register const struct timeval
*tvp
)
157 static unsigned b_sec
;
158 static unsigned b_usec
;
162 case 0: /* Default */
163 s
= (tvp
->tv_sec
+ thiszone
) % 86400;
164 (void)printf("%02d:%02d:%02d.%06u ",
165 s
/ 3600, (s
% 3600) / 60, s
% 60,
166 (unsigned)tvp
->tv_usec
);
169 case 1: /* No time stamp */
172 case 2: /* Unix timeval style */
173 (void)printf("%u.%06u ",
174 (unsigned)tvp
->tv_sec
,
175 (unsigned)tvp
->tv_usec
);
178 case 3: /* Microseconds since previous packet */
182 int d_usec
= tvp
->tv_usec
- b_usec
;
183 int d_sec
= tvp
->tv_sec
- b_sec
;
190 printf("%d. ", d_sec
);
191 printf("%06d ", d_usec
);
194 b_usec
= tvp
->tv_usec
;
197 case 4: /* Default + Date*/
198 s
= (tvp
->tv_sec
+ thiszone
) % 86400;
199 Time
= (tvp
->tv_sec
+ thiszone
) - s
;
202 printf("Date fail ");
204 printf("%04d-%02d-%02d ",
205 tm
->tm_year
+1900, tm
->tm_mon
+1, tm
->tm_mday
);
206 printf("%02d:%02d:%02d.%06u ",
207 s
/ 3600, (s
% 3600) / 60, s
% 60, (unsigned)tvp
->tv_usec
);
213 * Print a relative number of seconds (e.g. hold time, prune timer)
214 * in the form 5m1s. This does no truncation, so 32230861 seconds
215 * is represented as 1y1w1d1h1m1s.
218 relts_print(int secs
)
220 static const char *lengths
[] = {"y", "w", "d", "h", "m", "s"};
221 static const int seconds
[] = {31536000, 604800, 86400, 3600, 60, 1};
222 const char **l
= lengths
;
223 const int *s
= seconds
;
235 (void)printf("%d%s", secs
/ *s
, *l
);
236 secs
-= (secs
/ *s
) * *s
;
244 * this is a generic routine for printing unknown data;
245 * we pass on the linefeed plus indentation string to
246 * get a proper output - returns 0 on error
250 print_unknown_data(const u_char
*cp
,const char *ident
,int len
)
253 printf("%sDissector error: print_unknown_data called with negative length",
257 if (snapend
- cp
< len
)
260 printf("%sDissector error: print_unknown_data called with pointer past end of packet",
264 hex_print(ident
,cp
,len
);
265 return(1); /* everything is ok */
269 * Convert a token value to a string; use "fmt" if not found.
272 tok2strbuf(register const struct tok
*lp
, register const char *fmt
,
273 register int v
, char *buf
, size_t bufsize
)
276 while (lp
->s
!= NULL
) {
285 (void)snprintf(buf
, bufsize
, fmt
, v
);
286 return (const char *)buf
;
290 * Convert a token value to a string; use "fmt" if not found.
293 tok2str(register const struct tok
*lp
, register const char *fmt
,
296 static char buf
[4][128];
302 return tok2strbuf(lp
, fmt
, v
, ret
, sizeof(buf
[0]));
306 * Convert a bit token value to a string; use "fmt" if not found.
307 * this is useful for parsing bitfields, the output strings are comma seperated
310 bittok2str(register const struct tok
*lp
, register const char *fmt
,
313 static char buf
[256]; /* our stringbuffer */
315 register int rotbit
; /* this is the bit we rotate through all bitpositions */
318 while (lp
->s
!= NULL
&& lp
!= NULL
) {
319 tokval
=lp
->v
; /* load our first value */
321 while (rotbit
!= 0) {
323 * lets AND the rotating bit with our token value
324 * and see if we have got a match
326 if (tokval
== (v
&rotbit
)) {
327 /* ok we have found something */
328 buflen
+=snprintf(buf
+buflen
, sizeof(buf
)-buflen
, "%s, ",lp
->s
);
331 rotbit
=rotbit
<<1; /* no match - lets shift and try again */
336 if (buflen
!= 0) { /* did we find anything */
337 /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */
338 buf
[buflen
-2] = '\0';
342 /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
345 (void)snprintf(buf
, sizeof(buf
), fmt
, v
);
351 * Convert a value to a string using an array; the macro
352 * tok2strary() in <interface.h> is the public interface to
353 * this function and ensures that the second argument is
354 * correct for bounds-checking.
357 tok2strary_internal(register const char **lp
, int n
, register const char *fmt
,
360 static char buf
[128];
362 if (v
>= 0 && v
< n
&& lp
[v
] != NULL
)
366 (void)snprintf(buf
, sizeof(buf
), fmt
, v
);
371 * Convert a 32-bit netmask to prefixlen if possible
372 * the function returns the prefix-len; if plen == -1
373 * then conversion was not possible;
377 mask2plen (u_int32_t mask
)
379 u_int32_t bitmasks
[33] = {
381 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
382 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
383 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
384 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
385 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
386 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
387 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
388 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
392 /* let's see if we can transform the mask into a prefixlen */
393 while (prefix_len
>= 0) {
394 if (bitmasks
[prefix_len
] == mask
)
403 error(const char *fmt
, ...)
407 (void)fprintf(stderr
, "%s: ", program_name
);
409 (void)vfprintf(stderr
, fmt
, ap
);
414 (void)fputc('\n', stderr
);
422 warning(const char *fmt
, ...)
426 (void)fprintf(stderr
, "%s: WARNING: ", program_name
);
428 (void)vfprintf(stderr
, fmt
, ap
);
433 (void)fputc('\n', stderr
);
438 * Copy arg vector into a new buffer, concatenating arguments with spaces.
441 copy_argv(register char **argv
)
444 register u_int len
= 0;
453 len
+= strlen(*p
++) + 1;
455 buf
= (char *)malloc(len
);
457 error("copy_argv: malloc");
461 while ((src
= *p
++) != NULL
) {
462 while ((*dst
++ = *src
++) != '\0')
472 * On Windows, we need to open the file in binary mode, so that
473 * we get all the bytes specified by the size we get from "fstat()".
474 * On UNIX, that's not necessary. O_BINARY is defined on Windows;
475 * we define it as 0 if it's not defined, so it does nothing.
482 read_infile(char *fname
)
484 register int i
, fd
, cc
;
488 fd
= open(fname
, O_RDONLY
|O_BINARY
);
490 error("can't open %s: %s", fname
, pcap_strerror(errno
));
492 if (fstat(fd
, &buf
) < 0)
493 error("can't stat %s: %s", fname
, pcap_strerror(errno
));
495 cp
= malloc((u_int
)buf
.st_size
+ 1);
497 error("malloc(%d) for %s: %s", (u_int
)buf
.st_size
+ 1,
498 fname
, pcap_strerror(errno
));
499 cc
= read(fd
, cp
, (u_int
)buf
.st_size
);
501 error("read %s: %s", fname
, pcap_strerror(errno
));
502 if (cc
!= buf
.st_size
)
503 error("short read %s (%d != %d)", fname
, cc
, (int)buf
.st_size
);
506 /* replace "# comment" with spaces */
507 for (i
= 0; i
< cc
; i
++) {
509 while (i
< cc
&& cp
[i
] != '\n')
517 safeputs(const char *s
, int maxlen
)
520 while (*s
&& idx
< maxlen
) {
532 ch
= (unsigned char)(c
& 0xff);
533 if (ch
< 0x80 && isprint(ch
))
536 printf("\\%03o", ch
);