GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/util.c Lines: 0 130 0.0 %
Date: 2017-11-13 Branches: 0 114 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: util.c,v 1.27 2015/11/16 00:16:39 mmcc Exp $	*/
2
3
/*
4
 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
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
18
 * written permission.
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.
22
 */
23
24
#include <sys/types.h>
25
#include <sys/time.h>
26
#include <sys/file.h>
27
#include <sys/limits.h>
28
#include <sys/stat.h>
29
30
#include <ctype.h>
31
#include <err.h>
32
#include <errno.h>
33
#ifdef HAVE_FCNTL_H
34
#include <fcntl.h>
35
#endif
36
#include <pcap.h>
37
#include <stdio.h>
38
#include <stdarg.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#ifdef TIME_WITH_SYS_TIME
42
#include <time.h>
43
#endif
44
#include <unistd.h>
45
46
#include "interface.h"
47
#include "privsep.h"
48
/*
49
 * Print out a filename (or other ascii string).
50
 * If ep is NULL, assume no truncation check is needed.
51
 * Return true if truncated.
52
 */
53
int
54
fn_print(const u_char *s, const u_char *ep)
55
{
56
	int ret;
57
	u_char c;
58
59
	ret = 1;			/* assume truncated */
60
	while (ep == NULL || s < ep) {
61
		c = *s++;
62
		if (c == '\0') {
63
			ret = 0;
64
			break;
65
		}
66
		if (!isascii(c)) {
67
			c = toascii(c);
68
			putchar('M');
69
			putchar('-');
70
		}
71
		if (!isprint(c)) {
72
			c ^= 0x40;	/* DEL to ?, others to alpha */
73
			putchar('^');
74
		}
75
		putchar(c);
76
	}
77
	return(ret);
78
}
79
80
/*
81
 * Print out a counted filename (or other ascii string).
82
 * If ep is NULL, assume no truncation check is needed.
83
 * Return true if truncated.
84
 */
85
int
86
fn_printn(const u_char *s, u_int n, const u_char *ep)
87
{
88
	int ret;
89
	u_char c;
90
91
	ret = 1;			/* assume truncated */
92
	while (ep == NULL || s < ep) {
93
		if (n-- <= 0) {
94
			ret = 0;
95
			break;
96
		}
97
		c = *s++;
98
		if (!isascii(c)) {
99
			c = toascii(c);
100
			putchar('M');
101
			putchar('-');
102
		}
103
		if (!isprint(c)) {
104
			c ^= 0x40;	/* DEL to ?, others to alpha */
105
			putchar('^');
106
		}
107
		putchar(c);
108
	}
109
	return(ret);
110
}
111
112
/*
113
 * Print the timestamp
114
 */
115
void
116
ts_print(const struct bpf_timeval *tvp)
117
{
118
	int s;
119
#define TSBUFLEN 32
120
	static char buf[TSBUFLEN];
121
	static struct bpf_timeval last;
122
	struct timeval diff;
123
	time_t t;
124
125
	if (Iflag && device)
126
		(void)printf("%s ", device);
127
	switch(tflag){
128
	case 0:
129
		break;
130
	case -1:
131
		/* Unix timeval style */
132
		(void)printf("%u.%06u ",
133
		    (u_int32_t)tvp->tv_sec, (u_int32_t)tvp->tv_usec);
134
		break;
135
	case -2:
136
		t=tvp->tv_sec;
137
		strftime(buf, TSBUFLEN, "%b %d %T", priv_localtime(&t));
138
		printf("%s.%06u ", buf, (u_int32_t)tvp->tv_usec);
139
		break;
140
	case -3:
141
	case -4:
142
		/* time since first/last frame */
143
		timersub(tvp, &last, &diff);
144
		(void)printf("%u.%06u ",
145
		    (u_int32_t)diff.tv_sec, (u_int32_t)diff.tv_usec);
146
		if (tflag == -3 || (last.tv_sec == 0 && last.tv_usec == 0))
147
			last = *tvp;
148
		break;
149
	default:
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
		break;
155
	}
156
}
157
158
/*
159
 * Print a relative number of seconds (e.g. hold time, prune timer)
160
 * in the form 5m1s.  This does no truncation, so 32230861 seconds
161
 * is represented as 1y1w1d1h1m1s.
162
 */
163
void
164
relts_print(int secs)
165
{
166
	static char *lengths[] = {"y", "w", "d", "h", "m", "s"};
167
	static int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
168
	char **l = lengths;
169
	int *s = seconds;
170
171
	if (secs <= 0) {
172
		(void)printf("0s");
173
		return;
174
	}
175
	while (secs > 0) {
176
		if (secs >= *s) {
177
			(void)printf("%d%s", secs / *s, *l);
178
			secs -= (secs / *s) * *s;
179
		}
180
		s++;
181
		l++;
182
	}
183
}
184
185
/*
186
 * Convert a token value to a string; use "fmt" if not found.
187
 */
