]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/util.c
This commit was generated by cvs2svn to compensate for changes in r89354,
[FreeBSD/FreeBSD.git] / contrib / tcpdump / util.c
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
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
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
23 static const char rcsid[] =
24     "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.69 2000/07/11 00:49:03 assar Exp $ (LBL)";
25 #endif
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <sys/types.h>
32 #include <sys/time.h>
33 #include <sys/file.h>
34 #include <sys/stat.h>
35
36 #include <ctype.h>
37 #include <errno.h>
38 #ifdef HAVE_FCNTL_H
39 #include <fcntl.h>
40 #endif
41 #include <pcap.h>
42 #include <stdio.h>
43 #include <stdarg.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #ifdef TIME_WITH_SYS_TIME
47 #include <time.h>
48 #endif
49 #include <unistd.h>
50
51 #include "interface.h"
52
53 /*
54  * Print out a filename (or other ascii string).
55  * If ep is NULL, assume no truncation check is needed.
56  * Return true if truncated.
57  */
58 int
59 fn_print(register const u_char *s, register const u_char *ep)
60 {
61         register int ret;
62         register u_char c;
63
64         ret = 1;                        /* assume truncated */
65         while (ep == NULL || s < ep) {
66                 c = *s++;
67                 if (c == '\0') {
68                         ret = 0;
69                         break;
70                 }
71                 if (!isascii(c)) {
72                         c = toascii(c);
73                         putchar('M');
74                         putchar('-');
75                 }
76                 if (!isprint(c)) {
77                         c ^= 0x40;      /* DEL to ?, others to alpha */
78                         putchar('^');
79                 }
80                 putchar(c);
81         }
82         return(ret);
83 }
84
85 /*
86  * Print out a counted filename (or other ascii string).
87  * If ep is NULL, assume no truncation check is needed.
88  * Return true if truncated.
89  */
90 int
91 fn_printn(register const u_char *s, register u_int n,
92           register const u_char *ep)
93 {
94         register int ret;
95         register u_char c;
96
97         ret = 1;                        /* assume truncated */
98         while (ep == NULL || s < ep) {
99                 if (n-- <= 0) {
100                         ret = 0;
101                         break;
102                 }
103                 c = *s++;
104                 if (!isascii(c)) {
105                         c = toascii(c);
106                         putchar('M');
107                         putchar('-');
108                 }
109                 if (!isprint(c)) {
110                         c ^= 0x40;      /* DEL to ?, others to alpha */
111                         putchar('^');
112                 }
113                 putchar(c);
114         }
115         return(ret);
116 }
117
118 /*
119  * Print the timestamp
120  */
121 void
122 ts_print(register const struct timeval *tvp)
123 {
124         register int s;
125         struct tm *tm;
126         time_t Time;
127         static unsigned b_sec;
128         static unsigned b_usec;
129
130         switch(tflag) {
131         case 1: /* Default */
132                 s = (tvp->tv_sec + thiszone) % 86400;
133                 (void)printf("%02d:%02d:%02d.%06u ",
134                              s / 3600, (s % 3600) / 60, s % 60,
135                              (unsigned)tvp->tv_usec);
136                 break;
137         case -1: /* Unix timeval style */
138                 (void)printf("%u.%06u ",
139                              (unsigned)tvp->tv_sec,
140                              (unsigned)tvp->tv_usec);
141                 break;
142         case -2:
143                 if (b_sec == 0) {
144                         printf("000000 ");
145                 } else {
146                         int d_usec = tvp->tv_usec - b_usec;
147                         int d_sec = tvp->tv_sec - b_sec;
148                         
149                         while (d_usec < 0) {
150                                 d_usec += 1000000;
151                                 d_sec--;
152                         }
153                         if (d_sec)
154                                 printf("%d. ", d_sec);
155                         printf("%06d ", d_usec);
156                 }
157                 b_sec = tvp->tv_sec;
158                 b_usec = tvp->tv_usec;
159                 break;
160         case -3: /* Default + Date*/
161                 s = (tvp->tv_sec + thiszone) % 86400;
162                 Time = (tvp->tv_sec + thiszone) - s;
163                 tm  = gmtime (&Time);
164                 (void)printf("%02d/%02d/%04d %02d:%02d:%02d.%06u ",
165                              tm->tm_mon+1, tm->tm_mday,
166                              tm->tm_year+1900,
167                              s / 3600, (s % 3600) / 60,
168                              s % 60, (unsigned)tvp->tv_usec);
169                 break;
170         }
171 }
172
173 /*
174  * Print a relative number of seconds (e.g. hold time, prune timer)
175  * in the form 5m1s.  This does no truncation, so 32230861 seconds
176  * is represented as 1y1w1d1h1m1s.
177  */
178 void
179 relts_print(int secs)
180 {
181         static char *lengths[] = {"y", "w", "d", "h", "m", "s"};
182         static int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
183         char **l = lengths;
184         int *s = seconds;
185
186         if (secs <= 0) {
187                 (void)printf("0s");
188                 return;
189         }
190         while (secs > 0) {
191                 if (secs >= *s) {
192                         (void)printf("%d%s", secs / *s, *l);
193                         secs -= (secs / *s) * *s;
194                 }
195                 s++;
196                 l++;
197         }
198 }
199
200 /*
201  * Convert a token value to a string; use "fmt" if not found.
202  */
203 const char *
204 tok2str(register const struct tok *lp, register const char *fmt,
205         register int v)
206 {
207         static char buf[128];
208
209         while (lp->s != NULL) {
210                 if (lp->v == v)
211                         return (lp->s);
212                 ++lp;
213         }
214         if (fmt == NULL)
215                 fmt = "#%d";
216         (void)snprintf(buf, sizeof(buf), fmt, v);
217         return (buf);
218 }
219
220
221 /* VARARGS */
222 void
223 error(const char *fmt, ...)
224 {
225         va_list ap;
226
227         (void)fprintf(stderr, "%s: ", program_name);
228         va_start(ap, fmt);
229         (void)vfprintf(stderr, fmt, ap);
230         va_end(ap);
231         if (*fmt) {
232                 fmt += strlen(fmt);
233                 if (fmt[-1] != '\n')
234                         (void)fputc('\n', stderr);
235         }
236         exit(1);
237         /* NOTREACHED */
238 }
239
240 /* VARARGS */
241 void
242 warning(const char *fmt, ...)
243 {
244         va_list ap;
245
246         (void)fprintf(stderr, "%s: WARNING: ", program_name);
247         va_start(ap, fmt);
248         (void)vfprintf(stderr, fmt, ap);
249         va_end(ap);
250         if (*fmt) {
251                 fmt += strlen(fmt);
252                 if (fmt[-1] != '\n')
253                         (void)fputc('\n', stderr);
254         }
255 }
256
257 /*
258  * Copy arg vector into a new buffer, concatenating arguments with spaces.
259  */
260 char *
261 copy_argv(register char **argv)
262 {
263         register char **p;
264         register u_int len = 0;
265         char *buf;
266         char *src, *dst;
267
268         p = argv;
269         if (*p == 0)
270                 return 0;
271
272         while (*p)
273                 len += strlen(*p++) + 1;
274
275         buf = (char *)malloc(len);
276         if (buf == NULL)
277                 error("copy_argv: malloc");
278
279         p = argv;
280         dst = buf;
281         while ((src = *p++) != NULL) {
282                 while ((*dst++ = *src++) != '\0')
283                         ;
284                 dst[-1] = ' ';
285         }
286         dst[-1] = '\0';
287
288         return buf;
289 }
290
291 char *
292 read_infile(char *fname)
293 {
294         register int fd, cc;
295         register char *cp;
296         struct stat buf;
297
298         fd = open(fname, O_RDONLY);
299         if (fd < 0)
300                 error("can't open %s: %s", fname, pcap_strerror(errno));
301
302         if (fstat(fd, &buf) < 0)
303                 error("can't stat %s: %s", fname, pcap_strerror(errno));
304
305         cp = malloc((u_int)buf.st_size + 1);
306         cc = read(fd, cp, (int)buf.st_size);
307         if (cc < 0)
308                 error("read %s: %s", fname, pcap_strerror(errno));
309         if (cc != buf.st_size)
310                 error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
311         cp[(int)buf.st_size] = '\0';
312
313         return (cp);
314 }
315
316 void
317 safeputs(const char *s)
318 {
319         while (*s) {
320                 safeputchar(*s);
321                 s++;
322         }
323 }
324
325 void
326 safeputchar(int c)
327 {
328         unsigned char ch;
329
330         ch = (unsigned char)(c & 0xff);
331         if (c < 0x80 && isprint(c))
332                 printf("%c", c & 0xff);
333         else
334                 printf("\\%03o", c & 0xff);
335 }