]>
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>
39 #include "interface.h"
41 char * ts_format(register int, register int);
44 * Print out a null-terminated filename (or other ascii string).
45 * If ep is NULL, assume no truncation check is needed.
46 * Return true if truncated.
49 fn_print(register const u_char
*s
, register const u_char
*ep
)
54 ret
= 1; /* assume truncated */
55 while (ep
== NULL
|| s
< ep
) {
67 c
^= 0x40; /* DEL to ?, others to alpha */
76 * Print out a counted filename (or other ascii string).
77 * If ep is NULL, assume no truncation check is needed.
78 * Return true if truncated.
81 fn_printn(register const u_char
*s
, register u_int n
,
82 register const u_char
*ep
)
86 while (n
> 0 && (ep
== NULL
|| s
< ep
)) {
95 c
^= 0x40; /* DEL to ?, others to alpha */
100 return (n
== 0) ? 0 : 1;
104 * Print out a null-padded filename (or other ascii string).
105 * If ep is NULL, assume no truncation check is needed.
106 * Return true if truncated.
109 fn_printzp(register const u_char
*s
, register u_int n
,
110 register const u_char
*ep
)
115 ret
= 1; /* assume truncated */
116 while (n
> 0 && (ep
== NULL
|| s
< ep
)) {
123 if (!ND_ISASCII(c
)) {
128 if (!ND_ISPRINT(c
)) {
129 c
^= 0x40; /* DEL to ?, others to alpha */
134 return (n
== 0) ? 0 : ret
;
138 * Format the timestamp
141 ts_format(register int sec
, register int usec
)
143 static char buf
[sizeof("00:00:00.000000")];
144 (void)snprintf(buf
, sizeof(buf
), "%02d:%02d:%02d.%06u",
145 sec
/ 3600, (sec
% 3600) / 60, sec
% 60, usec
);
151 * Print the timestamp
154 ts_print(register const struct timeval
*tvp
)
159 static unsigned b_sec
;
160 static unsigned b_usec
;
166 case 0: /* Default */
167 s
= (tvp
->tv_sec
+ thiszone
) % 86400;
168 (void)printf("%s ", ts_format(s
, tvp
->tv_usec
));
171 case 1: /* No time stamp */
174 case 2: /* Unix timeval style */
175 (void)printf("%u.%06u ",
176 (unsigned)tvp
->tv_sec
,
177 (unsigned)tvp
->tv_usec
);
180 case 3: /* Microseconds since previous packet */
181 case 5: /* Microseconds since first packet */
183 /* init timestamp for first packet */
184 b_usec
= tvp
->tv_usec
;
188 d_usec
= tvp
->tv_usec
- b_usec
;
189 d_sec
= tvp
->tv_sec
- b_sec
;
196 (void)printf("%s ", ts_format(d_sec
, d_usec
));
198 if (tflag
== 3) { /* set timestamp for last packet */
200 b_usec
= tvp
->tv_usec
;
204 case 4: /* Default + Date*/
205 s
= (tvp
->tv_sec
+ thiszone
) % 86400;
206 Time
= (tvp
->tv_sec
+ thiszone
) - s
;
209 printf("Date fail ");
211 printf("%04d-%02d-%02d %s ",
212 tm
->tm_year
+1900, tm
->tm_mon
+1, tm
->tm_mday
,
213 ts_format(s
, tvp
->tv_usec
));
219 * Print a relative number of seconds (e.g. hold time, prune timer)
220 * in the form 5m1s. This does no truncation, so 32230861 seconds
221 * is represented as 1y1w1d1h1m1s.
224 relts_print(int secs
)
226 static const char *lengths
[] = {"y", "w", "d", "h", "m", "s"};
227 static const int seconds
[] = {31536000, 604800, 86400, 3600, 60, 1};
228 const char **l
= lengths
;
229 const int *s
= seconds
;
241 (void)printf("%d%s", secs
/ *s
, *l
);
242 secs
-= (secs
/ *s
) * *s
;
250 * this is a generic routine for printing unknown data;
251 * we pass on the linefeed plus indentation string to
252 * get a proper output - returns 0 on error
256 print_unknown_data(netdissect_options
*ndo
, const u_char
*cp
,const char *ident
,int len
)
259 ND_PRINT((ndo
,"%sDissector error: print_unknown_data called with negative length",
263 if (snapend
- cp
< len
)
266 ND_PRINT((ndo
,"%sDissector error: print_unknown_data called with pointer past end of packet",
270 hex_print(ndo
, ident
,cp
,len
);
271 return(1); /* everything is ok */
275 * Convert a token value to a string; use "fmt" if not found.
278 tok2strbuf(register const struct tok
*lp
, register const char *fmt
,
279 register u_int v
, char *buf
, size_t bufsize
)
282 while (lp
->s
!= NULL
) {
291 (void)snprintf(buf
, bufsize
, fmt
, v
);
292 return (const char *)buf
;
296 * Convert a token value to a string; use "fmt" if not found.
299 tok2str(register const struct tok
*lp
, register const char *fmt
,
302 static char buf
[4][128];
308 return tok2strbuf(lp
, fmt
, v
, ret
, sizeof(buf
[0]));
312 * Convert a bit token value to a string; use "fmt" if not found.
313 * this is useful for parsing bitfields, the output strings are seperated
314 * if the s field is positive.
317 bittok2str_internal(register const struct tok
*lp
, register const char *fmt
,
318 register int v
, register int sep
)
320 static char buf
[256]; /* our stringbuffer */
322 register int rotbit
; /* this is the bit we rotate through all bitpositions */
325 while (lp
!= NULL
&& lp
->s
!= NULL
) {
326 tokval
=lp
->v
; /* load our first value */
328 while (rotbit
!= 0) {
330 * lets AND the rotating bit with our token value
331 * and see if we have got a match
333 if (tokval
== (v
&rotbit
)) {
334 /* ok we have found something */
335 buflen
+=snprintf(buf
+buflen
, sizeof(buf
)-buflen
, "%s%s",
336 lp
->s
, sep
? ", " : "");
339 rotbit
=rotbit
<<1; /* no match - lets shift and try again */
344 /* user didn't want string seperation - no need to cut off trailing seperators */
349 if (buflen
!= 0) { /* did we find anything */
350 /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */
351 buf
[buflen
-2] = '\0';
355 /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
358 (void)snprintf(buf
, sizeof(buf
), fmt
, v
);
364 * Convert a bit token value to a string; use "fmt" if not found.
365 * this is useful for parsing bitfields, the output strings are not seperated.
368 bittok2str_nosep(register const struct tok
*lp
, register const char *fmt
,
371 return (bittok2str_internal(lp
, fmt
, v
, 0));
375 * Convert a bit token value to a string; use "fmt" if not found.
376 * this is useful for parsing bitfields, the output strings are comma seperated.
379 bittok2str(register const struct tok
*lp
, register const char *fmt
,
382 return (bittok2str_internal(lp
, fmt
, v
, 1));
386 * Convert a value to a string using an array; the macro
387 * tok2strary() in <interface.h> is the public interface to
388 * this function and ensures that the second argument is
389 * correct for bounds-checking.
392 tok2strary_internal(register const char **lp
, int n
, register const char *fmt
,
395 static char buf
[128];
397 if (v
>= 0 && v
< n
&& lp
[v
] != NULL
)
401 (void)snprintf(buf
, sizeof(buf
), fmt
, v
);
406 * Convert a 32-bit netmask to prefixlen if possible
407 * the function returns the prefix-len; if plen == -1
408 * then conversion was not possible;
412 mask2plen(u_int32_t mask
)
414 u_int32_t bitmasks
[33] = {
416 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
417 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
418 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
419 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
420 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
421 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
422 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
423 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
427 /* let's see if we can transform the mask into a prefixlen */
428 while (prefix_len
>= 0) {
429 if (bitmasks
[prefix_len
] == mask
)
438 mask62plen(const u_char
*mask
)
440 u_char bitmasks
[9] = {
442 0x80, 0xc0, 0xe0, 0xf0,
443 0xf8, 0xfc, 0xfe, 0xff
448 for (byte
= 0; byte
< 16; byte
++) {
451 for (bits
= 0; bits
< (sizeof (bitmasks
) / sizeof (bitmasks
[0])); bits
++) {
452 if (mask
[byte
] == bitmasks
[bits
]) {
458 if (mask
[byte
] != 0xff)
467 error(const char *fmt
, ...)
471 (void)fprintf(stderr
, "%s: ", program_name
);
473 (void)vfprintf(stderr
, fmt
, ap
);
478 (void)fputc('\n', stderr
);
486 warning(const char *fmt
, ...)
490 (void)fprintf(stderr
, "%s: WARNING: ", program_name
);
492 (void)vfprintf(stderr
, fmt
, ap
);
497 (void)fputc('\n', stderr
);
502 * Copy arg vector into a new buffer, concatenating arguments with spaces.
505 copy_argv(register char **argv
)
508 register u_int len
= 0;
517 len
+= strlen(*p
++) + 1;
519 buf
= (char *)malloc(len
);
521 error("copy_argv: malloc");
525 while ((src
= *p
++) != NULL
) {
526 while ((*dst
++ = *src
++) != '\0')
536 * On Windows, we need to open the file in binary mode, so that
537 * we get all the bytes specified by the size we get from "fstat()".
538 * On UNIX, that's not necessary. O_BINARY is defined on Windows;
539 * we define it as 0 if it's not defined, so it does nothing.
546 read_infile(char *fname
)
548 register int i
, fd
, cc
;
552 fd
= open(fname
, O_RDONLY
|O_BINARY
);
554 error("can't open %s: %s", fname
, pcap_strerror(errno
));
556 if (fstat(fd
, &buf
) < 0)
557 error("can't stat %s: %s", fname
, pcap_strerror(errno
));
559 cp
= malloc((u_int
)buf
.st_size
+ 1);
561 error("malloc(%d) for %s: %s", (u_int
)buf
.st_size
+ 1,
562 fname
, pcap_strerror(errno
));
563 cc
= read(fd
, cp
, (u_int
)buf
.st_size
);
565 error("read %s: %s", fname
, pcap_strerror(errno
));
566 if (cc
!= buf
.st_size
)
567 error("short read %s (%d != %d)", fname
, cc
, (int)buf
.st_size
);
570 /* replace "# comment" with spaces */
571 for (i
= 0; i
< cc
; i
++) {
573 while (i
< cc
&& cp
[i
] != '\n')
581 safeputs(const char *s
, int maxlen
)
585 while (*s
&& idx
< maxlen
) {
597 ch
= (unsigned char)(c
& 0xff);
598 if (ch
< 0x80 && ND_ISPRINT(ch
))
601 printf("\\0x%02x", ch
);
606 * Some compilers try to optimize memcpy(), using the alignment constraint
607 * on the argument pointer type. by using this function, we try to avoid the
611 unaligned_memcpy(void *p
, const void *q
, size_t l
)
616 /* As with memcpy(), so with memcmp(). */
618 unaligned_memcmp(const void *p
, const void *q
, size_t l
)
620 return (memcmp(p
, q
, l
));