]> The Tcpdump Group git mirrors - libpcap/blob - testprogs/writecaptest.c
Fix typos in some comments
[libpcap] / testprogs / writecaptest.c
1 /*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
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 #include "varattrs.h"
23
24 #ifndef lint
25 static const char copyright[] _U_ =
26 "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
27 The Regents of the University of California. All rights reserved.\n";
28 #endif
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdarg.h>
34 #include <limits.h>
35 #ifdef _WIN32
36 #include "getopt.h"
37 #else
38 #include <unistd.h>
39 #endif
40 #include <errno.h>
41 #ifndef _WIN32
42 #include <signal.h>
43 #endif
44 #include <sys/types.h>
45
46 #include <pcap.h>
47
48 #include "pcap/funcattrs.h"
49
50 #ifdef _WIN32
51 #include "portability.h"
52 #endif
53
54 static char *program_name;
55
56 /* Forwards */
57 static void PCAP_NORETURN usage(void);
58 static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
59 static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
60 static char *copy_argv(char **);
61
62 static pcap_t *pd;
63
64 #ifdef _WIN32
65 static BOOL WINAPI
66 stop_capture(DWORD ctrltype _U_)
67 {
68 pcap_breakloop(pd);
69 return TRUE;
70 }
71 #else
72 static void
73 stop_capture(int signum _U_)
74 {
75 pcap_breakloop(pd);
76 }
77 #endif
78
79 #define COMMAND_OPTIONS "Li:w:y:"
80
81 int
82 main(int argc, char **argv)
83 {
84 register int op;
85 register char *cp, *cmdbuf, *device, *savefile = NULL;
86 pcap_if_t *devlist;
87 int show_dlt_types = 0;
88 int ndlts;
89 int *dlts;
90 bpf_u_int32 localnet, netmask;
91 struct bpf_program fcode;
92 char ebuf[PCAP_ERRBUF_SIZE];
93 #ifndef _WIN32
94 struct sigaction action;
95 #endif
96 int dlt;
97 const char *dlt_name = NULL;
98 int status;
99 pcap_dumper_t *pdd;
100
101 device = NULL;
102 if ((cp = strrchr(argv[0], '/')) != NULL)
103 program_name = cp + 1;
104 else
105 program_name = argv[0];
106
107 opterr = 0;
108 while ((op = getopt(argc, argv, COMMAND_OPTIONS)) != -1) {
109 switch (op) {
110
111 case 'L':
112 show_dlt_types = 1;
113 break;
114
115 case 'i':
116 device = optarg;
117 break;
118
119 case 'w':
120 savefile = optarg;
121 break;
122
123 case 'y':
124 dlt_name = optarg;
125 break;
126
127 default:
128 usage();
129 /* NOTREACHED */
130 }
131 }
132
133 if (device == NULL) {
134 if (pcap_findalldevs(&devlist, ebuf) == -1)
135 error("%s", ebuf);
136 if (devlist == NULL)
137 error("no interfaces available for capture");
138 device = strdup(devlist->name);
139 pcap_freealldevs(devlist);
140 }
141 if (show_dlt_types) {
142 pd = pcap_create(device, ebuf);
143 if (pd == NULL)
144 error("%s", ebuf);
145 status = pcap_activate(pd);
146 if (status < 0) {
147 /*
148 * pcap_activate() failed.
149 */
150 error("%s: %s\n(%s)", device,
151 pcap_statustostr(status), pcap_geterr(pd));
152 }
153 ndlts = pcap_list_datalinks(pd, &dlts);
154 if (ndlts < 0) {
155 /*
156 * pcap_list_datalinks() failed.
157 */
158 error("%s: %s\n(%s)", device,
159 pcap_statustostr(status), pcap_geterr(pd));
160 }
161 for (int i = 0; i < ndlts; i++) {
162 dlt_name = pcap_datalink_val_to_name(dlts[i]);
163 if (dlt_name == NULL)
164 printf("DLT %d", dlts[i]);
165 else
166 printf("%s", dlt_name);
167 printf("\n");
168 }
169 pcap_free_datalinks(dlts);
170 pcap_close(pd);
171 return 0;
172 }
173
174 if (savefile == NULL)
175 error("no savefile specified");
176
177 *ebuf = '\0';
178
179 pd = pcap_create(device, ebuf);
180 if (pd == NULL)
181 error("%s", ebuf);
182 status = pcap_set_snaplen(pd, 262144);
183 if (status != 0)
184 error("%s: pcap_set_snaplen failed: %s",
185 device, pcap_statustostr(status));
186 status = pcap_set_timeout(pd, 100);
187 if (status != 0)
188 error("%s: pcap_set_timeout failed: %s",
189 device, pcap_statustostr(status));
190 status = pcap_activate(pd);
191 if (status < 0) {
192 /*
193 * pcap_activate() failed.
194 */
195 error("%s: %s\n(%s)", device,
196 pcap_statustostr(status), pcap_geterr(pd));
197 } else if (status > 0) {
198 /*
199 * pcap_activate() succeeded, but it's warning us
200 * of a problem it had.
201 */
202 warning("%s: %s\n(%s)", device,
203 pcap_statustostr(status), pcap_geterr(pd));
204 }
205 if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
206 localnet = 0;
207 netmask = 0;
208 warning("%s", ebuf);
209 }
210
211 if (dlt_name != NULL) {
212 dlt = pcap_datalink_name_to_val(dlt_name);
213 if (dlt == PCAP_ERROR)
214 error("%s isn't a valid DLT name", dlt_name);
215 if (pcap_set_datalink(pd, dlt) == PCAP_ERROR)
216 error("%s: %s", device, pcap_geterr(pd));
217 }
218
219 cmdbuf = copy_argv(&argv[optind]);
220
221 if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
222 error("%s", pcap_geterr(pd));
223
224 if (pcap_setfilter(pd, &fcode) < 0)
225 error("%s", pcap_geterr(pd));
226
227 pdd = pcap_dump_open(pd, savefile);
228 if (pdd == NULL)
229 error("%s", pcap_geterr(pd));
230
231 #ifdef _WIN32
232 SetConsoleCtrlHandler(stop_capture, TRUE);
233 #else
234 action.sa_handler = stop_capture;
235 sigemptyset(&action.sa_mask);
236 action.sa_flags = 0;
237 if (sigaction(SIGINT, &action, NULL) == -1)
238 error("Can't catch SIGINT: %s\n", strerror(errno));
239 #endif
240
241 printf("Listening on %s, link-type ", device);
242 dlt = pcap_datalink(pd);
243 dlt_name = pcap_datalink_val_to_name(dlt);
244 if (dlt_name == NULL)
245 printf("DLT %d", dlt);
246 else
247 printf("%s", dlt_name);
248 printf("\n");
249 for (;;) {
250 status = pcap_dispatch(pd, -1, pcap_dump, (u_char *)pdd);
251 if (status < 0)
252 break;
253 if (status != 0) {
254 printf("%d packets seen\n", status);
255 struct pcap_stat ps;
256 pcap_stats(pd, &ps);
257 printf("%d ps_recv, %d ps_drop, %d ps_ifdrop\n",
258 ps.ps_recv, ps.ps_drop, ps.ps_ifdrop);
259 }
260 }
261 if (status == -2) {
262 /*
263 * We got interrupted, so perhaps we didn't
264 * manage to finish a line we were printing.
265 * Print an extra newline, just in case.
266 */
267 putchar('\n');
268 printf("Broken out of loop from SIGINT handler\n");
269 }
270 (void)fflush(stdout);
271 if (status == -1) {
272 /*
273 * Error. Report it.
274 */
275 (void)fprintf(stderr, "%s: pcap_dispatch: %s\n",
276 program_name, pcap_geterr(pd));
277 }
278 pcap_close(pd);
279 pcap_freecode(&fcode);
280 free(cmdbuf);
281 exit(status == -1 ? 1 : 0);
282 }
283
284 static void
285 usage(void)
286 {
287 (void)fprintf(stderr, "Usage: %s -L [ -i interface ] [ -w file ] [ -y dlt ] [expression]\n",
288 program_name);
289 exit(1);
290 }
291
292 /* VARARGS */
293 static void
294 error(const char *fmt, ...)
295 {
296 va_list ap;
297
298 (void)fprintf(stderr, "%s: ", program_name);
299 va_start(ap, fmt);
300 (void)vfprintf(stderr, fmt, ap);
301 va_end(ap);
302 if (*fmt) {
303 fmt += strlen(fmt);
304 if (fmt[-1] != '\n')
305 (void)fputc('\n', stderr);
306 }
307 exit(1);
308 /* NOTREACHED */
309 }
310
311 /* VARARGS */
312 static void
313 warning(const char *fmt, ...)
314 {
315 va_list ap;
316
317 (void)fprintf(stderr, "%s: WARNING: ", program_name);
318 va_start(ap, fmt);
319 (void)vfprintf(stderr, fmt, ap);
320 va_end(ap);
321 if (*fmt) {
322 fmt += strlen(fmt);
323 if (fmt[-1] != '\n')
324 (void)fputc('\n', stderr);
325 }
326 }
327
328 /*
329 * Copy arg vector into a new buffer, concatenating arguments with spaces.
330 */
331 static char *
332 copy_argv(register char **argv)
333 {
334 register char **p;
335 register size_t len = 0;
336 char *buf;
337 char *src, *dst;
338
339 p = argv;
340 if (*p == 0)
341 return 0;
342
343 while (*p)
344 len += strlen(*p++) + 1;
345
346 buf = (char *)malloc(len);
347 if (buf == NULL)
348 error("copy_argv: malloc");
349
350 p = argv;
351 dst = buf;
352 while ((src = *p++) != NULL) {
353 while ((*dst++ = *src++) != '\0')
354 ;
355 dst[-1] = ' ';
356 }
357 dst[-1] = '\0';
358
359 return buf;
360 }