1 | #include <machine/rtems-bsd-user-space.h> |
---|
2 | |
---|
3 | /* |
---|
4 | * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998 |
---|
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 the following conditions |
---|
9 | * are met: |
---|
10 | * 1. Redistributions of source code must retain the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer. |
---|
12 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer in the |
---|
14 | * documentation and/or other materials provided with the distribution. |
---|
15 | * 3. All advertising materials mentioning features or use of this software |
---|
16 | * must display the following acknowledgement: |
---|
17 | * This product includes software developed by the Computer Systems |
---|
18 | * Engineering Group at Lawrence Berkeley Laboratory. |
---|
19 | * 4. Neither the name of the University nor of the Laboratory may be used |
---|
20 | * to endorse or promote products derived from this software without |
---|
21 | * specific prior written permission. |
---|
22 | * |
---|
23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
33 | * SUCH DAMAGE. |
---|
34 | */ |
---|
35 | |
---|
36 | #if 0 |
---|
37 | #ifndef lint |
---|
38 | static const char rcsid[] _U_ = |
---|
39 | "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.128 2008-12-23 20:13:29 guy Exp $ (LBL)"; |
---|
40 | #endif |
---|
41 | #endif |
---|
42 | |
---|
43 | #ifdef HAVE_CONFIG_H |
---|
44 | #include "config.h" |
---|
45 | #endif |
---|
46 | |
---|
47 | #ifdef WIN32 |
---|
48 | #include <pcap-stdinc.h> |
---|
49 | #else /* WIN32 */ |
---|
50 | #if HAVE_INTTYPES_H |
---|
51 | #include <inttypes.h> |
---|
52 | #elif HAVE_STDINT_H |
---|
53 | #include <stdint.h> |
---|
54 | #endif |
---|
55 | #ifdef HAVE_SYS_BITYPES_H |
---|
56 | #include <sys/bitypes.h> |
---|
57 | #endif |
---|
58 | #include <sys/types.h> |
---|
59 | #include <sys/mman.h> |
---|
60 | #endif /* WIN32 */ |
---|
61 | |
---|
62 | #include <stdio.h> |
---|
63 | #include <stdlib.h> |
---|
64 | #include <string.h> |
---|
65 | #if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__) |
---|
66 | #include <unistd.h> |
---|
67 | #endif |
---|
68 | #include <fcntl.h> |
---|
69 | #include <errno.h> |
---|
70 | |
---|
71 | #ifdef HAVE_OS_PROTO_H |
---|
72 | #include "os-proto.h" |
---|
73 | #endif |
---|
74 | |
---|
75 | #ifdef MSDOS |
---|
76 | #include "pcap-dos.h" |
---|
77 | #endif |
---|
78 | |
---|
79 | #include "pcap-int.h" |
---|
80 | |
---|
81 | #ifdef HAVE_DAG_API |
---|
82 | #include "pcap-dag.h" |
---|
83 | #endif /* HAVE_DAG_API */ |
---|
84 | |
---|
85 | #ifdef HAVE_SEPTEL_API |
---|
86 | #include "pcap-septel.h" |
---|
87 | #endif /* HAVE_SEPTEL_API */ |
---|
88 | |
---|
89 | #ifdef HAVE_SNF_API |
---|
90 | #include "pcap-snf.h" |
---|
91 | #endif /* HAVE_SNF_API */ |
---|
92 | |
---|
93 | #ifdef PCAP_SUPPORT_USB |
---|
94 | #include "pcap-usb-linux.h" |
---|
95 | #endif |
---|
96 | |
---|
97 | #ifdef PCAP_SUPPORT_BT |
---|
98 | #include "pcap-bt-linux.h" |
---|
99 | #endif |
---|
100 | |
---|
101 | #ifdef PCAP_SUPPORT_CAN |
---|
102 | #include "pcap-can-linux.h" |
---|
103 | #endif |
---|
104 | |
---|
105 | #ifdef PCAP_SUPPORT_CANUSB |
---|
106 | #include "pcap-canusb-linux.h" |
---|
107 | #endif |
---|
108 | |
---|
109 | #ifdef PCAP_SUPPORT_NETFILTER |
---|
110 | #include "pcap-netfilter-linux.h" |
---|
111 | #endif |
---|
112 | |
---|
113 | int |
---|
114 | pcap_not_initialized(pcap_t *pcap) |
---|
115 | { |
---|
116 | /* this means 'not initialized' */ |
---|
117 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
118 | } |
---|
119 | |
---|
120 | /* |
---|
121 | * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't, |
---|
122 | * a PCAP_ERROR value on an error. |
---|
123 | */ |
---|
124 | int |
---|
125 | pcap_can_set_rfmon(pcap_t *p) |
---|
126 | { |
---|
127 | return (p->can_set_rfmon_op(p)); |
---|
128 | } |
---|
129 | |
---|
130 | /* |
---|
131 | * For systems where rfmon mode is never supported. |
---|
132 | */ |
---|
133 | static int |
---|
134 | pcap_cant_set_rfmon(pcap_t *p _U_) |
---|
135 | { |
---|
136 | return (0); |
---|
137 | } |
---|
138 | |
---|
139 | /* |
---|
140 | * Sets *tstamp_typesp to point to an array 1 or more supported time stamp |
---|
141 | * types; the return value is the number of supported time stamp types. |
---|
142 | * The list should be freed by a call to pcap_free_tstamp_types() when |
---|
143 | * you're done with it. |
---|
144 | * |
---|
145 | * A return value of 0 means "you don't get a choice of time stamp type", |
---|
146 | * in which case *tstamp_typesp is set to null. |
---|
147 | * |
---|
148 | * PCAP_ERROR is returned on error. |
---|
149 | */ |
---|
150 | int |
---|
151 | pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp) |
---|
152 | { |
---|
153 | if (p->tstamp_type_count == 0) { |
---|
154 | /* |
---|
155 | * We don't support multiple time stamp types. |
---|
156 | */ |
---|
157 | *tstamp_typesp = NULL; |
---|
158 | } else { |
---|
159 | *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp), |
---|
160 | p->tstamp_type_count); |
---|
161 | if (*tstamp_typesp == NULL) { |
---|
162 | (void)snprintf(p->errbuf, sizeof(p->errbuf), |
---|
163 | "malloc: %s", pcap_strerror(errno)); |
---|
164 | return (PCAP_ERROR); |
---|
165 | } |
---|
166 | (void)memcpy(*tstamp_typesp, p->tstamp_type_list, |
---|
167 | sizeof(**tstamp_typesp) * p->tstamp_type_count); |
---|
168 | } |
---|
169 | return (p->tstamp_type_count); |
---|
170 | } |
---|
171 | |
---|
172 | /* |
---|
173 | * In Windows, you might have a library built with one version of the |
---|
174 | * C runtime library and an application built with another version of |
---|
175 | * the C runtime library, which means that the library might use one |
---|
176 | * version of malloc() and free() and the application might use another |
---|
177 | * version of malloc() and free(). If so, that means something |
---|
178 | * allocated by the library cannot be freed by the application, so we |
---|
179 | * need to have a pcap_free_tstamp_types() routine to free up the list |
---|
180 | * allocated by pcap_list_tstamp_types(), even though it's just a wrapper |
---|
181 | * around free(). |
---|
182 | */ |
---|
183 | void |
---|
184 | pcap_free_tstamp_types(int *tstamp_type_list) |
---|
185 | { |
---|
186 | free(tstamp_type_list); |
---|
187 | } |
---|
188 | |
---|
189 | /* |
---|
190 | * Default one-shot callback; overridden for capture types where the |
---|
191 | * packet data cannot be guaranteed to be available after the callback |
---|
192 | * returns, so that a copy must be made. |
---|
193 | */ |
---|
194 | static void |
---|
195 | pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt) |
---|
196 | { |
---|
197 | struct oneshot_userdata *sp = (struct oneshot_userdata *)user; |
---|
198 | |
---|
199 | *sp->hdr = *h; |
---|
200 | *sp->pkt = pkt; |
---|
201 | } |
---|
202 | |
---|
203 | const u_char * |
---|
204 | pcap_next(pcap_t *p, struct pcap_pkthdr *h) |
---|
205 | { |
---|
206 | struct oneshot_userdata s; |
---|
207 | const u_char *pkt; |
---|
208 | |
---|
209 | s.hdr = h; |
---|
210 | s.pkt = &pkt; |
---|
211 | s.pd = p; |
---|
212 | if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0) |
---|
213 | return (0); |
---|
214 | return (pkt); |
---|
215 | } |
---|
216 | |
---|
217 | int |
---|
218 | pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, |
---|
219 | const u_char **pkt_data) |
---|
220 | { |
---|
221 | struct oneshot_userdata s; |
---|
222 | |
---|
223 | s.hdr = &p->pcap_header; |
---|
224 | s.pkt = pkt_data; |
---|
225 | s.pd = p; |
---|
226 | |
---|
227 | /* Saves a pointer to the packet headers */ |
---|
228 | *pkt_header= &p->pcap_header; |
---|
229 | |
---|
230 | if (p->sf.rfile != NULL) { |
---|
231 | int status; |
---|
232 | |
---|
233 | /* We are on an offline capture */ |
---|
234 | status = pcap_offline_read(p, 1, p->oneshot_callback, |
---|
235 | (u_char *)&s); |
---|
236 | |
---|
237 | /* |
---|
238 | * Return codes for pcap_offline_read() are: |
---|
239 | * - 0: EOF |
---|
240 | * - -1: error |
---|
241 | * - >1: OK |
---|
242 | * The first one ('0') conflicts with the return code of |
---|
243 | * 0 from pcap_read() meaning "no packets arrived before |
---|
244 | * the timeout expired", so we map it to -2 so you can |
---|
245 | * distinguish between an EOF from a savefile and a |
---|
246 | * "no packets arrived before the timeout expired, try |
---|
247 | * again" from a live capture. |
---|
248 | */ |
---|
249 | if (status == 0) |
---|
250 | return (-2); |
---|
251 | else |
---|
252 | return (status); |
---|
253 | } |
---|
254 | |
---|
255 | /* |
---|
256 | * Return codes for pcap_read() are: |
---|
257 | * - 0: timeout |
---|
258 | * - -1: error |
---|
259 | * - -2: loop was broken out of with pcap_breakloop() |
---|
260 | * - >1: OK |
---|
261 | * The first one ('0') conflicts with the return code of 0 from |
---|
262 | * pcap_offline_read() meaning "end of file". |
---|
263 | */ |
---|
264 | return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s)); |
---|
265 | } |
---|
266 | |
---|
267 | #if defined(DAG_ONLY) |
---|
268 | int |
---|
269 | pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) |
---|
270 | { |
---|
271 | return (dag_findalldevs(alldevsp, errbuf)); |
---|
272 | } |
---|
273 | |
---|
274 | pcap_t * |
---|
275 | pcap_create(const char *source, char *errbuf) |
---|
276 | { |
---|
277 | return (dag_create(source, errbuf)); |
---|
278 | } |
---|
279 | #elif defined(SEPTEL_ONLY) |
---|
280 | int |
---|
281 | pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) |
---|
282 | { |
---|
283 | return (septel_findalldevs(alldevsp, errbuf)); |
---|
284 | } |
---|
285 | |
---|
286 | pcap_t * |
---|
287 | pcap_create(const char *source, char *errbuf) |
---|
288 | { |
---|
289 | return (septel_create(source, errbuf)); |
---|
290 | } |
---|
291 | #elif defined(SNF_ONLY) |
---|
292 | int |
---|
293 | pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) |
---|
294 | { |
---|
295 | return (snf_findalldevs(alldevsp, errbuf)); |
---|
296 | } |
---|
297 | |
---|
298 | pcap_t * |
---|
299 | pcap_create(const char *source, char *errbuf) |
---|
300 | { |
---|
301 | return (snf_create(source, errbuf)); |
---|
302 | } |
---|
303 | #else /* regular pcap */ |
---|
304 | struct capture_source_type { |
---|
305 | int (*findalldevs_op)(pcap_if_t **, char *); |
---|
306 | pcap_t *(*create_op)(const char *, char *, int *); |
---|
307 | } capture_source_types[] = { |
---|
308 | #ifdef HAVE_DAG_API |
---|
309 | { dag_findalldevs, dag_create }, |
---|
310 | #endif |
---|
311 | #ifdef HAVE_SEPTEL_API |
---|
312 | { septel_findalldevs, septel_create }, |
---|
313 | #endif |
---|
314 | #ifdef HAVE_SNF_API |
---|
315 | { snf_findalldevs, snf_create }, |
---|
316 | #endif |
---|
317 | #ifdef PCAP_SUPPORT_BT |
---|
318 | { bt_findalldevs, bt_create }, |
---|
319 | #endif |
---|
320 | #if PCAP_SUPPORT_CANUSB |
---|
321 | { canusb_findalldevs, canusb_create }, |
---|
322 | #endif |
---|
323 | #ifdef PCAP_SUPPORT_CAN |
---|
324 | { can_findalldevs, can_create }, |
---|
325 | #endif |
---|
326 | #ifdef PCAP_SUPPORT_USB |
---|
327 | { usb_findalldevs, usb_create }, |
---|
328 | #endif |
---|
329 | #ifdef PCAP_SUPPORT_NETFILTER |
---|
330 | { netfilter_findalldevs, netfilter_create }, |
---|
331 | #endif |
---|
332 | { NULL, NULL } |
---|
333 | }; |
---|
334 | |
---|
335 | /* |
---|
336 | * Get a list of all capture sources that are up and that we can open. |
---|
337 | * Returns -1 on error, 0 otherwise. |
---|
338 | * The list, as returned through "alldevsp", may be null if no interfaces |
---|
339 | * were up and could be opened. |
---|
340 | */ |
---|
341 | int |
---|
342 | pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) |
---|
343 | { |
---|
344 | size_t i; |
---|
345 | |
---|
346 | /* |
---|
347 | * Get the list of regular interfaces first. |
---|
348 | */ |
---|
349 | if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1) |
---|
350 | return (-1); /* failure */ |
---|
351 | |
---|
352 | /* |
---|
353 | * Add any interfaces that need a platform-specific mechanism |
---|
354 | * to find. |
---|
355 | */ |
---|
356 | if (pcap_platform_finddevs(alldevsp, errbuf) == -1) { |
---|
357 | /* |
---|
358 | * We had an error; free the list we've been |
---|
359 | * constructing. |
---|
360 | */ |
---|
361 | if (*alldevsp != NULL) { |
---|
362 | pcap_freealldevs(*alldevsp); |
---|
363 | *alldevsp = NULL; |
---|
364 | } |
---|
365 | return (-1); |
---|
366 | } |
---|
367 | |
---|
368 | /* |
---|
369 | * Ask each of the non-local-network-interface capture |
---|
370 | * source types what interfaces they have. |
---|
371 | */ |
---|
372 | for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) { |
---|
373 | if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) { |
---|
374 | /* |
---|
375 | * We had an error; free the list we've been |
---|
376 | * constructing. |
---|
377 | */ |
---|
378 | if (*alldevsp != NULL) { |
---|
379 | pcap_freealldevs(*alldevsp); |
---|
380 | *alldevsp = NULL; |
---|
381 | } |
---|
382 | return (-1); |
---|
383 | } |
---|
384 | } |
---|
385 | return (0); |
---|
386 | } |
---|
387 | |
---|
388 | pcap_t * |
---|
389 | pcap_create(const char *source, char *errbuf) |
---|
390 | { |
---|
391 | size_t i; |
---|
392 | int is_theirs; |
---|
393 | pcap_t *p; |
---|
394 | |
---|
395 | /* |
---|
396 | * A null source name is equivalent to the "any" device - |
---|
397 | * which might not be supported on this platform, but |
---|
398 | * this means that you'll get a "not supported" error |
---|
399 | * rather than, say, a crash when we try to dereference |
---|
400 | * the null pointer. |
---|
401 | */ |
---|
402 | if (source == NULL) |
---|
403 | source = "any"; |
---|
404 | |
---|
405 | /* |
---|
406 | * Try each of the non-local-network-interface capture |
---|
407 | * source types until we find one that works for this |
---|
408 | * device or run out of types. |
---|
409 | */ |
---|
410 | for (i = 0; capture_source_types[i].create_op != NULL; i++) { |
---|
411 | is_theirs = 0; |
---|
412 | p = capture_source_types[i].create_op(source, errbuf, &is_theirs); |
---|
413 | if (is_theirs) { |
---|
414 | /* |
---|
415 | * The device name refers to a device of the |
---|
416 | * type in question; either it succeeded, |
---|
417 | * in which case p refers to a pcap_t to |
---|
418 | * later activate for the device, or it |
---|
419 | * failed, in which case p is null and we |
---|
420 | * should return that to report the failure |
---|
421 | * to create. |
---|
422 | */ |
---|
423 | return (p); |
---|
424 | } |
---|
425 | } |
---|
426 | |
---|
427 | /* |
---|
428 | * OK, try it as a regular network interface. |
---|
429 | */ |
---|
430 | return (pcap_create_interface(source, errbuf)); |
---|
431 | } |
---|
432 | #endif |
---|
433 | |
---|
434 | static void |
---|
435 | initialize_ops(pcap_t *p) |
---|
436 | { |
---|
437 | /* |
---|
438 | * Set operation pointers for operations that only work on |
---|
439 | * an activated pcap_t to point to a routine that returns |
---|
440 | * a "this isn't activated" error. |
---|
441 | */ |
---|
442 | p->read_op = (read_op_t)pcap_not_initialized; |
---|
443 | p->inject_op = (inject_op_t)pcap_not_initialized; |
---|
444 | p->setfilter_op = (setfilter_op_t)pcap_not_initialized; |
---|
445 | p->setdirection_op = (setdirection_op_t)pcap_not_initialized; |
---|
446 | p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized; |
---|
447 | p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized; |
---|
448 | p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized; |
---|
449 | p->stats_op = (stats_op_t)pcap_not_initialized; |
---|
450 | #ifdef WIN32 |
---|
451 | p->setbuff_op = (setbuff_op_t)pcap_not_initialized; |
---|
452 | p->setmode_op = (setmode_op_t)pcap_not_initialized; |
---|
453 | p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; |
---|
454 | #endif |
---|
455 | |
---|
456 | /* |
---|
457 | * Default cleanup operation - implementations can override |
---|
458 | * this, but should call pcap_cleanup_live_common() after |
---|
459 | * doing their own additional cleanup. |
---|
460 | */ |
---|
461 | p->cleanup_op = pcap_cleanup_live_common; |
---|
462 | |
---|
463 | /* |
---|
464 | * In most cases, the standard one-short callback can |
---|
465 | * be used for pcap_next()/pcap_next_ex(). |
---|
466 | */ |
---|
467 | p->oneshot_callback = pcap_oneshot; |
---|
468 | } |
---|
469 | |
---|
470 | pcap_t * |
---|
471 | pcap_create_common(const char *source, char *ebuf) |
---|
472 | { |
---|
473 | pcap_t *p; |
---|
474 | |
---|
475 | p = malloc(sizeof(*p)); |
---|
476 | if (p == NULL) { |
---|
477 | snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", |
---|
478 | pcap_strerror(errno)); |
---|
479 | return (NULL); |
---|
480 | } |
---|
481 | memset(p, 0, sizeof(*p)); |
---|
482 | #ifndef WIN32 |
---|
483 | p->fd = -1; /* not opened yet */ |
---|
484 | p->selectable_fd = -1; |
---|
485 | p->send_fd = -1; |
---|
486 | #endif |
---|
487 | |
---|
488 | p->opt.source = strdup(source); |
---|
489 | if (p->opt.source == NULL) { |
---|
490 | snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", |
---|
491 | pcap_strerror(errno)); |
---|
492 | free(p); |
---|
493 | return (NULL); |
---|
494 | } |
---|
495 | |
---|
496 | /* |
---|
497 | * Default to "can't set rfmon mode"; if it's supported by |
---|
498 | * a platform, the create routine that called us can set |
---|
499 | * the op to its routine to check whether a particular |
---|
500 | * device supports it. |
---|
501 | */ |
---|
502 | p->can_set_rfmon_op = pcap_cant_set_rfmon; |
---|
503 | |
---|
504 | initialize_ops(p); |
---|
505 | |
---|
506 | /* put in some defaults*/ |
---|
507 | pcap_set_timeout(p, 0); |
---|
508 | pcap_set_snaplen(p, 65535); /* max packet size */ |
---|
509 | p->opt.promisc = 0; |
---|
510 | p->opt.buffer_size = 0; |
---|
511 | p->opt.tstamp_type = -1; /* default to not setting time stamp type */ |
---|
512 | return (p); |
---|
513 | } |
---|
514 | |
---|
515 | int |
---|
516 | pcap_check_activated(pcap_t *p) |
---|
517 | { |
---|
518 | if (p->activated) { |
---|
519 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform " |
---|
520 | " operation on activated capture"); |
---|
521 | return (-1); |
---|
522 | } |
---|
523 | return (0); |
---|
524 | } |
---|
525 | |
---|
526 | int |
---|
527 | pcap_set_snaplen(pcap_t *p, int snaplen) |
---|
528 | { |
---|
529 | if (pcap_check_activated(p)) |
---|
530 | return (PCAP_ERROR_ACTIVATED); |
---|
531 | p->snapshot = snaplen; |
---|
532 | return (0); |
---|
533 | } |
---|
534 | |
---|
535 | int |
---|
536 | pcap_set_promisc(pcap_t *p, int promisc) |
---|
537 | { |
---|
538 | if (pcap_check_activated(p)) |
---|
539 | return (PCAP_ERROR_ACTIVATED); |
---|
540 | p->opt.promisc = promisc; |
---|
541 | return (0); |
---|
542 | } |
---|
543 | |
---|
544 | int |
---|
545 | pcap_set_rfmon(pcap_t *p, int rfmon) |
---|
546 | { |
---|
547 | if (pcap_check_activated(p)) |
---|
548 | return (PCAP_ERROR_ACTIVATED); |
---|
549 | p->opt.rfmon = rfmon; |
---|
550 | return (0); |
---|
551 | } |
---|
552 | |
---|
553 | int |
---|
554 | pcap_set_timeout(pcap_t *p, int timeout_ms) |
---|
555 | { |
---|
556 | if (pcap_check_activated(p)) |
---|
557 | return (PCAP_ERROR_ACTIVATED); |
---|
558 | p->md.timeout = timeout_ms; |
---|
559 | return (0); |
---|
560 | } |
---|
561 | |
---|
562 | int |
---|
563 | pcap_set_tstamp_type(pcap_t *p, int tstamp_type) |
---|
564 | { |
---|
565 | int i; |
---|
566 | |
---|
567 | if (pcap_check_activated(p)) |
---|
568 | return (PCAP_ERROR_ACTIVATED); |
---|
569 | |
---|
570 | /* |
---|
571 | * If p->tstamp_type_count is 0, we don't support setting |
---|
572 | * the time stamp type at all. |
---|
573 | */ |
---|
574 | if (p->tstamp_type_count == 0) |
---|
575 | return (PCAP_ERROR_CANTSET_TSTAMP_TYPE); |
---|
576 | |
---|
577 | /* |
---|
578 | * Check whether we claim to support this type of time stamp. |
---|
579 | */ |
---|
580 | for (i = 0; i < p->tstamp_type_count; i++) { |
---|
581 | if (p->tstamp_type_list[i] == tstamp_type) { |
---|
582 | /* |
---|
583 | * Yes. |
---|
584 | */ |
---|
585 | p->opt.tstamp_type = tstamp_type; |
---|
586 | return (0); |
---|
587 | } |
---|
588 | } |
---|
589 | |
---|
590 | /* |
---|
591 | * No. We support setting the time stamp type, but not to this |
---|
592 | * particular value. |
---|
593 | */ |
---|
594 | return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); |
---|
595 | } |
---|
596 | |
---|
597 | int |
---|
598 | pcap_set_buffer_size(pcap_t *p, int buffer_size) |
---|
599 | { |
---|
600 | if (pcap_check_activated(p)) |
---|
601 | return (PCAP_ERROR_ACTIVATED); |
---|
602 | p->opt.buffer_size = buffer_size; |
---|
603 | return (0); |
---|
604 | } |
---|
605 | |
---|
606 | int |
---|
607 | pcap_activate(pcap_t *p) |
---|
608 | { |
---|
609 | int status; |
---|
610 | |
---|
611 | /* |
---|
612 | * Catch attempts to re-activate an already-activated |
---|
613 | * pcap_t; this should, for example, catch code that |
---|
614 | * calls pcap_open_live() followed by pcap_activate(), |
---|
615 | * as some code that showed up in a Stack Exchange |
---|
616 | * question did. |
---|
617 | */ |
---|
618 | if (pcap_check_activated(p)) |
---|
619 | return (PCAP_ERROR_ACTIVATED); |
---|
620 | status = p->activate_op(p); |
---|
621 | if (status >= 0) |
---|
622 | p->activated = 1; |
---|
623 | else { |
---|
624 | if (p->errbuf[0] == '\0') { |
---|
625 | /* |
---|
626 | * No error message supplied by the activate routine; |
---|
627 | * for the benefit of programs that don't specially |
---|
628 | * handle errors other than PCAP_ERROR, return the |
---|
629 | * error message corresponding to the status. |
---|
630 | */ |
---|
631 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", |
---|
632 | pcap_statustostr(status)); |
---|
633 | } |
---|
634 | |
---|
635 | /* |
---|
636 | * Undo any operation pointer setting, etc. done by |
---|
637 | * the activate operation. |
---|
638 | */ |
---|
639 | initialize_ops(p); |
---|
640 | } |
---|
641 | return (status); |
---|
642 | } |
---|
643 | |
---|
644 | pcap_t * |
---|
645 | pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf) |
---|
646 | { |
---|
647 | pcap_t *p; |
---|
648 | int status; |
---|
649 | |
---|
650 | p = pcap_create(source, errbuf); |
---|
651 | if (p == NULL) |
---|
652 | return (NULL); |
---|
653 | status = pcap_set_snaplen(p, snaplen); |
---|
654 | if (status < 0) |
---|
655 | goto fail; |
---|
656 | status = pcap_set_promisc(p, promisc); |
---|
657 | if (status < 0) |
---|
658 | goto fail; |
---|
659 | status = pcap_set_timeout(p, to_ms); |
---|
660 | if (status < 0) |
---|
661 | goto fail; |
---|
662 | /* |
---|
663 | * Mark this as opened with pcap_open_live(), so that, for |
---|
664 | * example, we show the full list of DLT_ values, rather |
---|
665 | * than just the ones that are compatible with capturing |
---|
666 | * when not in monitor mode. That allows existing applications |
---|
667 | * to work the way they used to work, but allows new applications |
---|
668 | * that know about the new open API to, for example, find out the |
---|
669 | * DLT_ values that they can select without changing whether |
---|
670 | * the adapter is in monitor mode or not. |
---|
671 | */ |
---|
672 | p->oldstyle = 1; |
---|
673 | status = pcap_activate(p); |
---|
674 | if (status < 0) |
---|
675 | goto fail; |
---|
676 | return (p); |
---|
677 | fail: |
---|
678 | if (status == PCAP_ERROR) |
---|
679 | snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, |
---|
680 | p->errbuf); |
---|
681 | else if (status == PCAP_ERROR_NO_SUCH_DEVICE || |
---|
682 | status == PCAP_ERROR_PERM_DENIED || |
---|
683 | status == PCAP_ERROR_PROMISC_PERM_DENIED) |
---|
684 | snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source, |
---|
685 | pcap_statustostr(status), p->errbuf); |
---|
686 | else |
---|
687 | snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source, |
---|
688 | pcap_statustostr(status)); |
---|
689 | pcap_close(p); |
---|
690 | return (NULL); |
---|
691 | } |
---|
692 | |
---|
693 | int |
---|
694 | pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) |
---|
695 | { |
---|
696 | return (p->read_op(p, cnt, callback, user)); |
---|
697 | } |
---|
698 | |
---|
699 | /* |
---|
700 | * XXX - is this necessary? |
---|
701 | */ |
---|
702 | int |
---|
703 | pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) |
---|
704 | { |
---|
705 | |
---|
706 | return (p->read_op(p, cnt, callback, user)); |
---|
707 | } |
---|
708 | |
---|
709 | int |
---|
710 | pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) |
---|
711 | { |
---|
712 | register int n; |
---|
713 | |
---|
714 | for (;;) { |
---|
715 | if (p->sf.rfile != NULL) { |
---|
716 | /* |
---|
717 | * 0 means EOF, so don't loop if we get 0. |
---|
718 | */ |
---|
719 | n = pcap_offline_read(p, cnt, callback, user); |
---|
720 | } else { |
---|
721 | /* |
---|
722 | * XXX keep reading until we get something |
---|
723 | * (or an error occurs) |
---|
724 | */ |
---|
725 | do { |
---|
726 | n = p->read_op(p, cnt, callback, user); |
---|
727 | } while (n == 0); |
---|
728 | } |
---|
729 | if (n <= 0) |
---|
730 | return (n); |
---|
731 | if (cnt > 0) { |
---|
732 | cnt -= n; |
---|
733 | if (cnt <= 0) |
---|
734 | return (0); |
---|
735 | } |
---|
736 | } |
---|
737 | } |
---|
738 | |
---|
739 | /* |
---|
740 | * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. |
---|
741 | */ |
---|
742 | void |
---|
743 | pcap_breakloop(pcap_t *p) |
---|
744 | { |
---|
745 | p->break_loop = 1; |
---|
746 | } |
---|
747 | |
---|
748 | int |
---|
749 | pcap_datalink(pcap_t *p) |
---|
750 | { |
---|
751 | return (p->linktype); |
---|
752 | } |
---|
753 | |
---|
754 | int |
---|
755 | pcap_datalink_ext(pcap_t *p) |
---|
756 | { |
---|
757 | return (p->linktype_ext); |
---|
758 | } |
---|
759 | |
---|
760 | int |
---|
761 | pcap_list_datalinks(pcap_t *p, int **dlt_buffer) |
---|
762 | { |
---|
763 | if (p->dlt_count == 0) { |
---|
764 | /* |
---|
765 | * We couldn't fetch the list of DLTs, which means |
---|
766 | * this platform doesn't support changing the |
---|
767 | * DLT for an interface. Return a list of DLTs |
---|
768 | * containing only the DLT this device supports. |
---|
769 | */ |
---|
770 | *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); |
---|
771 | if (*dlt_buffer == NULL) { |
---|
772 | (void)snprintf(p->errbuf, sizeof(p->errbuf), |
---|
773 | "malloc: %s", pcap_strerror(errno)); |
---|
774 | return (-1); |
---|
775 | } |
---|
776 | **dlt_buffer = p->linktype; |
---|
777 | return (1); |
---|
778 | } else { |
---|
779 | *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count); |
---|
780 | if (*dlt_buffer == NULL) { |
---|
781 | (void)snprintf(p->errbuf, sizeof(p->errbuf), |
---|
782 | "malloc: %s", pcap_strerror(errno)); |
---|
783 | return (-1); |
---|
784 | } |
---|
785 | (void)memcpy(*dlt_buffer, p->dlt_list, |
---|
786 | sizeof(**dlt_buffer) * p->dlt_count); |
---|
787 | return (p->dlt_count); |
---|
788 | } |
---|
789 | } |
---|
790 | |
---|
791 | /* |
---|
792 | * In Windows, you might have a library built with one version of the |
---|
793 | * C runtime library and an application built with another version of |
---|
794 | * the C runtime library, which means that the library might use one |
---|
795 | * version of malloc() and free() and the application might use another |
---|
796 | * version of malloc() and free(). If so, that means something |
---|
797 | * allocated by the library cannot be freed by the application, so we |
---|
798 | * need to have a pcap_free_datalinks() routine to free up the list |
---|
799 | * allocated by pcap_list_datalinks(), even though it's just a wrapper |
---|
800 | * around free(). |
---|
801 | */ |
---|
802 | void |
---|
803 | pcap_free_datalinks(int *dlt_list) |
---|
804 | { |
---|
805 | free(dlt_list); |
---|
806 | } |
---|
807 | |
---|
808 | int |
---|
809 | pcap_set_datalink(pcap_t *p, int dlt) |
---|
810 | { |
---|
811 | int i; |
---|
812 | const char *dlt_name; |
---|
813 | |
---|
814 | if (p->dlt_count == 0 || p->set_datalink_op == NULL) { |
---|
815 | /* |
---|
816 | * We couldn't fetch the list of DLTs, or we don't |
---|
817 | * have a "set datalink" operation, which means |
---|
818 | * this platform doesn't support changing the |
---|
819 | * DLT for an interface. Check whether the new |
---|
820 | * DLT is the one this interface supports. |
---|
821 | */ |
---|
822 | if (p->linktype != dlt) |
---|
823 | goto unsupported; |
---|
824 | |
---|
825 | /* |
---|
826 | * It is, so there's nothing we need to do here. |
---|
827 | */ |
---|
828 | return (0); |
---|
829 | } |
---|
830 | for (i = 0; i < p->dlt_count; i++) |
---|
831 | if (p->dlt_list[i] == dlt) |
---|
832 | break; |
---|
833 | if (i >= p->dlt_count) |
---|
834 | goto unsupported; |
---|
835 | if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && |
---|
836 | dlt == DLT_DOCSIS) { |
---|
837 | /* |
---|
838 | * This is presumably an Ethernet device, as the first |
---|
839 | * link-layer type it offers is DLT_EN10MB, and the only |
---|
840 | * other type it offers is DLT_DOCSIS. That means that |
---|
841 | * we can't tell the driver to supply DOCSIS link-layer |
---|
842 | * headers - we're just pretending that's what we're |
---|
843 | * getting, as, presumably, we're capturing on a dedicated |
---|
844 | * link to a Cisco Cable Modem Termination System, and |
---|
845 | * it's putting raw DOCSIS frames on the wire inside low-level |
---|
846 | * Ethernet framing. |
---|
847 | */ |
---|
848 | p->linktype = dlt; |
---|
849 | return (0); |
---|
850 | } |
---|
851 | if (p->set_datalink_op(p, dlt) == -1) |
---|
852 | return (-1); |
---|
853 | p->linktype = dlt; |
---|
854 | return (0); |
---|
855 | |
---|
856 | unsupported: |
---|
857 | dlt_name = pcap_datalink_val_to_name(dlt); |
---|
858 | if (dlt_name != NULL) { |
---|
859 | (void) snprintf(p->errbuf, sizeof(p->errbuf), |
---|
860 | "%s is not one of the DLTs supported by this device", |
---|
861 | dlt_name); |
---|
862 | } else { |
---|
863 | (void) snprintf(p->errbuf, sizeof(p->errbuf), |
---|
864 | "DLT %d is not one of the DLTs supported by this device", |
---|
865 | dlt); |
---|
866 | } |
---|
867 | return (-1); |
---|
868 | } |
---|
869 | |
---|
870 | /* |
---|
871 | * This array is designed for mapping upper and lower case letter |
---|
872 | * together for a case independent comparison. The mappings are |
---|
873 | * based upon ascii character sequences. |
---|
874 | */ |
---|
875 | static const u_char charmap[] = { |
---|
876 | (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', |
---|
877 | (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', |
---|
878 | (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', |
---|
879 | (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', |
---|
880 | (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', |
---|
881 | (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', |
---|
882 | (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', |
---|
883 | (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', |
---|
884 | (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', |
---|
885 | (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', |
---|
886 | (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', |
---|
887 | (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', |
---|
888 | (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', |
---|
889 | (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', |
---|
890 | (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', |
---|
891 | (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', |
---|
892 | (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', |
---|
893 | (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', |
---|
894 | (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', |
---|
895 | (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', |
---|
896 | (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', |
---|
897 | (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', |
---|
898 | (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', |
---|
899 | (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', |
---|
900 | (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', |
---|
901 | (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', |
---|
902 | (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', |
---|
903 | (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', |
---|
904 | (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', |
---|
905 | (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', |
---|
906 | (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', |
---|
907 | (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', |
---|
908 | (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', |
---|
909 | (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', |
---|
910 | (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', |
---|
911 | (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', |
---|
912 | (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', |
---|
913 | (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', |
---|
914 | (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', |
---|
915 | (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', |
---|
916 | (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', |
---|
917 | (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', |
---|
918 | (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', |
---|
919 | (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', |
---|
920 | (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', |
---|
921 | (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', |
---|
922 | (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', |
---|
923 | (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', |
---|
924 | (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', |
---|
925 | (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', |
---|
926 | (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', |
---|
927 | (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', |
---|
928 | (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', |
---|
929 | (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', |
---|
930 | (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', |
---|
931 | (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', |
---|
932 | (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', |
---|
933 | (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', |
---|
934 | (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', |
---|
935 | (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', |
---|
936 | (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', |
---|
937 | (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', |
---|
938 | (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', |
---|
939 | (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', |
---|
940 | }; |
---|
941 | |
---|
942 | int |
---|
943 | pcap_strcasecmp(const char *s1, const char *s2) |
---|
944 | { |
---|
945 | register const u_char *cm = charmap, |
---|
946 | *us1 = (const u_char *)s1, |
---|
947 | *us2 = (const u_char *)s2; |
---|
948 | |
---|
949 | while (cm[*us1] == cm[*us2++]) |
---|
950 | if (*us1++ == '\0') |
---|
951 | return(0); |
---|
952 | return (cm[*us1] - cm[*--us2]); |
---|
953 | } |
---|
954 | |
---|
955 | struct dlt_choice { |
---|
956 | const char *name; |
---|
957 | const char *description; |
---|
958 | int dlt; |
---|
959 | }; |
---|
960 | |
---|
961 | #define DLT_CHOICE(code, description) { #code, description, code } |
---|
962 | #define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } |
---|
963 | |
---|
964 | static struct dlt_choice dlt_choices[] = { |
---|
965 | DLT_CHOICE(DLT_NULL, "BSD loopback"), |
---|
966 | DLT_CHOICE(DLT_EN10MB, "Ethernet"), |
---|
967 | DLT_CHOICE(DLT_IEEE802, "Token ring"), |
---|
968 | DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"), |
---|
969 | DLT_CHOICE(DLT_SLIP, "SLIP"), |
---|
970 | DLT_CHOICE(DLT_PPP, "PPP"), |
---|
971 | DLT_CHOICE(DLT_FDDI, "FDDI"), |
---|
972 | DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), |
---|
973 | DLT_CHOICE(DLT_RAW, "Raw IP"), |
---|
974 | DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"), |
---|
975 | DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"), |
---|
976 | DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"), |
---|
977 | DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"), |
---|
978 | DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"), |
---|
979 | DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"), |
---|
980 | DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"), |
---|
981 | DLT_CHOICE(DLT_IEEE802_11, "802.11"), |
---|
982 | DLT_CHOICE(DLT_FRELAY, "Frame Relay"), |
---|
983 | DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"), |
---|
984 | DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"), |
---|
985 | DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"), |
---|
986 | DLT_CHOICE(DLT_LTALK, "Localtalk"), |
---|
987 | DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"), |
---|
988 | DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"), |
---|
989 | DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"), |
---|
990 | DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), |
---|
991 | DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"), |
---|
992 | DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"), |
---|
993 | DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"), |
---|
994 | DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"), |
---|
995 | DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), |
---|
996 | DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"), |
---|
997 | DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"), |
---|
998 | DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), |
---|
999 | DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"), |
---|
1000 | DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"), |
---|
1001 | DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"), |
---|
1002 | DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), |
---|
1003 | DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), |
---|
1004 | DLT_CHOICE(DLT_MTP2, "SS7 MTP2"), |
---|
1005 | DLT_CHOICE(DLT_MTP3, "SS7 MTP3"), |
---|
1006 | DLT_CHOICE(DLT_SCCP, "SS7 SCCP"), |
---|
1007 | DLT_CHOICE(DLT_DOCSIS, "DOCSIS"), |
---|
1008 | DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"), |
---|
1009 | DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), |
---|
1010 | DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), |
---|
1011 | DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"), |
---|
1012 | DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"), |
---|
1013 | DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), |
---|
1014 | DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"), |
---|
1015 | DLT_CHOICE(DLT_GPF_T, "GPF-T"), |
---|
1016 | DLT_CHOICE(DLT_GPF_F, "GPF-F"), |
---|
1017 | DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"), |
---|
1018 | DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"), |
---|
1019 | DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"), |
---|
1020 | DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"), |
---|
1021 | DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"), |
---|
1022 | DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"), |
---|
1023 | DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"), |
---|
1024 | DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"), |
---|
1025 | DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"), |
---|
1026 | DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"), |
---|
1027 | DLT_CHOICE(DLT_A429, "Arinc 429"), |
---|
1028 | DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"), |
---|
1029 | DLT_CHOICE(DLT_USB, "USB"), |
---|
1030 | DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"), |
---|
1031 | DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"), |
---|
1032 | DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"), |
---|
1033 | DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"), |
---|
1034 | DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"), |
---|
1035 | DLT_CHOICE(DLT_PPI, "Per-Packet Information"), |
---|
1036 | DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"), |
---|
1037 | DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"), |
---|
1038 | DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"), |
---|
1039 | DLT_CHOICE(DLT_SITA, "SITA pseudo-header"), |
---|
1040 | DLT_CHOICE(DLT_ERF, "Endace ERF header"), |
---|
1041 | DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"), |
---|
1042 | DLT_CHOICE(DLT_IPMB, "IPMB"), |
---|
1043 | DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"), |
---|
1044 | DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), |
---|
1045 | DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"), |
---|
1046 | DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"), |
---|
1047 | DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"), |
---|
1048 | DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"), |
---|
1049 | DLT_CHOICE(DLT_DECT, "DECT"), |
---|
1050 | DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"), |
---|
1051 | DLT_CHOICE(DLT_WIHART, "Wireless HART"), |
---|
1052 | DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"), |
---|
1053 | DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"), |
---|
1054 | DLT_CHOICE(DLT_IPNET, "Solaris ipnet"), |
---|
1055 | DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"), |
---|
1056 | DLT_CHOICE(DLT_IPV4, "Raw IPv4"), |
---|
1057 | DLT_CHOICE(DLT_IPV6, "Raw IPv6"), |
---|
1058 | DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"), |
---|
1059 | DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"), |
---|
1060 | DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"), |
---|
1061 | DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"), |
---|
1062 | DLT_CHOICE(DLT_DVB_CI, "DVB-CI"), |
---|
1063 | DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"), |
---|
1064 | DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"), |
---|
1065 | DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"), |
---|
1066 | DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"), |
---|
1067 | DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"), |
---|
1068 | DLT_CHOICE_SENTINEL |
---|
1069 | }; |
---|
1070 | |
---|
1071 | int |
---|
1072 | pcap_datalink_name_to_val(const char *name) |
---|
1073 | { |
---|
1074 | int i; |
---|
1075 | |
---|
1076 | for (i = 0; dlt_choices[i].name != NULL; i++) { |
---|
1077 | if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1, |
---|
1078 | name) == 0) |
---|
1079 | return (dlt_choices[i].dlt); |
---|
1080 | } |
---|
1081 | return (-1); |
---|
1082 | } |
---|
1083 | |
---|
1084 | const char * |
---|
1085 | pcap_datalink_val_to_name(int dlt) |
---|
1086 | { |
---|
1087 | int i; |
---|
1088 | |
---|
1089 | for (i = 0; dlt_choices[i].name != NULL; i++) { |
---|
1090 | if (dlt_choices[i].dlt == dlt) |
---|
1091 | return (dlt_choices[i].name + sizeof("DLT_") - 1); |
---|
1092 | } |
---|
1093 | return (NULL); |
---|
1094 | } |
---|
1095 | |
---|
1096 | const char * |
---|
1097 | pcap_datalink_val_to_description(int dlt) |
---|
1098 | { |
---|
1099 | int i; |
---|
1100 | |
---|
1101 | for (i = 0; dlt_choices[i].name != NULL; i++) { |
---|
1102 | if (dlt_choices[i].dlt == dlt) |
---|
1103 | return (dlt_choices[i].description); |
---|
1104 | } |
---|
1105 | return (NULL); |
---|
1106 | } |
---|
1107 | |
---|
1108 | struct tstamp_type_choice { |
---|
1109 | const char *name; |
---|
1110 | const char *description; |
---|
1111 | int type; |
---|
1112 | }; |
---|
1113 | |
---|
1114 | static struct tstamp_type_choice tstamp_type_choices[] = { |
---|
1115 | { "host", "Host", PCAP_TSTAMP_HOST }, |
---|
1116 | { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC }, |
---|
1117 | { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC }, |
---|
1118 | { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER }, |
---|
1119 | { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED }, |
---|
1120 | { NULL, NULL, 0 } |
---|
1121 | }; |
---|
1122 | |
---|
1123 | int |
---|
1124 | pcap_tstamp_type_name_to_val(const char *name) |
---|
1125 | { |
---|
1126 | int i; |
---|
1127 | |
---|
1128 | for (i = 0; tstamp_type_choices[i].name != NULL; i++) { |
---|
1129 | if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0) |
---|
1130 | return (tstamp_type_choices[i].type); |
---|
1131 | } |
---|
1132 | return (PCAP_ERROR); |
---|
1133 | } |
---|
1134 | |
---|
1135 | const char * |
---|
1136 | pcap_tstamp_type_val_to_name(int tstamp_type) |
---|
1137 | { |
---|
1138 | int i; |
---|
1139 | |
---|
1140 | for (i = 0; tstamp_type_choices[i].name != NULL; i++) { |
---|
1141 | if (tstamp_type_choices[i].type == tstamp_type) |
---|
1142 | return (tstamp_type_choices[i].name); |
---|
1143 | } |
---|
1144 | return (NULL); |
---|
1145 | } |
---|
1146 | |
---|
1147 | const char * |
---|
1148 | pcap_tstamp_type_val_to_description(int tstamp_type) |
---|
1149 | { |
---|
1150 | int i; |
---|
1151 | |
---|
1152 | for (i = 0; tstamp_type_choices[i].name != NULL; i++) { |
---|
1153 | if (tstamp_type_choices[i].type == tstamp_type) |
---|
1154 | return (tstamp_type_choices[i].description); |
---|
1155 | } |
---|
1156 | return (NULL); |
---|
1157 | } |
---|
1158 | |
---|
1159 | int |
---|
1160 | pcap_snapshot(pcap_t *p) |
---|
1161 | { |
---|
1162 | return (p->snapshot); |
---|
1163 | } |
---|
1164 | |
---|
1165 | int |
---|
1166 | pcap_is_swapped(pcap_t *p) |
---|
1167 | { |
---|
1168 | return (p->sf.swapped); |
---|
1169 | } |
---|
1170 | |
---|
1171 | int |
---|
1172 | pcap_major_version(pcap_t *p) |
---|
1173 | { |
---|
1174 | return (p->sf.version_major); |
---|
1175 | } |
---|
1176 | |
---|
1177 | int |
---|
1178 | pcap_minor_version(pcap_t *p) |
---|
1179 | { |
---|
1180 | return (p->sf.version_minor); |
---|
1181 | } |
---|
1182 | |
---|
1183 | FILE * |
---|
1184 | pcap_file(pcap_t *p) |
---|
1185 | { |
---|
1186 | return (p->sf.rfile); |
---|
1187 | } |
---|
1188 | |
---|
1189 | int |
---|
1190 | pcap_fileno(pcap_t *p) |
---|
1191 | { |
---|
1192 | #ifndef WIN32 |
---|
1193 | return (p->fd); |
---|
1194 | #else |
---|
1195 | if (p->adapter != NULL) |
---|
1196 | return ((int)(DWORD)p->adapter->hFile); |
---|
1197 | else |
---|
1198 | return (-1); |
---|
1199 | #endif |
---|
1200 | } |
---|
1201 | |
---|
1202 | #if !defined(WIN32) && !defined(MSDOS) |
---|
1203 | int |
---|
1204 | pcap_get_selectable_fd(pcap_t *p) |
---|
1205 | { |
---|
1206 | return (p->selectable_fd); |
---|
1207 | } |
---|
1208 | #endif |
---|
1209 | |
---|
1210 | void |
---|
1211 | pcap_perror(pcap_t *p, char *prefix) |
---|
1212 | { |
---|
1213 | fprintf(stderr, "%s: %s\n", prefix, p->errbuf); |
---|
1214 | } |
---|
1215 | |
---|
1216 | char * |
---|
1217 | pcap_geterr(pcap_t *p) |
---|
1218 | { |
---|
1219 | return (p->errbuf); |
---|
1220 | } |
---|
1221 | |
---|
1222 | int |
---|
1223 | pcap_getnonblock(pcap_t *p, char *errbuf) |
---|
1224 | { |
---|
1225 | int ret; |
---|
1226 | |
---|
1227 | ret = p->getnonblock_op(p, errbuf); |
---|
1228 | if (ret == -1) { |
---|
1229 | /* |
---|
1230 | * In case somebody depended on the bug wherein |
---|
1231 | * the error message was put into p->errbuf |
---|
1232 | * by pcap_getnonblock_fd(). |
---|
1233 | */ |
---|
1234 | strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); |
---|
1235 | } |
---|
1236 | return (ret); |
---|
1237 | } |
---|
1238 | |
---|
1239 | /* |
---|
1240 | * Get the current non-blocking mode setting, under the assumption that |
---|
1241 | * it's just the standard POSIX non-blocking flag. |
---|
1242 | * |
---|
1243 | * We don't look at "p->nonblock", in case somebody tweaked the FD |
---|
1244 | * directly. |
---|
1245 | */ |
---|
1246 | #if !defined(WIN32) && !defined(MSDOS) |
---|
1247 | int |
---|
1248 | pcap_getnonblock_fd(pcap_t *p, char *errbuf) |
---|
1249 | { |
---|
1250 | int fdflags; |
---|
1251 | |
---|
1252 | fdflags = fcntl(p->fd, F_GETFL, 0); |
---|
1253 | if (fdflags == -1) { |
---|
1254 | snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", |
---|
1255 | pcap_strerror(errno)); |
---|
1256 | return (-1); |
---|
1257 | } |
---|
1258 | if (fdflags & O_NONBLOCK) |
---|
1259 | return (1); |
---|
1260 | else |
---|
1261 | return (0); |
---|
1262 | } |
---|
1263 | #endif |
---|
1264 | |
---|
1265 | int |
---|
1266 | pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) |
---|
1267 | { |
---|
1268 | int ret; |
---|
1269 | |
---|
1270 | ret = p->setnonblock_op(p, nonblock, errbuf); |
---|
1271 | if (ret == -1) { |
---|
1272 | /* |
---|
1273 | * In case somebody depended on the bug wherein |
---|
1274 | * the error message was put into p->errbuf |
---|
1275 | * by pcap_setnonblock_fd(). |
---|
1276 | */ |
---|
1277 | strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); |
---|
1278 | } |
---|
1279 | return (ret); |
---|
1280 | } |
---|
1281 | |
---|
1282 | #if !defined(WIN32) && !defined(MSDOS) |
---|
1283 | /* |
---|
1284 | * Set non-blocking mode, under the assumption that it's just the |
---|
1285 | * standard POSIX non-blocking flag. (This can be called by the |
---|
1286 | * per-platform non-blocking-mode routine if that routine also |
---|
1287 | * needs to do some additional work.) |
---|
1288 | */ |
---|
1289 | int |
---|
1290 | pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) |
---|
1291 | { |
---|
1292 | int fdflags; |
---|
1293 | |
---|
1294 | fdflags = fcntl(p->fd, F_GETFL, 0); |
---|
1295 | if (fdflags == -1) { |
---|
1296 | snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", |
---|
1297 | pcap_strerror(errno)); |
---|
1298 | return (-1); |
---|
1299 | } |
---|
1300 | if (nonblock) |
---|
1301 | fdflags |= O_NONBLOCK; |
---|
1302 | else |
---|
1303 | fdflags &= ~O_NONBLOCK; |
---|
1304 | if (fcntl(p->fd, F_SETFL, fdflags) == -1) { |
---|
1305 | snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", |
---|
1306 | pcap_strerror(errno)); |
---|
1307 | return (-1); |
---|
1308 | } |
---|
1309 | return (0); |
---|
1310 | } |
---|
1311 | #endif |
---|
1312 | |
---|
1313 | #ifdef WIN32 |
---|
1314 | /* |
---|
1315 | * Generate a string for the last Win32-specific error (i.e. an error generated when |
---|
1316 | * calling a Win32 API). |
---|
1317 | * For errors occurred during standard C calls, we still use pcap_strerror() |
---|
1318 | */ |
---|
1319 | char * |
---|
1320 | pcap_win32strerror(void) |
---|
1321 | { |
---|
1322 | DWORD error; |
---|
1323 | static char errbuf[PCAP_ERRBUF_SIZE+1]; |
---|
1324 | int errlen; |
---|
1325 | char *p; |
---|
1326 | |
---|
1327 | error = GetLastError(); |
---|
1328 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, |
---|
1329 | PCAP_ERRBUF_SIZE, NULL); |
---|
1330 | |
---|
1331 | /* |
---|
1332 | * "FormatMessage()" "helpfully" sticks CR/LF at the end of the |
---|
1333 | * message. Get rid of it. |
---|
1334 | */ |
---|
1335 | errlen = strlen(errbuf); |
---|
1336 | if (errlen >= 2) { |
---|
1337 | errbuf[errlen - 1] = '\0'; |
---|
1338 | errbuf[errlen - 2] = '\0'; |
---|
1339 | } |
---|
1340 | p = strchr(errbuf, '\0'); |
---|
1341 | snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error); |
---|
1342 | return (errbuf); |
---|
1343 | } |
---|
1344 | #endif |
---|
1345 | |
---|
1346 | /* |
---|
1347 | * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. |
---|
1348 | */ |
---|
1349 | const char * |
---|
1350 | pcap_statustostr(int errnum) |
---|
1351 | { |
---|
1352 | static char ebuf[15+10+1]; |
---|
1353 | |
---|
1354 | switch (errnum) { |
---|
1355 | |
---|
1356 | case PCAP_WARNING: |
---|
1357 | return("Generic warning"); |
---|
1358 | |
---|
1359 | case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: |
---|
1360 | return ("That type of time stamp is not supported by that device"); |
---|
1361 | |
---|
1362 | case PCAP_WARNING_PROMISC_NOTSUP: |
---|
1363 | return ("That device doesn't support promiscuous mode"); |
---|
1364 | |
---|
1365 | case PCAP_ERROR: |
---|
1366 | return("Generic error"); |
---|
1367 | |
---|
1368 | case PCAP_ERROR_BREAK: |
---|
1369 | return("Loop terminated by pcap_breakloop"); |
---|
1370 | |
---|
1371 | case PCAP_ERROR_NOT_ACTIVATED: |
---|
1372 | return("The pcap_t has not been activated"); |
---|
1373 | |
---|
1374 | case PCAP_ERROR_ACTIVATED: |
---|
1375 | return ("The setting can't be changed after the pcap_t is activated"); |
---|
1376 | |
---|
1377 | case PCAP_ERROR_NO_SUCH_DEVICE: |
---|
1378 | return ("No such device exists"); |
---|
1379 | |
---|
1380 | case PCAP_ERROR_RFMON_NOTSUP: |
---|
1381 | return ("That device doesn't support monitor mode"); |
---|
1382 | |
---|
1383 | case PCAP_ERROR_NOT_RFMON: |
---|
1384 | return ("That operation is supported only in monitor mode"); |
---|
1385 | |
---|
1386 | case PCAP_ERROR_PERM_DENIED: |
---|
1387 | return ("You don't have permission to capture on that device"); |
---|
1388 | |
---|
1389 | case PCAP_ERROR_IFACE_NOT_UP: |
---|
1390 | return ("That device is not up"); |
---|
1391 | |
---|
1392 | case PCAP_ERROR_CANTSET_TSTAMP_TYPE: |
---|
1393 | return ("That device doesn't support setting the time stamp type"); |
---|
1394 | |
---|
1395 | case PCAP_ERROR_PROMISC_PERM_DENIED: |
---|
1396 | return ("You don't have permission to capture in promiscuous mode on that device"); |
---|
1397 | } |
---|
1398 | (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); |
---|
1399 | return(ebuf); |
---|
1400 | } |
---|
1401 | |
---|
1402 | /* |
---|
1403 | * Not all systems have strerror(). |
---|
1404 | */ |
---|
1405 | const char * |
---|
1406 | pcap_strerror(int errnum) |
---|
1407 | { |
---|
1408 | #ifdef HAVE_STRERROR |
---|
1409 | return (strerror(errnum)); |
---|
1410 | #else |
---|
1411 | extern int sys_nerr; |
---|
1412 | extern const char *const sys_errlist[]; |
---|
1413 | static char ebuf[15+10+1]; |
---|
1414 | |
---|
1415 | if ((unsigned int)errnum < sys_nerr) |
---|
1416 | return ((char *)sys_errlist[errnum]); |
---|
1417 | (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); |
---|
1418 | return(ebuf); |
---|
1419 | #endif |
---|
1420 | } |
---|
1421 | |
---|
1422 | int |
---|
1423 | pcap_setfilter(pcap_t *p, struct bpf_program *fp) |
---|
1424 | { |
---|
1425 | return (p->setfilter_op(p, fp)); |
---|
1426 | } |
---|
1427 | |
---|
1428 | /* |
---|
1429 | * Set direction flag, which controls whether we accept only incoming |
---|
1430 | * packets, only outgoing packets, or both. |
---|
1431 | * Note that, depending on the platform, some or all direction arguments |
---|
1432 | * might not be supported. |
---|
1433 | */ |
---|
1434 | int |
---|
1435 | pcap_setdirection(pcap_t *p, pcap_direction_t d) |
---|
1436 | { |
---|
1437 | if (p->setdirection_op == NULL) { |
---|
1438 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1439 | "Setting direction is not implemented on this platform"); |
---|
1440 | return (-1); |
---|
1441 | } else |
---|
1442 | return (p->setdirection_op(p, d)); |
---|
1443 | } |
---|
1444 | |
---|
1445 | int |
---|
1446 | pcap_stats(pcap_t *p, struct pcap_stat *ps) |
---|
1447 | { |
---|
1448 | return (p->stats_op(p, ps)); |
---|
1449 | } |
---|
1450 | |
---|
1451 | static int |
---|
1452 | pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) |
---|
1453 | { |
---|
1454 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1455 | "Statistics aren't available from a pcap_open_dead pcap_t"); |
---|
1456 | return (-1); |
---|
1457 | } |
---|
1458 | |
---|
1459 | #ifdef WIN32 |
---|
1460 | int |
---|
1461 | pcap_setbuff(pcap_t *p, int dim) |
---|
1462 | { |
---|
1463 | return (p->setbuff_op(p, dim)); |
---|
1464 | } |
---|
1465 | |
---|
1466 | static int |
---|
1467 | pcap_setbuff_dead(pcap_t *p, int dim) |
---|
1468 | { |
---|
1469 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1470 | "The kernel buffer size cannot be set on a pcap_open_dead pcap_t"); |
---|
1471 | return (-1); |
---|
1472 | } |
---|
1473 | |
---|
1474 | int |
---|
1475 | pcap_setmode(pcap_t *p, int mode) |
---|
1476 | { |
---|
1477 | return (p->setmode_op(p, mode)); |
---|
1478 | } |
---|
1479 | |
---|
1480 | static int |
---|
1481 | pcap_setmode_dead(pcap_t *p, int mode) |
---|
1482 | { |
---|
1483 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1484 | "impossible to set mode on a pcap_open_dead pcap_t"); |
---|
1485 | return (-1); |
---|
1486 | } |
---|
1487 | |
---|
1488 | int |
---|
1489 | pcap_setmintocopy(pcap_t *p, int size) |
---|
1490 | { |
---|
1491 | return (p->setmintocopy_op(p, size)); |
---|
1492 | } |
---|
1493 | |
---|
1494 | static int |
---|
1495 | pcap_setmintocopy_dead(pcap_t *p, int size) |
---|
1496 | { |
---|
1497 | snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1498 | "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t"); |
---|
1499 | return (-1); |
---|
1500 | } |
---|
1501 | #endif |
---|
1502 | |
---|
1503 | /* |
---|
1504 | * On some platforms, we need to clean up promiscuous or monitor mode |
---|
1505 | * when we close a device - and we want that to happen even if the |
---|
1506 | * application just exits without explicitl closing devices. |
---|
1507 | * On those platforms, we need to register a "close all the pcaps" |
---|
1508 | * routine to be called when we exit, and need to maintain a list of |
---|
1509 | * pcaps that need to be closed to clean up modes. |
---|
1510 | * |
---|
1511 | * XXX - not thread-safe. |
---|
1512 | */ |
---|
1513 | |
---|
1514 | /* |
---|
1515 | * List of pcaps on which we've done something that needs to be |
---|
1516 | * cleaned up. |
---|
1517 | * If there are any such pcaps, we arrange to call "pcap_close_all()" |
---|
1518 | * when we exit, and have it close all of them. |
---|
1519 | */ |
---|
1520 | static struct pcap *pcaps_to_close; |
---|
1521 | |
---|
1522 | /* |
---|
1523 | * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to |
---|
1524 | * be called on exit. |
---|
1525 | */ |
---|
1526 | static int did_atexit; |
---|
1527 | |
---|
1528 | static void |
---|
1529 | pcap_close_all(void) |
---|
1530 | { |
---|
1531 | struct pcap *handle; |
---|
1532 | |
---|
1533 | while ((handle = pcaps_to_close) != NULL) |
---|
1534 | pcap_close(handle); |
---|
1535 | } |
---|
1536 | |
---|
1537 | int |
---|
1538 | pcap_do_addexit(pcap_t *p) |
---|
1539 | { |
---|
1540 | /* |
---|
1541 | * If we haven't already done so, arrange to have |
---|
1542 | * "pcap_close_all()" called when we exit. |
---|
1543 | */ |
---|
1544 | if (!did_atexit) { |
---|
1545 | if (atexit(pcap_close_all) == -1) { |
---|
1546 | /* |
---|
1547 | * "atexit()" failed; let our caller know. |
---|
1548 | */ |
---|
1549 | strncpy(p->errbuf, "atexit failed", |
---|
1550 | PCAP_ERRBUF_SIZE); |
---|
1551 | return (0); |
---|
1552 | } |
---|
1553 | did_atexit = 1; |
---|
1554 | } |
---|
1555 | return (1); |
---|
1556 | } |
---|
1557 | |
---|
1558 | void |
---|
1559 | pcap_add_to_pcaps_to_close(pcap_t *p) |
---|
1560 | { |
---|
1561 | p->md.next = pcaps_to_close; |
---|
1562 | pcaps_to_close = p; |
---|
1563 | } |
---|
1564 | |
---|
1565 | void |
---|
1566 | pcap_remove_from_pcaps_to_close(pcap_t *p) |
---|
1567 | { |
---|
1568 | pcap_t *pc, *prevpc; |
---|
1569 | |
---|
1570 | for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; |
---|
1571 | prevpc = pc, pc = pc->md.next) { |
---|
1572 | if (pc == p) { |
---|
1573 | /* |
---|
1574 | * Found it. Remove it from the list. |
---|
1575 | */ |
---|
1576 | if (prevpc == NULL) { |
---|
1577 | /* |
---|
1578 | * It was at the head of the list. |
---|
1579 | */ |
---|
1580 | pcaps_to_close = pc->md.next; |
---|
1581 | } else { |
---|
1582 | /* |
---|
1583 | * It was in the middle of the list. |
---|
1584 | */ |
---|
1585 | prevpc->md.next = pc->md.next; |
---|
1586 | } |
---|
1587 | break; |
---|
1588 | } |
---|
1589 | } |
---|
1590 | } |
---|
1591 | |
---|
1592 | void |
---|
1593 | pcap_cleanup_live_common(pcap_t *p) |
---|
1594 | { |
---|
1595 | if (p->buffer != NULL) { |
---|
1596 | free(p->buffer); |
---|
1597 | p->buffer = NULL; |
---|
1598 | } |
---|
1599 | if (p->dlt_list != NULL) { |
---|
1600 | free(p->dlt_list); |
---|
1601 | p->dlt_list = NULL; |
---|
1602 | p->dlt_count = 0; |
---|
1603 | } |
---|
1604 | if (p->tstamp_type_list != NULL) { |
---|
1605 | free(p->tstamp_type_list); |
---|
1606 | p->tstamp_type_list = NULL; |
---|
1607 | p->tstamp_type_count = 0; |
---|
1608 | } |
---|
1609 | pcap_freecode(&p->fcode); |
---|
1610 | #if !defined(WIN32) && !defined(MSDOS) |
---|
1611 | if (p->fd >= 0) { |
---|
1612 | close(p->fd); |
---|
1613 | p->fd = -1; |
---|
1614 | } |
---|
1615 | p->selectable_fd = -1; |
---|
1616 | p->send_fd = -1; |
---|
1617 | #endif |
---|
1618 | } |
---|
1619 | |
---|
1620 | static void |
---|
1621 | pcap_cleanup_dead(pcap_t *p _U_) |
---|
1622 | { |
---|
1623 | /* Nothing to do. */ |
---|
1624 | } |
---|
1625 | |
---|
1626 | pcap_t * |
---|
1627 | pcap_open_dead(int linktype, int snaplen) |
---|
1628 | { |
---|
1629 | pcap_t *p; |
---|
1630 | |
---|
1631 | p = malloc(sizeof(*p)); |
---|
1632 | if (p == NULL) |
---|
1633 | return NULL; |
---|
1634 | memset (p, 0, sizeof(*p)); |
---|
1635 | p->snapshot = snaplen; |
---|
1636 | p->linktype = linktype; |
---|
1637 | p->stats_op = pcap_stats_dead; |
---|
1638 | #ifdef WIN32 |
---|
1639 | p->setbuff_op = pcap_setbuff_dead; |
---|
1640 | p->setmode_op = pcap_setmode_dead; |
---|
1641 | p->setmintocopy_op = pcap_setmintocopy_dead; |
---|
1642 | #endif |
---|
1643 | p->cleanup_op = pcap_cleanup_dead; |
---|
1644 | p->activated = 1; |
---|
1645 | return (p); |
---|
1646 | } |
---|
1647 | |
---|
1648 | /* |
---|
1649 | * API compatible with WinPcap's "send a packet" routine - returns -1 |
---|
1650 | * on error, 0 otherwise. |
---|
1651 | * |
---|
1652 | * XXX - what if we get a short write? |
---|
1653 | */ |
---|
1654 | int |
---|
1655 | pcap_sendpacket(pcap_t *p, const u_char *buf, int size) |
---|
1656 | { |
---|
1657 | if (p->inject_op(p, buf, size) == -1) |
---|
1658 | return (-1); |
---|
1659 | return (0); |
---|
1660 | } |
---|
1661 | |
---|
1662 | /* |
---|
1663 | * API compatible with OpenBSD's "send a packet" routine - returns -1 on |
---|
1664 | * error, number of bytes written otherwise. |
---|
1665 | */ |
---|
1666 | int |
---|
1667 | pcap_inject(pcap_t *p, const void *buf, size_t size) |
---|
1668 | { |
---|
1669 | return (p->inject_op(p, buf, size)); |
---|
1670 | } |
---|
1671 | |
---|
1672 | void |
---|
1673 | pcap_close(pcap_t *p) |
---|
1674 | { |
---|
1675 | if (p->opt.source != NULL) |
---|
1676 | free(p->opt.source); |
---|
1677 | p->cleanup_op(p); |
---|
1678 | free(p); |
---|
1679 | } |
---|
1680 | |
---|
1681 | /* |
---|
1682 | * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw |
---|
1683 | * data for the packet, check whether the packet passes the filter. |
---|
1684 | * Returns the return value of the filter program, which will be zero if |
---|
1685 | * the packet doesn't pass and non-zero if the packet does pass. |
---|
1686 | */ |
---|
1687 | int |
---|
1688 | pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, |
---|
1689 | const u_char *pkt) |
---|
1690 | { |
---|
1691 | const struct bpf_insn *fcode = fp->bf_insns; |
---|
1692 | |
---|
1693 | if (fcode != NULL) |
---|
1694 | return (bpf_filter(fcode, pkt, h->len, h->caplen)); |
---|
1695 | else |
---|
1696 | return (0); |
---|
1697 | } |
---|
1698 | |
---|
1699 | /* |
---|
1700 | * We make the version string static, and return a pointer to it, rather |
---|
1701 | * than exporting the version string directly. On at least some UNIXes, |
---|
1702 | * if you import data from a shared library into an program, the data is |
---|
1703 | * bound into the program binary, so if the string in the version of the |
---|
1704 | * library with which the program was linked isn't the same as the |
---|
1705 | * string in the version of the library with which the program is being |
---|
1706 | * run, various undesirable things may happen (warnings, the string |
---|
1707 | * being the one from the version of the library with which the program |
---|
1708 | * was linked, or even weirder things, such as the string being the one |
---|
1709 | * from the library but being truncated). |
---|
1710 | */ |
---|
1711 | #ifdef HAVE_VERSION_H |
---|
1712 | #include "version.h" |
---|
1713 | #else |
---|
1714 | static const char pcap_version_string[] = "libpcap version 1.x.y"; |
---|
1715 | #endif |
---|
1716 | |
---|
1717 | #ifdef WIN32 |
---|
1718 | /* |
---|
1719 | * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap |
---|
1720 | * version numbers when building WinPcap. (It'd be nice to do so for |
---|
1721 | * the packet.dll version number as well.) |
---|
1722 | */ |
---|
1723 | static const char wpcap_version_string[] = "4.0"; |
---|
1724 | static const char pcap_version_string_fmt[] = |
---|
1725 | "WinPcap version %s, based on %s"; |
---|
1726 | static const char pcap_version_string_packet_dll_fmt[] = |
---|
1727 | "WinPcap version %s (packet.dll version %s), based on %s"; |
---|
1728 | static char *full_pcap_version_string; |
---|
1729 | |
---|
1730 | const char * |
---|
1731 | pcap_lib_version(void) |
---|
1732 | { |
---|
1733 | char *packet_version_string; |
---|
1734 | size_t full_pcap_version_string_len; |
---|
1735 | |
---|
1736 | if (full_pcap_version_string == NULL) { |
---|
1737 | /* |
---|
1738 | * Generate the version string. |
---|
1739 | */ |
---|
1740 | packet_version_string = PacketGetVersion(); |
---|
1741 | if (strcmp(wpcap_version_string, packet_version_string) == 0) { |
---|
1742 | /* |
---|
1743 | * WinPcap version string and packet.dll version |
---|
1744 | * string are the same; just report the WinPcap |
---|
1745 | * version. |
---|
1746 | */ |
---|
1747 | full_pcap_version_string_len = |
---|
1748 | (sizeof pcap_version_string_fmt - 4) + |
---|
1749 | strlen(wpcap_version_string) + |
---|
1750 | strlen(pcap_version_string); |
---|
1751 | full_pcap_version_string = |
---|
1752 | malloc(full_pcap_version_string_len); |
---|
1753 | sprintf(full_pcap_version_string, |
---|
1754 | pcap_version_string_fmt, wpcap_version_string, |
---|
1755 | pcap_version_string); |
---|
1756 | } else { |
---|
1757 | /* |
---|
1758 | * WinPcap version string and packet.dll version |
---|
1759 | * string are different; that shouldn't be the |
---|
1760 | * case (the two libraries should come from the |
---|
1761 | * same version of WinPcap), so we report both |
---|
1762 | * versions. |
---|
1763 | */ |
---|
1764 | full_pcap_version_string_len = |
---|
1765 | (sizeof pcap_version_string_packet_dll_fmt - 6) + |
---|
1766 | strlen(wpcap_version_string) + |
---|
1767 | strlen(packet_version_string) + |
---|
1768 | strlen(pcap_version_string); |
---|
1769 | full_pcap_version_string = malloc(full_pcap_version_string_len); |
---|
1770 | |
---|
1771 | sprintf(full_pcap_version_string, |
---|
1772 | pcap_version_string_packet_dll_fmt, |
---|
1773 | wpcap_version_string, packet_version_string, |
---|
1774 | pcap_version_string); |
---|
1775 | } |
---|
1776 | } |
---|
1777 | return (full_pcap_version_string); |
---|
1778 | } |
---|
1779 | |
---|
1780 | #elif defined(MSDOS) |
---|
1781 | |
---|
1782 | static char *full_pcap_version_string; |
---|
1783 | |
---|
1784 | const char * |
---|
1785 | pcap_lib_version (void) |
---|
1786 | { |
---|
1787 | char *packet_version_string; |
---|
1788 | size_t full_pcap_version_string_len; |
---|
1789 | static char dospfx[] = "DOS-"; |
---|
1790 | |
---|
1791 | if (full_pcap_version_string == NULL) { |
---|
1792 | /* |
---|
1793 | * Generate the version string. |
---|
1794 | */ |
---|
1795 | full_pcap_version_string_len = |
---|
1796 | sizeof dospfx + strlen(pcap_version_string); |
---|
1797 | full_pcap_version_string = |
---|
1798 | malloc(full_pcap_version_string_len); |
---|
1799 | strcpy(full_pcap_version_string, dospfx); |
---|
1800 | strcat(full_pcap_version_string, pcap_version_string); |
---|
1801 | } |
---|
1802 | return (full_pcap_version_string); |
---|
1803 | } |
---|
1804 | |
---|
1805 | #else /* UN*X */ |
---|
1806 | |
---|
1807 | const char * |
---|
1808 | pcap_lib_version(void) |
---|
1809 | { |
---|
1810 | return (pcap_version_string); |
---|
1811 | } |
---|
1812 | #endif |
---|