]> git.saurik.com Git - apple/network_cmds.git/blob - tcpdump.tproj/util.c
6df0352ee737f0a2f7f0d1d7fd2f2891962b8779
[apple/network_cmds.git] / tcpdump.tproj / util.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
26 * The Regents of the University of California. All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that: (1) source code distributions
30 * retain the above copyright notice and this paragraph in its entirety, (2)
31 * distributions including binary code include the above copyright notice and
32 * this paragraph in its entirety in the documentation or other materials
33 * provided with the distribution, and (3) all advertising materials mentioning
34 * features or use of this software display the following acknowledgement:
35 * ``This product includes software developed by the University of California,
36 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
37 * the University nor the names of its contributors may be used to endorse
38 * or promote products derived from this software without specific prior
39 * written permission.
40 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
41 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
43 */
44
45 #ifndef lint
46 static const char rcsid[] =
47 "@(#) $Header: /cvs/Darwin/Commands/NeXT/network_cmds/tcpdump.tproj/util.c,v 1.1.1.1 1999/05/02 03:58:34 wsanchez Exp $ (LBL)";
48 #endif
49
50 #include <sys/types.h>
51 #include <sys/time.h>
52 #include <sys/file.h>
53 #include <sys/stat.h>
54
55 #include <ctype.h>
56 #include <errno.h>
57 #ifdef HAVE_FCNTL_H
58 #include <fcntl.h>
59 #endif
60 #include <pcap.h>
61 #include <stdio.h>
62 #if __STDC__
63 #include <stdarg.h>
64 #else
65 #include <varargs.h>
66 #endif
67 #include <stdlib.h>
68 #include <string.h>
69 #ifdef TIME_WITH_SYS_TIME
70 #include <time.h>
71 #endif
72 #include <unistd.h>
73
74 #include "interface.h"
75
76 /*
77 * Print out a filename (or other ascii string).
78 * If ep is NULL, assume no truncation check is needed.
79 * Return true if truncated.
80 */
81 int
82 fn_print(register const u_char *s, register const u_char *ep)
83 {
84 register int ret;
85 register u_char c;
86
87 ret = 1; /* assume truncated */
88 while (ep == NULL || s < ep) {
89 c = *s++;
90 if (c == '\0') {
91 ret = 0;
92 break;
93 }
94 if (!isascii(c)) {
95 c = toascii(c);
96 putchar('M');
97 putchar('-');
98 }
99 if (!isprint(c)) {
100 c ^= 0x40; /* DEL to ?, others to alpha */
101 putchar('^');
102 }
103 putchar(c);
104 }
105 return(ret);
106 }
107
108 /*
109 * Print out a counted filename (or other ascii string).
110 * If ep is NULL, assume no truncation check is needed.
111 * Return true if truncated.
112 */
113 int
114 fn_printn(register const u_char *s, register u_int n,
115 register const u_char *ep)
116 {
117 register int ret;
118 register u_char c;
119
120 ret = 1; /* assume truncated */
121 while (ep == NULL || s < ep) {
122 if (n-- <= 0) {
123 ret = 0;
124 break;
125 }
126 c = *s++;
127 if (!isascii(c)) {
128 c = toascii(c);
129 putchar('M');
130 putchar('-');
131 }
132 if (!isprint(c)) {
133 c ^= 0x40; /* DEL to ?, others to alpha */
134 putchar('^');
135 }
136 putchar(c);
137 }
138 return(ret);
139 }
140
141 /*
142 * Print the timestamp
143 */
144 void
145 ts_print(register const struct timeval *tvp)
146 {
147 register int s;
148
149 if (tflag > 0) {
150 /* Default */
151 s = (tvp->tv_sec + thiszone) % 86400;
152 (void)printf("%02d:%02d:%02d.%06u ",
153 s / 3600, (s % 3600) / 60, s % 60, (u_int32_t)tvp->tv_usec);
154 } else if (tflag < 0) {
155 /* Unix timeval style */
156 (void)printf("%u.%06u ",
157 (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec);
158 }
159 }
160
161 /*
162 * Convert a token value to a string; use "fmt" if not found.
163 */
164 const char *
165 tok2str(register const struct tok *lp, register const char *fmt,
166 register int v)
167 {
168 static char buf[128];
169
170 while (lp->s != NULL) {
171 if (lp->v == v)
172 return (lp->s);
173 ++lp;
174 }
175 if (fmt == NULL)
176 fmt = "#%d";
177 (void)sprintf(buf, fmt, v);
178 return (buf);
179 }
180
181
182 /* VARARGS */
183 __dead void
184 #if __STDC__
185 error(const char *fmt, ...)
186 #else
187 error(fmt, va_alist)
188 const char *fmt;
189 va_dcl
190 #endif
191 {
192 va_list ap;
193
194 (void)fprintf(stderr, "%s: ", program_name);
195 #if __STDC__
196 va_start(ap, fmt);
197 #else
198 va_start(ap);
199 #endif
200 (void)vfprintf(stderr, fmt, ap);
201 va_end(ap);
202 if (*fmt) {
203 fmt += strlen(fmt);
204 if (fmt[-1] != '\n')
205 (void)fputc('\n', stderr);
206 }
207 exit(1);
208 /* NOTREACHED */
209 }
210
211 /* VARARGS */
212 void
213 #if __STDC__
214 warning(const char *fmt, ...)
215 #else
216 warning(fmt, va_alist)
217 const char *fmt;
218 va_dcl
219 #endif
220 {
221 va_list ap;
222
223 (void)fprintf(stderr, "%s: WARNING: ", program_name);
224 #if __STDC__
225 va_start(ap, fmt);
226 #else
227 va_start(ap);
228 #endif
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 }
237
238 /*
239 * Copy arg vector into a new buffer, concatenating arguments with spaces.
240 */
241 char *
242 copy_argv(register char **argv)
243 {
244 register char **p;
245 register u_int len = 0;
246 char *buf;
247 char *src, *dst;
248
249 p = argv;
250 if (*p == 0)
251 return 0;
252
253 while (*p)
254 len += strlen(*p++) + 1;
255
256 buf = (char *)malloc(len);
257 if (buf == NULL)
258 error("copy_argv: malloc");
259
260 p = argv;
261 dst = buf;
262 while ((src = *p++) != NULL) {
263 while ((*dst++ = *src++) != '\0')
264 ;
265 dst[-1] = ' ';
266 }
267 dst[-1] = '\0';
268
269 return buf;
270 }
271
272 /* A replacement for strdup() that cuts down on malloc() overhead */
273 char *
274 savestr(register const char *str)
275 {
276 register u_int size;
277 register char *p;
278 static char *strptr = NULL;
279 static u_int strsize = 0;
280
281 size = strlen(str) + 1;
282 if (size > strsize) {
283 strsize = 1024;
284 if (strsize < size)
285 strsize = size;
286 strptr = (char *)malloc(strsize);
287 if (strptr == NULL)
288 error("savestr: malloc");
289 }
290 (void)strcpy(strptr, str);
291 p = strptr;
292 strptr += size;
293 strsize -= size;
294 return (p);
295 }
296
297 char *
298 read_infile(char *fname)
299 {
300 register int fd, cc;
301 register char *cp;
302 struct stat buf;
303
304 fd = open(fname, O_RDONLY);
305 if (fd < 0)
306 error("can't open %s: %s", fname, pcap_strerror(errno));
307
308 if (fstat(fd, &buf) < 0)
309 error("can't stat %s: %s", fname, pcap_strerror(errno));
310
311 cp = malloc((u_int)buf.st_size + 1);
312 cc = read(fd, cp, (int)buf.st_size);
313 if (cc < 0)
314 error("read %s: %s", fname, pcap_strerror(errno));
315 if (cc != buf.st_size)
316 error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
317 cp[(int)buf.st_size] = '\0';
318
319 return (cp);
320 }
321
322 /*
323 * Returns the difference between gmt and local time in seconds.
324 * Use gmtime() and localtime() to keep things simple.
325 */
326 int32_t
327 gmt2local(void)
328 {
329 register int dt, dir;
330 register struct tm *gmt, *loc;
331 time_t t;
332 struct tm sgmt;
333
334 t = time(NULL);
335 gmt = &sgmt;
336 *gmt = *gmtime(&t);
337 loc = localtime(&t);
338 dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
339 (loc->tm_min - gmt->tm_min) * 60;
340
341 /*
342 * If the year or julian day is different, we span 00:00 GMT
343 * and must add or subtract a day. Check the year first to
344 * avoid problems when the julian day wraps.
345 */
346 dir = loc->tm_year - gmt->tm_year;
347 if (dir == 0)
348 dir = loc->tm_yday - gmt->tm_yday;
349 dt += dir * 24 * 60 * 60;
350
351 return (dt);
352 }