188
const char *
189
tok2str(const struct tok *lp, const char *fmt, int v)
190
{
191
	static char buf[128];
192
193
	while (lp->s != NULL) {
194
		if (lp->v == v)
195
			return (lp->s);
196
		++lp;
197
	}
198
	if (fmt == NULL)
199
		fmt = "#%d";
200
	(void)snprintf(buf, sizeof(buf), fmt, v);
201
	return (buf);
202
}
203
204
205
__dead void
206
error(const char *fmt, ...)
207
{
208
	va_list ap;
209
210
	(void)fprintf(stderr, "%s: ", program_name);
211
	va_start(ap, fmt);
212
	(void)vfprintf(stderr, fmt, ap);
213
	va_end(ap);
214
	(void)fputc('\n', stderr);
215
	exit(1);
216
	/* NOTREACHED */
217
}
218
219
void
220
warning(const char *fmt, ...)
221
{
222
	va_list ap;
223
224
	(void)fprintf(stderr, "%s: WARNING: ", program_name);
225
	va_start(ap, fmt);
226
	(void)vfprintf(stderr, fmt, ap);
227
	va_end(ap);
228
	(void)fputc('\n', stderr);
229
}
230
231
232
/*
233
 * Copy arg vector into a new buffer, concatenating arguments with spaces.
234
 */
235
char *
236
copy_argv(char * const *argv)
237
{
238
	size_t len = 0, n;
239
	char *buf;
240
241
	if (argv == NULL)
242
		return (NULL);
243
244
	for (n = 0; argv[n]; n++)
245
		len += strlen(argv[n])+1;
246
	if (len == 0)
247
		return (NULL);
248
249
	buf = malloc(len);
250
	if (buf == NULL)
251
		return (NULL);
252
253
	strlcpy(buf, argv[0], len);
254
	for (n = 1; argv[n]; n++) {
255
		strlcat(buf, " ", len);
256
		strlcat(buf, argv[n], len);
257
	}
258
	return (buf);
259
}
260
261
char *
262
read_infile(char *fname)
263
{
264
	struct stat	 buf;
265
	int		 fd;
266
	ssize_t		 cc;
267
	size_t		 bs;
268
	char		*cp;
269
270
	fd = open(fname, O_RDONLY);
271
	if (fd < 0)
272
		error("can't open %s: %s", fname, pcap_strerror(errno));
273
274
	if (fstat(fd, &buf) < 0)
275
		error("can't stat %s: %s", fname, pcap_strerror(errno));
276
277
	if (buf.st_size >= SSIZE_MAX)
278
		error("file too long");
279
280
	bs = buf.st_size;
281
	cp = malloc(bs + 1);
282
	if (cp == NULL)
283
		err(1, NULL);
284
	cc = read(fd, cp, bs);
285
	if (cc == -1)
286
		error("read %s: %s", fname, pcap_strerror(errno));
287
	if (cc != bs)
288
		error("short read %s (%ld != %lu)", fname, (long)cc,
289
		    (unsigned long)bs);
290
	cp[bs] = '\0';
291
	close(fd);
292
293
	return (cp);
294
}
295
296
void
297
safeputs(const char *s)
298
{
299
	while (*s) {
300
		safeputchar(*s);
301
		s++;
302
	}
303
}
304
305
void
306
safeputchar(int c)
307
{
308
	unsigned char ch;
309
310
	ch = (unsigned char)(c & 0xff);
311
	if (c < 0x80 && isprint(c))
312
		printf("%c", c & 0xff);
313
	else
314
		printf("\\%03o", c & 0xff);
315
}
316
317
/*
318
 * Print a value a la the %b format of the kernel's printf
319
 * (from sbin/ifconfig/ifconfig.c)
320
 */
321
void
322
printb(char *s, unsigned short v, char *bits)
323
{
324
	int i, any = 0;
325
	char c;
326
327
	if (bits && *bits == 8)
328
		printf("%s=%o", s, v);
329
	else
330
		printf("%s=%x", s, v);
331
332
	if (bits) {
333
		bits++;
334
		putchar('<');
335
		while ((i = *bits++)) {
336
			if (v & (1 << (i-1))) {
337
				if (any)
338
					putchar(',');
339
				any = 1;
340
				for (; (c = *bits) > 32; bits++)
341
					putchar(c);
342
			} else
343
				for (; *bits > 32; bits++)
344
					;
345
		}
346
		putchar('>');
347
	}
348
}