]>
The Tcpdump Group git mirrors - tcpdump/blob - util.c
2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3 * The Regents of the University of California. All rights reserved.
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
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
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.
26 #include <tcpdump-stdinc.h>
40 #include "interface.h"
42 char * ts_format(register int, register int);
45 * Print out a null-terminated filename (or other ascii string).
46 * If ep is NULL, assume no truncation check is needed.
47 * Return true if truncated.
50 fn_print(register const u_char
*s
, register const u_char
*ep
)
55 ret
= 1; /* assume truncated */
56 while (ep
== NULL
|| s
< ep
) {
68 c
^= 0x40; /* DEL to ?, others to alpha */
77 * Print out a counted filename (or other ascii string).
78 * If ep is NULL, assume no truncation check is needed.
79 * Return true if truncated.
82 fn_printn(register const u_char
*s
, register u_int n
,
83 register const u_char
*ep
)
87 while (n
> 0 && (ep
== NULL
|| s
< ep
)) {
96 c
^= 0x40; /* DEL to ?, others to alpha */
101 return (n
== 0) ? 0 : 1;
105 * Print out a null-padded filename (or other ascii string).
106 * If ep is NULL, assume no truncation check is needed.
107 * Return true if truncated.
110 fn_printzp(register const u_char
*s
, register u_int n
,
111 register const u_char
*ep
)
116 ret
= 1; /* assume truncated */
117 while (n
> 0 && (ep
== NULL
|| s
< ep
)) {
130 c
^= 0x40; /* DEL to ?, others to alpha */
135 return (n
== 0) ? 0 : ret
;
139 * Format the timestamp
142 ts_format(register int sec
, register int usec
)
144 static char buf
[sizeof("00:00:00.000000")];
145 (void)snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d.%06u",
146 sec
/ 3600, (sec
% 3600) / 60, sec
% 60, usec
);
152 * Print the timestamp
155 ts_print(register const struct timeval
*tvp
)
160 static unsigned b_sec
;
161 static unsigned b_usec
;
167 case 0: /* Default */
168 s
= (tvp
->tv_sec
+ thiszone
) % 86400;
169 (void)printf("%s ", ts_format(s
, tvp
->tv_usec
));
172 case 1: /* No time stamp */
175 case 2: /* Unix timeval style */
176 (void)printf("%u.%06u ",
177 (unsigned)tvp
->tv_sec
,
178 (unsigned)tvp
->tv_usec
);
181 case 3: /* Microseconds since previous packet */
182 case 5: /* Microseconds since first packet */
184 /* init timestamp for first packet */
185 b_usec
= tvp
->tv_usec
;
189 d_usec
= tvp
->tv_usec
- b_usec
;
190 d_sec
= tvp
->tv_sec
- b_sec
;
197 (void)printf("%s ", ts_format(d_sec
, d_usec
));
199 if (tflag
== 3) { /* set timestamp for last packet */
201 b_usec
= tvp
->tv_usec
;
205 case 4: /* Default + Date*/
206 s
= (tvp
->tv_sec
+ thiszone
) % 86400;
207 Time
= (tvp
->tv_sec
+ thiszone
) - s
;
210 printf("Date fail ");
212 printf("%04d-%02d-%02d %s ",
213 tm
->tm_year
+1900, tm
->tm_mon
+1, tm
->tm_mday
,
214 ts_format(s
, tvp
->tv_usec
));
220 * Print a relative number of seconds (e.g. hold time, prune timer)
221 * in the form 5m1s. This does no truncation, so 32230861 seconds
222 * is represented as 1y1w1d1h1m1s.
225 relts_print(int secs
)
227 static const char *lengths
[] = {"y", "w", "d", "h", "m", "s"};
228 static const int seconds
[] = {31536000, 604800, 86400, 3600, 60, 1};
229 const char **l
= lengths
;
230 const int *s
= seconds
;
242 (void)printf("%d%s", secs
/ *s
, *l
);
243 secs
-= (secs
/ *s
) * *s
;
251 * this is a generic routine for printing unknown data;
252 * we pass on the linefeed plus indentation string to
253 * get a proper output - returns 0 on error
257 print_unknown_data(netdissect_options
*ndo
, const u_char
*cp
,const char *ident
,int len
)
260 ND_PRINT((ndo
,"%sDissector error: print_unknown_data called with negative length",
264 if (snapend
- cp
< len
)
267 ND_PRINT((ndo
,"%sDissector error: print_unknown_data called with pointer past end of packet",
271 hex_print(ndo
, ident
,cp
,len
);
272 return(1); /* everything is ok */
276 * Convert a token value to a string; use "fmt" if not found.
279 tok2strbuf(register const struct tok
*lp
, register const char *fmt
,
280 register int v
, char *buf
, size_t bufsize
)
283 while (lp
->s
!= NULL
) {
292 (void)snprintf(buf
, bufsize
, fmt
, v
);
293 return (const char *)buf
;
297 * Convert a token value to a string; use "fmt" if not found.
300 tok2str(register const struct tok
*lp
, register const char *fmt
,
303 static char buf
[4][128];
309 return tok2strbuf(lp
, fmt
, v
, ret
, sizeof(buf
[0]));
313 * Convert a bit token value to a string; use "fmt" if not found.
314 * this is useful for parsing bitfields, the output strings are seperated
315 * if the s field is positive.
318 bittok2str_internal(register const struct tok
*lp
, register const char *fmt
,
319 register int v
, register int sep
)
321 static char buf
[256]; /* our stringbuffer */
323 register int rotbit
; /* this is the bit we rotate through all bitpositions */
326 while (lp
!= NULL
&& lp
->s
!= NULL
) {
327 tokval
=lp
->v
; /* load our first value */
329 while (rotbit
!= 0) {
331 * lets AND the rotating bit with our token value
332 * and see if we have got a match
334 if (tokval
== (v
&rotbit
)) {
335 /* ok we have found something */
336 buflen
+=snprintf(buf
+buflen
, sizeof(buf
)-buflen
, "%s%s",
337 lp
->s
, sep
? ", " : "");
340 rotbit
=rotbit
<<1; /* no match - lets shift and try again */
345 /* user didn't want string seperation - no need to cut off trailing seperators */
350 if (buflen
!= 0) { /* did we find anything */
351 /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */
352 buf
[buflen
-2] = '\0';
356 /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
359 (void)snprintf(buf
, sizeof(buf
), fmt
, v
);
365 * Convert a bit token value to a string; use "fmt" if not found.
366 * this is useful for parsing bitfields, the output strings are not seperated.
369 bittok2str_nosep(register const struct tok
*lp
, register const char *fmt
,
372 return (bittok2str_internal(lp
, fmt
, v
, 0));
376 * Convert a bit token value to a string; use "fmt" if not found.
377 * this is useful for parsing bitfields, the output strings are comma seperated.
380 bittok2str(register const struct tok
*lp
, register const char *fmt
,
383 return (bittok2str_internal(lp
, fmt
, v
, 1));
387 * Convert a value to a string using an array; the macro
388 * tok2strary() in <interface.h> is the public interface to
389 * this function and ensures that the second argument is
390 * correct for bounds-checking.
393 tok2strary_internal(register const char **lp
, int n
, register const char *fmt
,
396 static char buf
[128];
398 if (v
>= 0 && v
< n
&& lp
[v
] != NULL
)
402 (void)snprintf(buf
, sizeof(buf
), fmt
, v
);
407 * Convert a 32-bit netmask to prefixlen if possible
408 * the function returns the prefix-len; if plen == -1
409 * then conversion was not possible;
413 mask2plen(u_int32_t mask
)
415 u_int32_t bitmasks
[33] = {
417 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
418 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
419 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
420 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
421 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
422 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
423 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
424 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
428 /* let's see if we can transform the mask into a prefixlen */
429 while (prefix_len
>= 0) {
430 if (bitmasks
[prefix_len
] == mask
)
439 mask62plen(const u_char
*mask
)
441 u_char bitmasks
[9] = {
443 0x80, 0xc0, 0xe0, 0xf0,
444 0xf8, 0xfc, 0xfe, 0xff
449 for (byte
= 0; byte
< 16; byte
++) {
452 for (bits
= 0; bits
< (sizeof (bitmasks
) / sizeof (bitmasks
[0])); bits
++) {
453 if (mask
[byte
] == bitmasks
[bits
]) {
459 if (mask
[byte
] != 0xff)
468 error(const char *fmt
, ...)
472 (void)fprintf(stderr
, "%s: ", program_name
);
474 (void)vfprintf(stderr
, fmt
, ap
);
479 (void)fputc('\n', stderr
);
487 warning(const char *fmt
, ...)
491 (void)fprintf(stderr
, "%s: WARNING: ", program_name
);
493 (void)vfprintf(stderr
, fmt
, ap
);
498 (void)fputc('\n', stderr
);
503 * Copy arg vector into a new buffer, concatenating arguments with spaces.
506 copy_argv(register char **argv
)
509 register u_int len
= 0;
518 len
+= strlen(*p
++) + 1;
520 buf
= (char *)malloc(len
);
522 error("copy_argv: malloc");
526 while ((src
= *p
++) != NULL
) {
527 while ((*dst
++ = *src
++) != '\0')
537 * On Windows, we need to open the file in binary mode, so that
538 * we get all the bytes specified by the size we get from "fstat()".
539 * On UNIX, that's not necessary. O_BINARY is defined on Windows;
540 * we define it as 0 if it's not defined, so it does nothing.
547 read_infile(char *fname
)
549 register int i
, fd
, cc
;
553 fd
= open(fname
, O_RDONLY
|O_BINARY
);
555 error("can't open %s: %s", fname
, pcap_strerror(errno
));
557 if (fstat(fd
, &buf
) < 0)
558 error("can't stat %s: %s", fname
, pcap_strerror(errno
));
560 cp
= malloc((u_int
)buf
.st_size
+ 1);
562 error("malloc(%d) for %s: %s", (u_int
)buf
.st_size
+ 1,
563 fname
, pcap_strerror(errno
));
564 cc
= read(fd
, cp
, (u_int
)buf
.st_size
);
566 error("read %s: %s", fname
, pcap_strerror(errno
));
567 if (cc
!= buf
.st_size
)
568 error("short read %s (%d != %d)", fname
, cc
, (int)buf
.st_size
);
571 /* replace "# comment" with spaces */
572 for (i
= 0; i
< cc
; i
++) {
574 while (i
< cc
&& cp
[i
] != '\n')
582 safeputs(const char *s
, int maxlen
)
586 while (*s
&& idx
< maxlen
) {
598 ch
= (unsigned char)(c
& 0xff);
599 if (ch
< 0x80 && isprint(ch
))
602 printf("\\0x%02x", ch
);