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 | #ifdef HAVE_CONFIG_H |
---|
37 | #include "config.h" |
---|
38 | #endif |
---|
39 | |
---|
40 | #ifdef _WIN32 |
---|
41 | #include <pcap-stdinc.h> |
---|
42 | #else /* _WIN32 */ |
---|
43 | #if HAVE_INTTYPES_H |
---|
44 | #include <inttypes.h> |
---|
45 | #elif HAVE_STDINT_H |
---|
46 | #include <stdint.h> |
---|
47 | #endif |
---|
48 | #ifdef HAVE_SYS_BITYPES_H |
---|
49 | #include <sys/bitypes.h> |
---|
50 | #endif |
---|
51 | #include <sys/types.h> |
---|
52 | #include <sys/mman.h> |
---|
53 | #endif /* _WIN32 */ |
---|
54 | |
---|
55 | #include <stdio.h> |
---|
56 | #include <stdlib.h> |
---|
57 | #include <string.h> |
---|
58 | #if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__) |
---|
59 | #include <unistd.h> |
---|
60 | #endif |
---|
61 | #include <fcntl.h> |
---|
62 | #include <errno.h> |
---|
63 | |
---|
64 | #ifdef HAVE_OS_PROTO_H |
---|
65 | #include "os-proto.h" |
---|
66 | #endif |
---|
67 | |
---|
68 | #ifdef MSDOS |
---|
69 | #include "pcap-dos.h" |
---|
70 | #endif |
---|
71 | |
---|
72 | #include "pcap-int.h" |
---|
73 | |
---|
74 | #ifdef HAVE_DAG_API |
---|
75 | #include "pcap-dag.h" |
---|
76 | #endif /* HAVE_DAG_API */ |
---|
77 | |
---|
78 | #ifdef HAVE_SEPTEL_API |
---|
79 | #include "pcap-septel.h" |
---|
80 | #endif /* HAVE_SEPTEL_API */ |
---|
81 | |
---|
82 | #ifdef HAVE_SNF_API |
---|
83 | #include "pcap-snf.h" |
---|
84 | #endif /* HAVE_SNF_API */ |
---|
85 | |
---|
86 | #ifdef HAVE_TC_API |
---|
87 | #include "pcap-tc.h" |
---|
88 | #endif /* HAVE_TC_API */ |
---|
89 | |
---|
90 | #ifdef PCAP_SUPPORT_USB |
---|
91 | #include "pcap-usb-linux.h" |
---|
92 | #endif |
---|
93 | |
---|
94 | #ifdef PCAP_SUPPORT_BT |
---|
95 | #include "pcap-bt-linux.h" |
---|
96 | #endif |
---|
97 | |
---|
98 | #ifdef PCAP_SUPPORT_BT_MONITOR |
---|
99 | #include "pcap-bt-monitor-linux.h" |
---|
100 | #endif |
---|
101 | |
---|
102 | #ifdef PCAP_SUPPORT_NETFILTER |
---|
103 | #include "pcap-netfilter-linux.h" |
---|
104 | #endif |
---|
105 | |
---|
106 | #ifdef PCAP_SUPPORT_NETMAP |
---|
107 | pcap_t* pcap_netmap_create(const char *device, char *ebuf, int *is_ours); |
---|
108 | #endif |
---|
109 | |
---|
110 | #ifdef PCAP_SUPPORT_DBUS |
---|
111 | #include "pcap-dbus.h" |
---|
112 | #endif |
---|
113 | |
---|
114 | static int |
---|
115 | pcap_not_initialized(pcap_t *pcap) |
---|
116 | { |
---|
117 | /* in case the caller doesn't check for PCAP_ERROR_NOT_ACTIVATED */ |
---|
118 | (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), |
---|
119 | "This handle hasn't been activated yet"); |
---|
120 | /* this means 'not initialized' */ |
---|
121 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
122 | } |
---|
123 | |
---|
124 | #ifdef _WIN32 |
---|
125 | static void * |
---|
126 | pcap_not_initialized_ptr(pcap_t *pcap) |
---|
127 | { |
---|
128 | (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), |
---|
129 | "This handle hasn't been activated yet"); |
---|
130 | return (NULL); |
---|
131 | } |
---|
132 | |
---|
133 | static HANDLE |
---|
134 | pcap_getevent_not_initialized(pcap_t *pcap) |
---|
135 | { |
---|
136 | (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), |
---|
137 | "This handle hasn't been activated yet"); |
---|
138 | return (INVALID_HANDLE_VALUE); |
---|
139 | } |
---|
140 | |
---|
141 | static u_int |
---|
142 | pcap_sendqueue_transmit_not_initialized(pcap_t *pcap, pcap_send_queue* queue, int sync) |
---|
143 | { |
---|
144 | (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), |
---|
145 | "This handle hasn't been activated yet"); |
---|
146 | return (0); |
---|
147 | } |
---|
148 | |
---|
149 | static PAirpcapHandle |
---|
150 | pcap_get_airpcap_handle_not_initialized(pcap_t *pcap) |
---|
151 | { |
---|
152 | (void)pcap_snprintf(pcap->errbuf, sizeof(pcap->errbuf), |
---|
153 | "This handle hasn't been activated yet"); |
---|
154 | return (NULL); |
---|
155 | } |
---|
156 | #endif |
---|
157 | |
---|
158 | /* |
---|
159 | * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't, |
---|
160 | * a PCAP_ERROR value on an error. |
---|
161 | */ |
---|
162 | int |
---|
163 | pcap_can_set_rfmon(pcap_t *p) |
---|
164 | { |
---|
165 | return (p->can_set_rfmon_op(p)); |
---|
166 | } |
---|
167 | |
---|
168 | /* |
---|
169 | * For systems where rfmon mode is never supported. |
---|
170 | */ |
---|
171 | static int |
---|
172 | pcap_cant_set_rfmon(pcap_t *p _U_) |
---|
173 | { |
---|
174 | return (0); |
---|
175 | } |
---|
176 | |
---|
177 | /* |
---|
178 | * Sets *tstamp_typesp to point to an array 1 or more supported time stamp |
---|
179 | * types; the return value is the number of supported time stamp types. |
---|
180 | * The list should be freed by a call to pcap_free_tstamp_types() when |
---|
181 | * you're done with it. |
---|
182 | * |
---|
183 | * A return value of 0 means "you don't get a choice of time stamp type", |
---|
184 | * in which case *tstamp_typesp is set to null. |
---|
185 | * |
---|
186 | * PCAP_ERROR is returned on error. |
---|
187 | */ |
---|
188 | int |
---|
189 | pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp) |
---|
190 | { |
---|
191 | if (p->tstamp_type_count == 0) { |
---|
192 | /* |
---|
193 | * We don't support multiple time stamp types. |
---|
194 | */ |
---|
195 | *tstamp_typesp = NULL; |
---|
196 | } else { |
---|
197 | *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp), |
---|
198 | p->tstamp_type_count); |
---|
199 | if (*tstamp_typesp == NULL) { |
---|
200 | (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), |
---|
201 | "malloc: %s", pcap_strerror(errno)); |
---|
202 | return (PCAP_ERROR); |
---|
203 | } |
---|
204 | (void)memcpy(*tstamp_typesp, p->tstamp_type_list, |
---|
205 | sizeof(**tstamp_typesp) * p->tstamp_type_count); |
---|
206 | } |
---|
207 | return (p->tstamp_type_count); |
---|
208 | } |
---|
209 | |
---|
210 | /* |
---|
211 | * In Windows, you might have a library built with one version of the |
---|
212 | * C runtime library and an application built with another version of |
---|
213 | * the C runtime library, which means that the library might use one |
---|
214 | * version of malloc() and free() and the application might use another |
---|
215 | * version of malloc() and free(). If so, that means something |
---|
216 | * allocated by the library cannot be freed by the application, so we |
---|
217 | * need to have a pcap_free_tstamp_types() routine to free up the list |
---|
218 | * allocated by pcap_list_tstamp_types(), even though it's just a wrapper |
---|
219 | * around free(). |
---|
220 | */ |
---|
221 | void |
---|
222 | pcap_free_tstamp_types(int *tstamp_type_list) |
---|
223 | { |
---|
224 | free(tstamp_type_list); |
---|
225 | } |
---|
226 | |
---|
227 | /* |
---|
228 | * Default one-shot callback; overridden for capture types where the |
---|
229 | * packet data cannot be guaranteed to be available after the callback |
---|
230 | * returns, so that a copy must be made. |
---|
231 | */ |
---|
232 | void |
---|
233 | pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt) |
---|
234 | { |
---|
235 | struct oneshot_userdata *sp = (struct oneshot_userdata *)user; |
---|
236 | |
---|
237 | *sp->hdr = *h; |
---|
238 | *sp->pkt = pkt; |
---|
239 | } |
---|
240 | |
---|
241 | const u_char * |
---|
242 | pcap_next(pcap_t *p, struct pcap_pkthdr *h) |
---|
243 | { |
---|
244 | struct oneshot_userdata s; |
---|
245 | const u_char *pkt; |
---|
246 | |
---|
247 | s.hdr = h; |
---|
248 | s.pkt = &pkt; |
---|
249 | s.pd = p; |
---|
250 | if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0) |
---|
251 | return (0); |
---|
252 | return (pkt); |
---|
253 | } |
---|
254 | |
---|
255 | int |
---|
256 | pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, |
---|
257 | const u_char **pkt_data) |
---|
258 | { |
---|
259 | struct oneshot_userdata s; |
---|
260 | |
---|
261 | s.hdr = &p->pcap_header; |
---|
262 | s.pkt = pkt_data; |
---|
263 | s.pd = p; |
---|
264 | |
---|
265 | /* Saves a pointer to the packet headers */ |
---|
266 | *pkt_header= &p->pcap_header; |
---|
267 | |
---|
268 | if (p->rfile != NULL) { |
---|
269 | int status; |
---|
270 | |
---|
271 | /* We are on an offline capture */ |
---|
272 | status = pcap_offline_read(p, 1, p->oneshot_callback, |
---|
273 | (u_char *)&s); |
---|
274 | |
---|
275 | /* |
---|
276 | * Return codes for pcap_offline_read() are: |
---|
277 | * - 0: EOF |
---|
278 | * - -1: error |
---|
279 | * - >1: OK |
---|
280 | * The first one ('0') conflicts with the return code of |
---|
281 | * 0 from pcap_read() meaning "no packets arrived before |
---|
282 | * the timeout expired", so we map it to -2 so you can |
---|
283 | * distinguish between an EOF from a savefile and a |
---|
284 | * "no packets arrived before the timeout expired, try |
---|
285 | * again" from a live capture. |
---|
286 | */ |
---|
287 | if (status == 0) |
---|
288 | return (-2); |
---|
289 | else |
---|
290 | return (status); |
---|
291 | } |
---|
292 | |
---|
293 | /* |
---|
294 | * Return codes for pcap_read() are: |
---|
295 | * - 0: timeout |
---|
296 | * - -1: error |
---|
297 | * - -2: loop was broken out of with pcap_breakloop() |
---|
298 | * - >1: OK |
---|
299 | * The first one ('0') conflicts with the return code of 0 from |
---|
300 | * pcap_offline_read() meaning "end of file". |
---|
301 | */ |
---|
302 | return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s)); |
---|
303 | } |
---|
304 | |
---|
305 | static struct capture_source_type { |
---|
306 | int (*findalldevs_op)(pcap_if_t **, char *); |
---|
307 | pcap_t *(*create_op)(const char *, char *, int *); |
---|
308 | } capture_source_types[] = { |
---|
309 | #ifdef PCAP_SUPPORT_NETMAP |
---|
310 | { NULL, pcap_netmap_create }, |
---|
311 | #endif |
---|
312 | #ifdef HAVE_DAG_API |
---|
313 | { dag_findalldevs, dag_create }, |
---|
314 | #endif |
---|
315 | #ifdef HAVE_SEPTEL_API |
---|
316 | { septel_findalldevs, septel_create }, |
---|
317 | #endif |
---|
318 | #ifdef HAVE_SNF_API |
---|
319 | { snf_findalldevs, snf_create }, |
---|
320 | #endif |
---|
321 | #ifdef HAVE_TC_API |
---|
322 | { TcFindAllDevs, TcCreate }, |
---|
323 | #endif |
---|
324 | #ifdef PCAP_SUPPORT_BT |
---|
325 | { bt_findalldevs, bt_create }, |
---|
326 | #endif |
---|
327 | #ifdef PCAP_SUPPORT_BT_MONITOR |
---|
328 | { bt_monitor_findalldevs, bt_monitor_create }, |
---|
329 | #endif |
---|
330 | #ifdef PCAP_SUPPORT_USB |
---|
331 | { usb_findalldevs, usb_create }, |
---|
332 | #endif |
---|
333 | #ifdef PCAP_SUPPORT_NETFILTER |
---|
334 | { netfilter_findalldevs, netfilter_create }, |
---|
335 | #endif |
---|
336 | #ifdef PCAP_SUPPORT_DBUS |
---|
337 | { dbus_findalldevs, dbus_create }, |
---|
338 | #endif |
---|
339 | { NULL, NULL } |
---|
340 | }; |
---|
341 | |
---|
342 | /* |
---|
343 | * Get a list of all capture sources that are up and that we can open. |
---|
344 | * Returns -1 on error, 0 otherwise. |
---|
345 | * The list, as returned through "alldevsp", may be null if no interfaces |
---|
346 | * were up and could be opened. |
---|
347 | */ |
---|
348 | int |
---|
349 | pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) |
---|
350 | { |
---|
351 | size_t i; |
---|
352 | |
---|
353 | /* |
---|
354 | * Find all the local network interfaces on which we |
---|
355 | * can capture. |
---|
356 | */ |
---|
357 | if (pcap_platform_finddevs(alldevsp, errbuf) == -1) |
---|
358 | return (-1); |
---|
359 | |
---|
360 | /* |
---|
361 | * Ask each of the non-local-network-interface capture |
---|
362 | * source types what interfaces they have. |
---|
363 | */ |
---|
364 | for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) { |
---|
365 | if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) { |
---|
366 | /* |
---|
367 | * We had an error; free the list we've been |
---|
368 | * constructing. |
---|
369 | */ |
---|
370 | if (*alldevsp != NULL) { |
---|
371 | pcap_freealldevs(*alldevsp); |
---|
372 | *alldevsp = NULL; |
---|
373 | } |
---|
374 | return (-1); |
---|
375 | } |
---|
376 | } |
---|
377 | |
---|
378 | return (0); |
---|
379 | } |
---|
380 | |
---|
381 | pcap_t * |
---|
382 | pcap_create(const char *device, char *errbuf) |
---|
383 | { |
---|
384 | size_t i; |
---|
385 | int is_theirs; |
---|
386 | pcap_t *p; |
---|
387 | char *device_str; |
---|
388 | |
---|
389 | /* |
---|
390 | * A null device name is equivalent to the "any" device - |
---|
391 | * which might not be supported on this platform, but |
---|
392 | * this means that you'll get a "not supported" error |
---|
393 | * rather than, say, a crash when we try to dereference |
---|
394 | * the null pointer. |
---|
395 | */ |
---|
396 | if (device == NULL) |
---|
397 | device_str = strdup("any"); |
---|
398 | else { |
---|
399 | #ifdef _WIN32 |
---|
400 | /* |
---|
401 | * If the string appears to be little-endian UCS-2/UTF-16, |
---|
402 | * convert it to ASCII. |
---|
403 | * |
---|
404 | * XXX - to UTF-8 instead? Or report an error if any |
---|
405 | * character isn't ASCII? |
---|
406 | */ |
---|
407 | if (device[0] != '\0' && device[1] == '\0') { |
---|
408 | size_t length; |
---|
409 | |
---|
410 | length = wcslen((wchar_t *)device); |
---|
411 | device_str = (char *)malloc(length + 1); |
---|
412 | if (device_str == NULL) { |
---|
413 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
---|
414 | "malloc: %s", pcap_strerror(errno)); |
---|
415 | return (NULL); |
---|
416 | } |
---|
417 | |
---|
418 | pcap_snprintf(device_str, length + 1, "%ws", |
---|
419 | (const wchar_t *)device); |
---|
420 | } else |
---|
421 | #endif |
---|
422 | device_str = strdup(device); |
---|
423 | } |
---|
424 | if (device_str == NULL) { |
---|
425 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, |
---|
426 | "malloc: %s", pcap_strerror(errno)); |
---|
427 | return (NULL); |
---|
428 | } |
---|
429 | |
---|
430 | /* |
---|
431 | * Try each of the non-local-network-interface capture |
---|
432 | * source types until we find one that works for this |
---|
433 | * device or run out of types. |
---|
434 | */ |
---|
435 | for (i = 0; capture_source_types[i].create_op != NULL; i++) { |
---|
436 | is_theirs = 0; |
---|
437 | p = capture_source_types[i].create_op(device_str, errbuf, |
---|
438 | &is_theirs); |
---|
439 | if (is_theirs) { |
---|
440 | /* |
---|
441 | * The device name refers to a device of the |
---|
442 | * type in question; either it succeeded, |
---|
443 | * in which case p refers to a pcap_t to |
---|
444 | * later activate for the device, or it |
---|
445 | * failed, in which case p is null and we |
---|
446 | * should return that to report the failure |
---|
447 | * to create. |
---|
448 | */ |
---|
449 | if (p == NULL) { |
---|
450 | /* |
---|
451 | * We assume the caller filled in errbuf. |
---|
452 | */ |
---|
453 | free(device_str); |
---|
454 | return (NULL); |
---|
455 | } |
---|
456 | p->opt.device = device_str; |
---|
457 | return (p); |
---|
458 | } |
---|
459 | } |
---|
460 | |
---|
461 | /* |
---|
462 | * OK, try it as a regular network interface. |
---|
463 | */ |
---|
464 | p = pcap_create_interface(device_str, errbuf); |
---|
465 | if (p == NULL) { |
---|
466 | /* |
---|
467 | * We assume the caller filled in errbuf. |
---|
468 | */ |
---|
469 | free(device_str); |
---|
470 | return (NULL); |
---|
471 | } |
---|
472 | p->opt.device = device_str; |
---|
473 | return (p); |
---|
474 | } |
---|
475 | |
---|
476 | static void |
---|
477 | initialize_ops(pcap_t *p) |
---|
478 | { |
---|
479 | /* |
---|
480 | * Set operation pointers for operations that only work on |
---|
481 | * an activated pcap_t to point to a routine that returns |
---|
482 | * a "this isn't activated" error. |
---|
483 | */ |
---|
484 | p->read_op = (read_op_t)pcap_not_initialized; |
---|
485 | p->inject_op = (inject_op_t)pcap_not_initialized; |
---|
486 | p->setfilter_op = (setfilter_op_t)pcap_not_initialized; |
---|
487 | p->setdirection_op = (setdirection_op_t)pcap_not_initialized; |
---|
488 | p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized; |
---|
489 | p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized; |
---|
490 | p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized; |
---|
491 | p->stats_op = (stats_op_t)pcap_not_initialized; |
---|
492 | #ifdef _WIN32 |
---|
493 | p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr; |
---|
494 | p->setbuff_op = (setbuff_op_t)pcap_not_initialized; |
---|
495 | p->setmode_op = (setmode_op_t)pcap_not_initialized; |
---|
496 | p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized; |
---|
497 | p->getevent_op = pcap_getevent_not_initialized; |
---|
498 | p->oid_get_request_op = (oid_get_request_op_t)pcap_not_initialized; |
---|
499 | p->oid_set_request_op = (oid_set_request_op_t)pcap_not_initialized; |
---|
500 | p->sendqueue_transmit_op = pcap_sendqueue_transmit_not_initialized; |
---|
501 | p->setuserbuffer_op = (setuserbuffer_op_t)pcap_not_initialized; |
---|
502 | p->live_dump_op = (live_dump_op_t)pcap_not_initialized; |
---|
503 | p->live_dump_ended_op = (live_dump_ended_op_t)pcap_not_initialized; |
---|
504 | p->get_airpcap_handle_op = pcap_get_airpcap_handle_not_initialized; |
---|
505 | #endif |
---|
506 | |
---|
507 | /* |
---|
508 | * Default cleanup operation - implementations can override |
---|
509 | * this, but should call pcap_cleanup_live_common() after |
---|
510 | * doing their own additional cleanup. |
---|
511 | */ |
---|
512 | p->cleanup_op = pcap_cleanup_live_common; |
---|
513 | |
---|
514 | /* |
---|
515 | * In most cases, the standard one-shot callback can |
---|
516 | * be used for pcap_next()/pcap_next_ex(). |
---|
517 | */ |
---|
518 | p->oneshot_callback = pcap_oneshot; |
---|
519 | } |
---|
520 | |
---|
521 | static pcap_t * |
---|
522 | pcap_alloc_pcap_t(char *ebuf, size_t size) |
---|
523 | { |
---|
524 | char *chunk; |
---|
525 | pcap_t *p; |
---|
526 | |
---|
527 | /* |
---|
528 | * Allocate a chunk of memory big enough for a pcap_t |
---|
529 | * plus a structure following it of size "size". The |
---|
530 | * structure following it is a private data structure |
---|
531 | * for the routines that handle this pcap_t. |
---|
532 | */ |
---|
533 | chunk = malloc(sizeof (pcap_t) + size); |
---|
534 | if (chunk == NULL) { |
---|
535 | pcap_snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", |
---|
536 | pcap_strerror(errno)); |
---|
537 | return (NULL); |
---|
538 | } |
---|
539 | memset(chunk, 0, sizeof (pcap_t) + size); |
---|
540 | |
---|
541 | /* |
---|
542 | * Get a pointer to the pcap_t at the beginning. |
---|
543 | */ |
---|
544 | p = (pcap_t *)chunk; |
---|
545 | |
---|
546 | #ifndef _WIN32 |
---|
547 | p->fd = -1; /* not opened yet */ |
---|
548 | p->selectable_fd = -1; |
---|
549 | #endif |
---|
550 | |
---|
551 | if (size == 0) { |
---|
552 | /* No private data was requested. */ |
---|
553 | p->priv = NULL; |
---|
554 | } else { |
---|
555 | /* |
---|
556 | * Set the pointer to the private data; that's the structure |
---|
557 | * of size "size" following the pcap_t. |
---|
558 | */ |
---|
559 | p->priv = (void *)(chunk + sizeof (pcap_t)); |
---|
560 | } |
---|
561 | |
---|
562 | return (p); |
---|
563 | } |
---|
564 | |
---|
565 | pcap_t * |
---|
566 | pcap_create_common(char *ebuf, size_t size) |
---|
567 | { |
---|
568 | pcap_t *p; |
---|
569 | |
---|
570 | p = pcap_alloc_pcap_t(ebuf, size); |
---|
571 | if (p == NULL) |
---|
572 | return (NULL); |
---|
573 | |
---|
574 | /* |
---|
575 | * Default to "can't set rfmon mode"; if it's supported by |
---|
576 | * a platform, the create routine that called us can set |
---|
577 | * the op to its routine to check whether a particular |
---|
578 | * device supports it. |
---|
579 | */ |
---|
580 | p->can_set_rfmon_op = pcap_cant_set_rfmon; |
---|
581 | |
---|
582 | initialize_ops(p); |
---|
583 | |
---|
584 | /* put in some defaults*/ |
---|
585 | p->snapshot = MAXIMUM_SNAPLEN; /* max packet size */ |
---|
586 | p->opt.timeout = 0; /* no timeout specified */ |
---|
587 | p->opt.buffer_size = 0; /* use the platform's default */ |
---|
588 | p->opt.promisc = 0; |
---|
589 | p->opt.rfmon = 0; |
---|
590 | p->opt.immediate = 0; |
---|
591 | p->opt.tstamp_type = -1; /* default to not setting time stamp type */ |
---|
592 | p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO; |
---|
593 | |
---|
594 | /* |
---|
595 | * Start out with no BPF code generation flags set. |
---|
596 | */ |
---|
597 | p->bpf_codegen_flags = 0; |
---|
598 | |
---|
599 | return (p); |
---|
600 | } |
---|
601 | |
---|
602 | int |
---|
603 | pcap_check_activated(pcap_t *p) |
---|
604 | { |
---|
605 | if (p->activated) { |
---|
606 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform " |
---|
607 | " operation on activated capture"); |
---|
608 | return (-1); |
---|
609 | } |
---|
610 | return (0); |
---|
611 | } |
---|
612 | |
---|
613 | int |
---|
614 | pcap_set_snaplen(pcap_t *p, int snaplen) |
---|
615 | { |
---|
616 | if (pcap_check_activated(p)) |
---|
617 | return (PCAP_ERROR_ACTIVATED); |
---|
618 | |
---|
619 | /* |
---|
620 | * Turn invalid values, or excessively large values, into |
---|
621 | * the maximum allowed value. |
---|
622 | * |
---|
623 | * If some application really *needs* a bigger snapshot |
---|
624 | * length, we should just increase MAXIMUM_SNAPLEN. |
---|
625 | */ |
---|
626 | if (snaplen <= 0 || snaplen > MAXIMUM_SNAPLEN) |
---|
627 | snaplen = MAXIMUM_SNAPLEN; |
---|
628 | p->snapshot = snaplen; |
---|
629 | return (0); |
---|
630 | } |
---|
631 | |
---|
632 | int |
---|
633 | pcap_set_promisc(pcap_t *p, int promisc) |
---|
634 | { |
---|
635 | if (pcap_check_activated(p)) |
---|
636 | return (PCAP_ERROR_ACTIVATED); |
---|
637 | p->opt.promisc = promisc; |
---|
638 | return (0); |
---|
639 | } |
---|
640 | |
---|
641 | int |
---|
642 | pcap_set_rfmon(pcap_t *p, int rfmon) |
---|
643 | { |
---|
644 | if (pcap_check_activated(p)) |
---|
645 | return (PCAP_ERROR_ACTIVATED); |
---|
646 | p->opt.rfmon = rfmon; |
---|
647 | return (0); |
---|
648 | } |
---|
649 | |
---|
650 | int |
---|
651 | pcap_set_timeout(pcap_t *p, int timeout_ms) |
---|
652 | { |
---|
653 | if (pcap_check_activated(p)) |
---|
654 | return (PCAP_ERROR_ACTIVATED); |
---|
655 | p->opt.timeout = timeout_ms; |
---|
656 | return (0); |
---|
657 | } |
---|
658 | |
---|
659 | int |
---|
660 | pcap_set_tstamp_type(pcap_t *p, int tstamp_type) |
---|
661 | { |
---|
662 | int i; |
---|
663 | |
---|
664 | if (pcap_check_activated(p)) |
---|
665 | return (PCAP_ERROR_ACTIVATED); |
---|
666 | |
---|
667 | /* |
---|
668 | * The argument should have been u_int, but that's too late |
---|
669 | * to change now - it's an API. |
---|
670 | */ |
---|
671 | if (tstamp_type < 0) |
---|
672 | return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); |
---|
673 | |
---|
674 | /* |
---|
675 | * If p->tstamp_type_count is 0, we only support PCAP_TSTAMP_HOST; |
---|
676 | * the default time stamp type is PCAP_TSTAMP_HOST. |
---|
677 | */ |
---|
678 | if (p->tstamp_type_count == 0) { |
---|
679 | if (tstamp_type == PCAP_TSTAMP_HOST) { |
---|
680 | p->opt.tstamp_type = tstamp_type; |
---|
681 | return (0); |
---|
682 | } |
---|
683 | } else { |
---|
684 | /* |
---|
685 | * Check whether we claim to support this type of time stamp. |
---|
686 | */ |
---|
687 | for (i = 0; i < p->tstamp_type_count; i++) { |
---|
688 | if (p->tstamp_type_list[i] == (u_int)tstamp_type) { |
---|
689 | /* |
---|
690 | * Yes. |
---|
691 | */ |
---|
692 | p->opt.tstamp_type = tstamp_type; |
---|
693 | return (0); |
---|
694 | } |
---|
695 | } |
---|
696 | } |
---|
697 | |
---|
698 | /* |
---|
699 | * We don't support this type of time stamp. |
---|
700 | */ |
---|
701 | return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP); |
---|
702 | } |
---|
703 | |
---|
704 | int |
---|
705 | pcap_set_immediate_mode(pcap_t *p, int immediate) |
---|
706 | { |
---|
707 | if (pcap_check_activated(p)) |
---|
708 | return (PCAP_ERROR_ACTIVATED); |
---|
709 | p->opt.immediate = immediate; |
---|
710 | return (0); |
---|
711 | } |
---|
712 | |
---|
713 | int |
---|
714 | pcap_set_buffer_size(pcap_t *p, int buffer_size) |
---|
715 | { |
---|
716 | if (pcap_check_activated(p)) |
---|
717 | return (PCAP_ERROR_ACTIVATED); |
---|
718 | if (buffer_size <= 0) { |
---|
719 | /* |
---|
720 | * Silently ignore invalid values. |
---|
721 | */ |
---|
722 | return (0); |
---|
723 | } |
---|
724 | p->opt.buffer_size = buffer_size; |
---|
725 | return (0); |
---|
726 | } |
---|
727 | |
---|
728 | int |
---|
729 | pcap_set_tstamp_precision(pcap_t *p, int tstamp_precision) |
---|
730 | { |
---|
731 | int i; |
---|
732 | |
---|
733 | if (pcap_check_activated(p)) |
---|
734 | return (PCAP_ERROR_ACTIVATED); |
---|
735 | |
---|
736 | /* |
---|
737 | * The argument should have been u_int, but that's too late |
---|
738 | * to change now - it's an API. |
---|
739 | */ |
---|
740 | if (tstamp_precision < 0) |
---|
741 | return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP); |
---|
742 | |
---|
743 | /* |
---|
744 | * If p->tstamp_precision_count is 0, we only support setting |
---|
745 | * the time stamp precision to microsecond precision; every |
---|
746 | * pcap module *MUST* support microsecond precision, even if |
---|
747 | * it does so by converting the native precision to |
---|
748 | * microseconds. |
---|
749 | */ |
---|
750 | if (p->tstamp_precision_count == 0) { |
---|
751 | if (tstamp_precision == PCAP_TSTAMP_PRECISION_MICRO) { |
---|
752 | p->opt.tstamp_precision = tstamp_precision; |
---|
753 | return (0); |
---|
754 | } |
---|
755 | } else { |
---|
756 | /* |
---|
757 | * Check whether we claim to support this precision of |
---|
758 | * time stamp. |
---|
759 | */ |
---|
760 | for (i = 0; i < p->tstamp_precision_count; i++) { |
---|
761 | if (p->tstamp_precision_list[i] == (u_int)tstamp_precision) { |
---|
762 | /* |
---|
763 | * Yes. |
---|
764 | */ |
---|
765 | p->opt.tstamp_precision = tstamp_precision; |
---|
766 | return (0); |
---|
767 | } |
---|
768 | } |
---|
769 | } |
---|
770 | |
---|
771 | /* |
---|
772 | * We don't support this time stamp precision. |
---|
773 | */ |
---|
774 | return (PCAP_ERROR_TSTAMP_PRECISION_NOTSUP); |
---|
775 | } |
---|
776 | |
---|
777 | int |
---|
778 | pcap_get_tstamp_precision(pcap_t *p) |
---|
779 | { |
---|
780 | return (p->opt.tstamp_precision); |
---|
781 | } |
---|
782 | |
---|
783 | int |
---|
784 | pcap_activate(pcap_t *p) |
---|
785 | { |
---|
786 | int status; |
---|
787 | |
---|
788 | /* |
---|
789 | * Catch attempts to re-activate an already-activated |
---|
790 | * pcap_t; this should, for example, catch code that |
---|
791 | * calls pcap_open_live() followed by pcap_activate(), |
---|
792 | * as some code that showed up in a Stack Exchange |
---|
793 | * question did. |
---|
794 | */ |
---|
795 | if (pcap_check_activated(p)) |
---|
796 | return (PCAP_ERROR_ACTIVATED); |
---|
797 | status = p->activate_op(p); |
---|
798 | if (status >= 0) |
---|
799 | p->activated = 1; |
---|
800 | else { |
---|
801 | if (p->errbuf[0] == '\0') { |
---|
802 | /* |
---|
803 | * No error message supplied by the activate routine; |
---|
804 | * for the benefit of programs that don't specially |
---|
805 | * handle errors other than PCAP_ERROR, return the |
---|
806 | * error message corresponding to the status. |
---|
807 | */ |
---|
808 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s", |
---|
809 | pcap_statustostr(status)); |
---|
810 | } |
---|
811 | |
---|
812 | /* |
---|
813 | * Undo any operation pointer setting, etc. done by |
---|
814 | * the activate operation. |
---|
815 | */ |
---|
816 | initialize_ops(p); |
---|
817 | } |
---|
818 | return (status); |
---|
819 | } |
---|
820 | |
---|
821 | pcap_t * |
---|
822 | pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, char *errbuf) |
---|
823 | { |
---|
824 | pcap_t *p; |
---|
825 | int status; |
---|
826 | |
---|
827 | p = pcap_create(device, errbuf); |
---|
828 | if (p == NULL) |
---|
829 | return (NULL); |
---|
830 | status = pcap_set_snaplen(p, snaplen); |
---|
831 | if (status < 0) |
---|
832 | goto fail; |
---|
833 | status = pcap_set_promisc(p, promisc); |
---|
834 | if (status < 0) |
---|
835 | goto fail; |
---|
836 | status = pcap_set_timeout(p, to_ms); |
---|
837 | if (status < 0) |
---|
838 | goto fail; |
---|
839 | /* |
---|
840 | * Mark this as opened with pcap_open_live(), so that, for |
---|
841 | * example, we show the full list of DLT_ values, rather |
---|
842 | * than just the ones that are compatible with capturing |
---|
843 | * when not in monitor mode. That allows existing applications |
---|
844 | * to work the way they used to work, but allows new applications |
---|
845 | * that know about the new open API to, for example, find out the |
---|
846 | * DLT_ values that they can select without changing whether |
---|
847 | * the adapter is in monitor mode or not. |
---|
848 | */ |
---|
849 | p->oldstyle = 1; |
---|
850 | status = pcap_activate(p); |
---|
851 | if (status < 0) |
---|
852 | goto fail; |
---|
853 | return (p); |
---|
854 | fail: |
---|
855 | if (status == PCAP_ERROR) |
---|
856 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, |
---|
857 | p->errbuf); |
---|
858 | else if (status == PCAP_ERROR_NO_SUCH_DEVICE || |
---|
859 | status == PCAP_ERROR_PERM_DENIED || |
---|
860 | status == PCAP_ERROR_PROMISC_PERM_DENIED) |
---|
861 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", device, |
---|
862 | pcap_statustostr(status), p->errbuf); |
---|
863 | else |
---|
864 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", device, |
---|
865 | pcap_statustostr(status)); |
---|
866 | pcap_close(p); |
---|
867 | return (NULL); |
---|
868 | } |
---|
869 | |
---|
870 | pcap_t * |
---|
871 | pcap_open_offline_common(char *ebuf, size_t size) |
---|
872 | { |
---|
873 | pcap_t *p; |
---|
874 | |
---|
875 | p = pcap_alloc_pcap_t(ebuf, size); |
---|
876 | if (p == NULL) |
---|
877 | return (NULL); |
---|
878 | |
---|
879 | p->opt.tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO; |
---|
880 | |
---|
881 | return (p); |
---|
882 | } |
---|
883 | |
---|
884 | int |
---|
885 | pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user) |
---|
886 | { |
---|
887 | return (p->read_op(p, cnt, callback, user)); |
---|
888 | } |
---|
889 | |
---|
890 | int |
---|
891 | pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user) |
---|
892 | { |
---|
893 | register int n; |
---|
894 | |
---|
895 | for (;;) { |
---|
896 | if (p->rfile != NULL) { |
---|
897 | /* |
---|
898 | * 0 means EOF, so don't loop if we get 0. |
---|
899 | */ |
---|
900 | n = pcap_offline_read(p, cnt, callback, user); |
---|
901 | } else { |
---|
902 | /* |
---|
903 | * XXX keep reading until we get something |
---|
904 | * (or an error occurs) |
---|
905 | */ |
---|
906 | do { |
---|
907 | n = p->read_op(p, cnt, callback, user); |
---|
908 | } while (n == 0); |
---|
909 | } |
---|
910 | if (n <= 0) |
---|
911 | return (n); |
---|
912 | if (!PACKET_COUNT_IS_UNLIMITED(cnt)) { |
---|
913 | cnt -= n; |
---|
914 | if (cnt <= 0) |
---|
915 | return (0); |
---|
916 | } |
---|
917 | } |
---|
918 | } |
---|
919 | |
---|
920 | /* |
---|
921 | * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate. |
---|
922 | */ |
---|
923 | void |
---|
924 | pcap_breakloop(pcap_t *p) |
---|
925 | { |
---|
926 | p->break_loop = 1; |
---|
927 | } |
---|
928 | |
---|
929 | int |
---|
930 | pcap_datalink(pcap_t *p) |
---|
931 | { |
---|
932 | if (!p->activated) |
---|
933 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
934 | return (p->linktype); |
---|
935 | } |
---|
936 | |
---|
937 | int |
---|
938 | pcap_datalink_ext(pcap_t *p) |
---|
939 | { |
---|
940 | if (!p->activated) |
---|
941 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
942 | return (p->linktype_ext); |
---|
943 | } |
---|
944 | |
---|
945 | int |
---|
946 | pcap_list_datalinks(pcap_t *p, int **dlt_buffer) |
---|
947 | { |
---|
948 | if (!p->activated) |
---|
949 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
950 | if (p->dlt_count == 0) { |
---|
951 | /* |
---|
952 | * We couldn't fetch the list of DLTs, which means |
---|
953 | * this platform doesn't support changing the |
---|
954 | * DLT for an interface. Return a list of DLTs |
---|
955 | * containing only the DLT this device supports. |
---|
956 | */ |
---|
957 | *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer)); |
---|
958 | if (*dlt_buffer == NULL) { |
---|
959 | (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), |
---|
960 | "malloc: %s", pcap_strerror(errno)); |
---|
961 | return (PCAP_ERROR); |
---|
962 | } |
---|
963 | **dlt_buffer = p->linktype; |
---|
964 | return (1); |
---|
965 | } else { |
---|
966 | *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count); |
---|
967 | if (*dlt_buffer == NULL) { |
---|
968 | (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), |
---|
969 | "malloc: %s", pcap_strerror(errno)); |
---|
970 | return (PCAP_ERROR); |
---|
971 | } |
---|
972 | (void)memcpy(*dlt_buffer, p->dlt_list, |
---|
973 | sizeof(**dlt_buffer) * p->dlt_count); |
---|
974 | return (p->dlt_count); |
---|
975 | } |
---|
976 | } |
---|
977 | |
---|
978 | /* |
---|
979 | * In Windows, you might have a library built with one version of the |
---|
980 | * C runtime library and an application built with another version of |
---|
981 | * the C runtime library, which means that the library might use one |
---|
982 | * version of malloc() and free() and the application might use another |
---|
983 | * version of malloc() and free(). If so, that means something |
---|
984 | * allocated by the library cannot be freed by the application, so we |
---|
985 | * need to have a pcap_free_datalinks() routine to free up the list |
---|
986 | * allocated by pcap_list_datalinks(), even though it's just a wrapper |
---|
987 | * around free(). |
---|
988 | */ |
---|
989 | void |
---|
990 | pcap_free_datalinks(int *dlt_list) |
---|
991 | { |
---|
992 | free(dlt_list); |
---|
993 | } |
---|
994 | |
---|
995 | int |
---|
996 | pcap_set_datalink(pcap_t *p, int dlt) |
---|
997 | { |
---|
998 | int i; |
---|
999 | const char *dlt_name; |
---|
1000 | |
---|
1001 | if (dlt < 0) |
---|
1002 | goto unsupported; |
---|
1003 | |
---|
1004 | if (p->dlt_count == 0 || p->set_datalink_op == NULL) { |
---|
1005 | /* |
---|
1006 | * We couldn't fetch the list of DLTs, or we don't |
---|
1007 | * have a "set datalink" operation, which means |
---|
1008 | * this platform doesn't support changing the |
---|
1009 | * DLT for an interface. Check whether the new |
---|
1010 | * DLT is the one this interface supports. |
---|
1011 | */ |
---|
1012 | if (p->linktype != dlt) |
---|
1013 | goto unsupported; |
---|
1014 | |
---|
1015 | /* |
---|
1016 | * It is, so there's nothing we need to do here. |
---|
1017 | */ |
---|
1018 | return (0); |
---|
1019 | } |
---|
1020 | for (i = 0; i < p->dlt_count; i++) |
---|
1021 | if (p->dlt_list[i] == (u_int)dlt) |
---|
1022 | break; |
---|
1023 | if (i >= p->dlt_count) |
---|
1024 | goto unsupported; |
---|
1025 | if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB && |
---|
1026 | dlt == DLT_DOCSIS) { |
---|
1027 | /* |
---|
1028 | * This is presumably an Ethernet device, as the first |
---|
1029 | * link-layer type it offers is DLT_EN10MB, and the only |
---|
1030 | * other type it offers is DLT_DOCSIS. That means that |
---|
1031 | * we can't tell the driver to supply DOCSIS link-layer |
---|
1032 | * headers - we're just pretending that's what we're |
---|
1033 | * getting, as, presumably, we're capturing on a dedicated |
---|
1034 | * link to a Cisco Cable Modem Termination System, and |
---|
1035 | * it's putting raw DOCSIS frames on the wire inside low-level |
---|
1036 | * Ethernet framing. |
---|
1037 | */ |
---|
1038 | p->linktype = dlt; |
---|
1039 | return (0); |
---|
1040 | } |
---|
1041 | if (p->set_datalink_op(p, dlt) == -1) |
---|
1042 | return (-1); |
---|
1043 | p->linktype = dlt; |
---|
1044 | return (0); |
---|
1045 | |
---|
1046 | unsupported: |
---|
1047 | dlt_name = pcap_datalink_val_to_name(dlt); |
---|
1048 | if (dlt_name != NULL) { |
---|
1049 | (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), |
---|
1050 | "%s is not one of the DLTs supported by this device", |
---|
1051 | dlt_name); |
---|
1052 | } else { |
---|
1053 | (void) pcap_snprintf(p->errbuf, sizeof(p->errbuf), |
---|
1054 | "DLT %d is not one of the DLTs supported by this device", |
---|
1055 | dlt); |
---|
1056 | } |
---|
1057 | return (-1); |
---|
1058 | } |
---|
1059 | |
---|
1060 | /* |
---|
1061 | * This array is designed for mapping upper and lower case letter |
---|
1062 | * together for a case independent comparison. The mappings are |
---|
1063 | * based upon ascii character sequences. |
---|
1064 | */ |
---|
1065 | static const u_char charmap[] = { |
---|
1066 | (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003', |
---|
1067 | (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007', |
---|
1068 | (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013', |
---|
1069 | (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017', |
---|
1070 | (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023', |
---|
1071 | (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027', |
---|
1072 | (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033', |
---|
1073 | (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037', |
---|
1074 | (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043', |
---|
1075 | (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047', |
---|
1076 | (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053', |
---|
1077 | (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057', |
---|
1078 | (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063', |
---|
1079 | (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067', |
---|
1080 | (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073', |
---|
1081 | (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077', |
---|
1082 | (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143', |
---|
1083 | (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', |
---|
1084 | (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', |
---|
1085 | (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', |
---|
1086 | (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', |
---|
1087 | (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', |
---|
1088 | (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133', |
---|
1089 | (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137', |
---|
1090 | (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143', |
---|
1091 | (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147', |
---|
1092 | (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153', |
---|
1093 | (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157', |
---|
1094 | (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163', |
---|
1095 | (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167', |
---|
1096 | (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173', |
---|
1097 | (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177', |
---|
1098 | (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203', |
---|
1099 | (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207', |
---|
1100 | (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213', |
---|
1101 | (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217', |
---|
1102 | (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223', |
---|
1103 | (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227', |
---|
1104 | (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233', |
---|
1105 | (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237', |
---|
1106 | (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243', |
---|
1107 | (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247', |
---|
1108 | (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253', |
---|
1109 | (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257', |
---|
1110 | (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263', |
---|
1111 | (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267', |
---|
1112 | (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273', |
---|
1113 | (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277', |
---|
1114 | (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343', |
---|
1115 | (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', |
---|
1116 | (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', |
---|
1117 | (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', |
---|
1118 | (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', |
---|
1119 | (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', |
---|
1120 | (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333', |
---|
1121 | (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337', |
---|
1122 | (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343', |
---|
1123 | (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347', |
---|
1124 | (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353', |
---|
1125 | (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357', |
---|
1126 | (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363', |
---|
1127 | (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367', |
---|
1128 | (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373', |
---|
1129 | (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377', |
---|
1130 | }; |
---|
1131 | |
---|
1132 | int |
---|
1133 | pcap_strcasecmp(const char *s1, const char *s2) |
---|
1134 | { |
---|
1135 | register const u_char *cm = charmap, |
---|
1136 | *us1 = (const u_char *)s1, |
---|
1137 | *us2 = (const u_char *)s2; |
---|
1138 | |
---|
1139 | while (cm[*us1] == cm[*us2++]) |
---|
1140 | if (*us1++ == '\0') |
---|
1141 | return(0); |
---|
1142 | return (cm[*us1] - cm[*--us2]); |
---|
1143 | } |
---|
1144 | |
---|
1145 | struct dlt_choice { |
---|
1146 | const char *name; |
---|
1147 | const char *description; |
---|
1148 | int dlt; |
---|
1149 | }; |
---|
1150 | |
---|
1151 | #define DLT_CHOICE(code, description) { #code, description, DLT_ ## code } |
---|
1152 | #define DLT_CHOICE_SENTINEL { NULL, NULL, 0 } |
---|
1153 | |
---|
1154 | static struct dlt_choice dlt_choices[] = { |
---|
1155 | DLT_CHOICE(NULL, "BSD loopback"), |
---|
1156 | DLT_CHOICE(EN10MB, "Ethernet"), |
---|
1157 | DLT_CHOICE(IEEE802, "Token ring"), |
---|
1158 | DLT_CHOICE(ARCNET, "BSD ARCNET"), |
---|
1159 | DLT_CHOICE(SLIP, "SLIP"), |
---|
1160 | DLT_CHOICE(PPP, "PPP"), |
---|
1161 | DLT_CHOICE(FDDI, "FDDI"), |
---|
1162 | DLT_CHOICE(ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"), |
---|
1163 | DLT_CHOICE(RAW, "Raw IP"), |
---|
1164 | DLT_CHOICE(SLIP_BSDOS, "BSD/OS SLIP"), |
---|
1165 | DLT_CHOICE(PPP_BSDOS, "BSD/OS PPP"), |
---|
1166 | DLT_CHOICE(ATM_CLIP, "Linux Classical IP-over-ATM"), |
---|
1167 | DLT_CHOICE(PPP_SERIAL, "PPP over serial"), |
---|
1168 | DLT_CHOICE(PPP_ETHER, "PPPoE"), |
---|
1169 | DLT_CHOICE(SYMANTEC_FIREWALL, "Symantec Firewall"), |
---|
1170 | DLT_CHOICE(C_HDLC, "Cisco HDLC"), |
---|
1171 | DLT_CHOICE(IEEE802_11, "802.11"), |
---|
1172 | DLT_CHOICE(FRELAY, "Frame Relay"), |
---|
1173 | DLT_CHOICE(LOOP, "OpenBSD loopback"), |
---|
1174 | DLT_CHOICE(ENC, "OpenBSD encapsulated IP"), |
---|
1175 | DLT_CHOICE(LINUX_SLL, "Linux cooked"), |
---|
1176 | DLT_CHOICE(LTALK, "Localtalk"), |
---|
1177 | DLT_CHOICE(PFLOG, "OpenBSD pflog file"), |
---|
1178 | DLT_CHOICE(PFSYNC, "Packet filter state syncing"), |
---|
1179 | DLT_CHOICE(PRISM_HEADER, "802.11 plus Prism header"), |
---|
1180 | DLT_CHOICE(IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"), |
---|
1181 | DLT_CHOICE(SUNATM, "Sun raw ATM"), |
---|
1182 | DLT_CHOICE(IEEE802_11_RADIO, "802.11 plus radiotap header"), |
---|
1183 | DLT_CHOICE(ARCNET_LINUX, "Linux ARCNET"), |
---|
1184 | DLT_CHOICE(JUNIPER_MLPPP, "Juniper Multi-Link PPP"), |
---|
1185 | DLT_CHOICE(JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"), |
---|
1186 | DLT_CHOICE(JUNIPER_ES, "Juniper Encryption Services PIC"), |
---|
1187 | DLT_CHOICE(JUNIPER_GGSN, "Juniper GGSN PIC"), |
---|
1188 | DLT_CHOICE(JUNIPER_MFR, "Juniper FRF.16 Frame Relay"), |
---|
1189 | DLT_CHOICE(JUNIPER_ATM2, "Juniper ATM2 PIC"), |
---|
1190 | DLT_CHOICE(JUNIPER_SERVICES, "Juniper Advanced Services PIC"), |
---|
1191 | DLT_CHOICE(JUNIPER_ATM1, "Juniper ATM1 PIC"), |
---|
1192 | DLT_CHOICE(APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"), |
---|
1193 | DLT_CHOICE(MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"), |
---|
1194 | DLT_CHOICE(MTP2, "SS7 MTP2"), |
---|
1195 | DLT_CHOICE(MTP3, "SS7 MTP3"), |
---|
1196 | DLT_CHOICE(SCCP, "SS7 SCCP"), |
---|
1197 | DLT_CHOICE(DOCSIS, "DOCSIS"), |
---|
1198 | DLT_CHOICE(LINUX_IRDA, "Linux IrDA"), |
---|
1199 | DLT_CHOICE(IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"), |
---|
1200 | DLT_CHOICE(JUNIPER_MONITOR, "Juniper Passive Monitor PIC"), |
---|
1201 | DLT_CHOICE(BACNET_MS_TP, "BACnet MS/TP"), |
---|
1202 | DLT_CHOICE(PPP_PPPD, "PPP for pppd, with direction flag"), |
---|
1203 | DLT_CHOICE(JUNIPER_PPPOE, "Juniper PPPoE"), |
---|
1204 | DLT_CHOICE(JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"), |
---|
1205 | DLT_CHOICE(GPRS_LLC, "GPRS LLC"), |
---|
1206 | DLT_CHOICE(GPF_T, "GPF-T"), |
---|
1207 | DLT_CHOICE(GPF_F, "GPF-F"), |
---|
1208 | DLT_CHOICE(JUNIPER_PIC_PEER, "Juniper PIC Peer"), |
---|
1209 | DLT_CHOICE(ERF_ETH, "Ethernet with Endace ERF header"), |
---|
1210 | DLT_CHOICE(ERF_POS, "Packet-over-SONET with Endace ERF header"), |
---|
1211 | DLT_CHOICE(LINUX_LAPD, "Linux vISDN LAPD"), |
---|
1212 | DLT_CHOICE(JUNIPER_ETHER, "Juniper Ethernet"), |
---|
1213 | DLT_CHOICE(JUNIPER_PPP, "Juniper PPP"), |
---|
1214 | DLT_CHOICE(JUNIPER_FRELAY, "Juniper Frame Relay"), |
---|
1215 | DLT_CHOICE(JUNIPER_CHDLC, "Juniper C-HDLC"), |
---|
1216 | DLT_CHOICE(MFR, "FRF.16 Frame Relay"), |
---|
1217 | DLT_CHOICE(JUNIPER_VP, "Juniper Voice PIC"), |
---|
1218 | DLT_CHOICE(A429, "Arinc 429"), |
---|
1219 | DLT_CHOICE(A653_ICM, "Arinc 653 Interpartition Communication"), |
---|
1220 | DLT_CHOICE(USB_FREEBSD, "USB with FreeBSD header"), |
---|
1221 | DLT_CHOICE(BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"), |
---|
1222 | DLT_CHOICE(IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"), |
---|
1223 | DLT_CHOICE(USB_LINUX, "USB with Linux header"), |
---|
1224 | DLT_CHOICE(CAN20B, "Controller Area Network (CAN) v. 2.0B"), |
---|
1225 | DLT_CHOICE(IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"), |
---|
1226 | DLT_CHOICE(PPI, "Per-Packet Information"), |
---|
1227 | DLT_CHOICE(IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"), |
---|
1228 | DLT_CHOICE(JUNIPER_ISM, "Juniper Integrated Service Module"), |
---|
1229 | DLT_CHOICE(IEEE802_15_4, "IEEE 802.15.4 with FCS"), |
---|
1230 | DLT_CHOICE(SITA, "SITA pseudo-header"), |
---|
1231 | DLT_CHOICE(ERF, "Endace ERF header"), |
---|
1232 | DLT_CHOICE(RAIF1, "Ethernet with u10 Networks pseudo-header"), |
---|
1233 | DLT_CHOICE(IPMB, "IPMB"), |
---|
1234 | DLT_CHOICE(JUNIPER_ST, "Juniper Secure Tunnel"), |
---|
1235 | DLT_CHOICE(BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"), |
---|
1236 | DLT_CHOICE(AX25_KISS, "AX.25 with KISS header"), |
---|
1237 | DLT_CHOICE(IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"), |
---|
1238 | DLT_CHOICE(MPLS, "MPLS with label as link-layer header"), |
---|
1239 | DLT_CHOICE(LINUX_EVDEV, "Linux evdev events"), |
---|
1240 | DLT_CHOICE(USB_LINUX_MMAPPED, "USB with padded Linux header"), |
---|
1241 | DLT_CHOICE(DECT, "DECT"), |
---|
1242 | DLT_CHOICE(AOS, "AOS Space Data Link protocol"), |
---|
1243 | DLT_CHOICE(WIHART, "Wireless HART"), |
---|
1244 | DLT_CHOICE(FC_2, "Fibre Channel FC-2"), |
---|
1245 | DLT_CHOICE(FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"), |
---|
1246 | DLT_CHOICE(IPNET, "Solaris ipnet"), |
---|
1247 | DLT_CHOICE(CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"), |
---|
1248 | DLT_CHOICE(IPV4, "Raw IPv4"), |
---|
1249 | DLT_CHOICE(IPV6, "Raw IPv6"), |
---|
1250 | DLT_CHOICE(IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"), |
---|
1251 | DLT_CHOICE(DBUS, "D-Bus"), |
---|
1252 | DLT_CHOICE(JUNIPER_VS, "Juniper Virtual Server"), |
---|
1253 | DLT_CHOICE(JUNIPER_SRX_E2E, "Juniper SRX E2E"), |
---|
1254 | DLT_CHOICE(JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"), |
---|
1255 | DLT_CHOICE(DVB_CI, "DVB-CI"), |
---|
1256 | DLT_CHOICE(MUX27010, "MUX27010"), |
---|
1257 | DLT_CHOICE(STANAG_5066_D_PDU, "STANAG 5066 D_PDUs"), |
---|
1258 | DLT_CHOICE(JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"), |
---|
1259 | DLT_CHOICE(NFLOG, "Linux netfilter log messages"), |
---|
1260 | DLT_CHOICE(NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"), |
---|
1261 | DLT_CHOICE(NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"), |
---|
1262 | DLT_CHOICE(IPOIB, "RFC 4391 IP-over-Infiniband"), |
---|
1263 | DLT_CHOICE(MPEG_2_TS, "MPEG-2 transport stream"), |
---|
1264 | DLT_CHOICE(NG40, "ng40 protocol tester Iub/Iur"), |
---|
1265 | DLT_CHOICE(NFC_LLCP, "NFC LLCP PDUs with pseudo-header"), |
---|
1266 | DLT_CHOICE(INFINIBAND, "InfiniBand"), |
---|
1267 | DLT_CHOICE(SCTP, "SCTP"), |
---|
1268 | DLT_CHOICE(USBPCAP, "USB with USBPcap header"), |
---|
1269 | DLT_CHOICE(RTAC_SERIAL, "Schweitzer Engineering Laboratories RTAC packets"), |
---|
1270 | DLT_CHOICE(BLUETOOTH_LE_LL, "Bluetooth Low Energy air interface"), |
---|
1271 | DLT_CHOICE(NETLINK, "Linux netlink"), |
---|
1272 | DLT_CHOICE(BLUETOOTH_LINUX_MONITOR, "Bluetooth Linux Monitor"), |
---|
1273 | DLT_CHOICE(BLUETOOTH_BREDR_BB, "Bluetooth Basic Rate/Enhanced Data Rate baseband packets"), |
---|
1274 | DLT_CHOICE(BLUETOOTH_LE_LL_WITH_PHDR, "Bluetooth Low Energy air interface with pseudo-header"), |
---|
1275 | DLT_CHOICE(PROFIBUS_DL, "PROFIBUS data link layer"), |
---|
1276 | DLT_CHOICE(PKTAP, "Apple DLT_PKTAP"), |
---|
1277 | DLT_CHOICE(EPON, "Ethernet with 802.3 Clause 65 EPON preamble"), |
---|
1278 | DLT_CHOICE(IPMI_HPM_2, "IPMI trace packets"), |
---|
1279 | DLT_CHOICE(ZWAVE_R1_R2, "Z-Wave RF profile R1 and R2 packets"), |
---|
1280 | DLT_CHOICE(ZWAVE_R3, "Z-Wave RF profile R3 packets"), |
---|
1281 | DLT_CHOICE(WATTSTOPPER_DLM, "WattStopper Digital Lighting Management (DLM) and Legrand Nitoo Open protocol"), |
---|
1282 | DLT_CHOICE(ISO_14443, "ISO 14443 messages"), |
---|
1283 | DLT_CHOICE(RDS, "IEC 62106 Radio Data System groups"), |
---|
1284 | DLT_CHOICE_SENTINEL |
---|
1285 | }; |
---|
1286 | |
---|
1287 | int |
---|
1288 | pcap_datalink_name_to_val(const char *name) |
---|
1289 | { |
---|
1290 | int i; |
---|
1291 | |
---|
1292 | for (i = 0; dlt_choices[i].name != NULL; i++) { |
---|
1293 | if (pcap_strcasecmp(dlt_choices[i].name, name) == 0) |
---|
1294 | return (dlt_choices[i].dlt); |
---|
1295 | } |
---|
1296 | return (-1); |
---|
1297 | } |
---|
1298 | |
---|
1299 | const char * |
---|
1300 | pcap_datalink_val_to_name(int dlt) |
---|
1301 | { |
---|
1302 | int i; |
---|
1303 | |
---|
1304 | for (i = 0; dlt_choices[i].name != NULL; i++) { |
---|
1305 | if (dlt_choices[i].dlt == dlt) |
---|
1306 | return (dlt_choices[i].name); |
---|
1307 | } |
---|
1308 | return (NULL); |
---|
1309 | } |
---|
1310 | |
---|
1311 | const char * |
---|
1312 | pcap_datalink_val_to_description(int dlt) |
---|
1313 | { |
---|
1314 | int i; |
---|
1315 | |
---|
1316 | for (i = 0; dlt_choices[i].name != NULL; i++) { |
---|
1317 | if (dlt_choices[i].dlt == dlt) |
---|
1318 | return (dlt_choices[i].description); |
---|
1319 | } |
---|
1320 | return (NULL); |
---|
1321 | } |
---|
1322 | |
---|
1323 | struct tstamp_type_choice { |
---|
1324 | const char *name; |
---|
1325 | const char *description; |
---|
1326 | int type; |
---|
1327 | }; |
---|
1328 | |
---|
1329 | static struct tstamp_type_choice tstamp_type_choices[] = { |
---|
1330 | { "host", "Host", PCAP_TSTAMP_HOST }, |
---|
1331 | { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC }, |
---|
1332 | { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC }, |
---|
1333 | { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER }, |
---|
1334 | { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED }, |
---|
1335 | { NULL, NULL, 0 } |
---|
1336 | }; |
---|
1337 | |
---|
1338 | int |
---|
1339 | pcap_tstamp_type_name_to_val(const char *name) |
---|
1340 | { |
---|
1341 | int i; |
---|
1342 | |
---|
1343 | for (i = 0; tstamp_type_choices[i].name != NULL; i++) { |
---|
1344 | if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0) |
---|
1345 | return (tstamp_type_choices[i].type); |
---|
1346 | } |
---|
1347 | return (PCAP_ERROR); |
---|
1348 | } |
---|
1349 | |
---|
1350 | const char * |
---|
1351 | pcap_tstamp_type_val_to_name(int tstamp_type) |
---|
1352 | { |
---|
1353 | int i; |
---|
1354 | |
---|
1355 | for (i = 0; tstamp_type_choices[i].name != NULL; i++) { |
---|
1356 | if (tstamp_type_choices[i].type == tstamp_type) |
---|
1357 | return (tstamp_type_choices[i].name); |
---|
1358 | } |
---|
1359 | return (NULL); |
---|
1360 | } |
---|
1361 | |
---|
1362 | const char * |
---|
1363 | pcap_tstamp_type_val_to_description(int tstamp_type) |
---|
1364 | { |
---|
1365 | int i; |
---|
1366 | |
---|
1367 | for (i = 0; tstamp_type_choices[i].name != NULL; i++) { |
---|
1368 | if (tstamp_type_choices[i].type == tstamp_type) |
---|
1369 | return (tstamp_type_choices[i].description); |
---|
1370 | } |
---|
1371 | return (NULL); |
---|
1372 | } |
---|
1373 | |
---|
1374 | int |
---|
1375 | pcap_snapshot(pcap_t *p) |
---|
1376 | { |
---|
1377 | if (!p->activated) |
---|
1378 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
1379 | return (p->snapshot); |
---|
1380 | } |
---|
1381 | |
---|
1382 | int |
---|
1383 | pcap_is_swapped(pcap_t *p) |
---|
1384 | { |
---|
1385 | if (!p->activated) |
---|
1386 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
1387 | return (p->swapped); |
---|
1388 | } |
---|
1389 | |
---|
1390 | int |
---|
1391 | pcap_major_version(pcap_t *p) |
---|
1392 | { |
---|
1393 | if (!p->activated) |
---|
1394 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
1395 | return (p->version_major); |
---|
1396 | } |
---|
1397 | |
---|
1398 | int |
---|
1399 | pcap_minor_version(pcap_t *p) |
---|
1400 | { |
---|
1401 | if (!p->activated) |
---|
1402 | return (PCAP_ERROR_NOT_ACTIVATED); |
---|
1403 | return (p->version_minor); |
---|
1404 | } |
---|
1405 | |
---|
1406 | FILE * |
---|
1407 | pcap_file(pcap_t *p) |
---|
1408 | { |
---|
1409 | return (p->rfile); |
---|
1410 | } |
---|
1411 | |
---|
1412 | int |
---|
1413 | pcap_fileno(pcap_t *p) |
---|
1414 | { |
---|
1415 | #ifndef _WIN32 |
---|
1416 | return (p->fd); |
---|
1417 | #else |
---|
1418 | if (p->adapter != NULL) |
---|
1419 | return ((int)(DWORD)p->adapter->hFile); |
---|
1420 | else |
---|
1421 | return (PCAP_ERROR); |
---|
1422 | #endif |
---|
1423 | } |
---|
1424 | |
---|
1425 | #if !defined(_WIN32) && !defined(MSDOS) |
---|
1426 | int |
---|
1427 | pcap_get_selectable_fd(pcap_t *p) |
---|
1428 | { |
---|
1429 | return (p->selectable_fd); |
---|
1430 | } |
---|
1431 | #endif |
---|
1432 | |
---|
1433 | void |
---|
1434 | pcap_perror(pcap_t *p, const char *prefix) |
---|
1435 | { |
---|
1436 | fprintf(stderr, "%s: %s\n", prefix, p->errbuf); |
---|
1437 | } |
---|
1438 | |
---|
1439 | char * |
---|
1440 | pcap_geterr(pcap_t *p) |
---|
1441 | { |
---|
1442 | return (p->errbuf); |
---|
1443 | } |
---|
1444 | |
---|
1445 | int |
---|
1446 | pcap_getnonblock(pcap_t *p, char *errbuf) |
---|
1447 | { |
---|
1448 | int ret; |
---|
1449 | |
---|
1450 | ret = p->getnonblock_op(p, errbuf); |
---|
1451 | if (ret == -1) { |
---|
1452 | /* |
---|
1453 | * In case somebody depended on the bug wherein |
---|
1454 | * the error message was put into p->errbuf |
---|
1455 | * by pcap_getnonblock_fd(). |
---|
1456 | */ |
---|
1457 | strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); |
---|
1458 | } |
---|
1459 | return (ret); |
---|
1460 | } |
---|
1461 | |
---|
1462 | /* |
---|
1463 | * Get the current non-blocking mode setting, under the assumption that |
---|
1464 | * it's just the standard POSIX non-blocking flag. |
---|
1465 | */ |
---|
1466 | #if !defined(_WIN32) && !defined(MSDOS) |
---|
1467 | int |
---|
1468 | pcap_getnonblock_fd(pcap_t *p, char *errbuf) |
---|
1469 | { |
---|
1470 | int fdflags; |
---|
1471 | |
---|
1472 | fdflags = fcntl(p->fd, F_GETFL, 0); |
---|
1473 | if (fdflags == -1) { |
---|
1474 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", |
---|
1475 | pcap_strerror(errno)); |
---|
1476 | return (-1); |
---|
1477 | } |
---|
1478 | if (fdflags & O_NONBLOCK) |
---|
1479 | return (1); |
---|
1480 | else |
---|
1481 | return (0); |
---|
1482 | } |
---|
1483 | #endif |
---|
1484 | |
---|
1485 | int |
---|
1486 | pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf) |
---|
1487 | { |
---|
1488 | int ret; |
---|
1489 | |
---|
1490 | ret = p->setnonblock_op(p, nonblock, errbuf); |
---|
1491 | if (ret == -1) { |
---|
1492 | /* |
---|
1493 | * In case somebody depended on the bug wherein |
---|
1494 | * the error message was put into p->errbuf |
---|
1495 | * by pcap_setnonblock_fd(). |
---|
1496 | */ |
---|
1497 | strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE); |
---|
1498 | } |
---|
1499 | return (ret); |
---|
1500 | } |
---|
1501 | |
---|
1502 | #if !defined(_WIN32) && !defined(MSDOS) |
---|
1503 | /* |
---|
1504 | * Set non-blocking mode, under the assumption that it's just the |
---|
1505 | * standard POSIX non-blocking flag. (This can be called by the |
---|
1506 | * per-platform non-blocking-mode routine if that routine also |
---|
1507 | * needs to do some additional work.) |
---|
1508 | */ |
---|
1509 | int |
---|
1510 | pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf) |
---|
1511 | { |
---|
1512 | int fdflags; |
---|
1513 | |
---|
1514 | fdflags = fcntl(p->fd, F_GETFL, 0); |
---|
1515 | if (fdflags == -1) { |
---|
1516 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s", |
---|
1517 | pcap_strerror(errno)); |
---|
1518 | return (-1); |
---|
1519 | } |
---|
1520 | if (nonblock) |
---|
1521 | fdflags |= O_NONBLOCK; |
---|
1522 | else |
---|
1523 | fdflags &= ~O_NONBLOCK; |
---|
1524 | if (fcntl(p->fd, F_SETFL, fdflags) == -1) { |
---|
1525 | pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s", |
---|
1526 | pcap_strerror(errno)); |
---|
1527 | return (-1); |
---|
1528 | } |
---|
1529 | return (0); |
---|
1530 | } |
---|
1531 | #endif |
---|
1532 | |
---|
1533 | #ifdef _WIN32 |
---|
1534 | /* |
---|
1535 | * Generate a string for a Win32-specific error (i.e. an error generated when |
---|
1536 | * calling a Win32 API). |
---|
1537 | * For errors occurred during standard C calls, we still use pcap_strerror() |
---|
1538 | */ |
---|
1539 | void |
---|
1540 | pcap_win32_err_to_str(DWORD error, char *errbuf) |
---|
1541 | { |
---|
1542 | size_t errlen; |
---|
1543 | char *p; |
---|
1544 | |
---|
1545 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf, |
---|
1546 | PCAP_ERRBUF_SIZE, NULL); |
---|
1547 | |
---|
1548 | /* |
---|
1549 | * "FormatMessage()" "helpfully" sticks CR/LF at the end of the |
---|
1550 | * message. Get rid of it. |
---|
1551 | */ |
---|
1552 | errlen = strlen(errbuf); |
---|
1553 | if (errlen >= 2) { |
---|
1554 | errbuf[errlen - 1] = '\0'; |
---|
1555 | errbuf[errlen - 2] = '\0'; |
---|
1556 | } |
---|
1557 | p = strchr(errbuf, '\0'); |
---|
1558 | pcap_snprintf (p, PCAP_ERRBUF_SIZE+1-(p-errbuf), " (%lu)", error); |
---|
1559 | } |
---|
1560 | #endif |
---|
1561 | |
---|
1562 | /* |
---|
1563 | * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values. |
---|
1564 | */ |
---|
1565 | const char * |
---|
1566 | pcap_statustostr(int errnum) |
---|
1567 | { |
---|
1568 | static char ebuf[15+10+1]; |
---|
1569 | |
---|
1570 | switch (errnum) { |
---|
1571 | |
---|
1572 | case PCAP_WARNING: |
---|
1573 | return("Generic warning"); |
---|
1574 | |
---|
1575 | case PCAP_WARNING_TSTAMP_TYPE_NOTSUP: |
---|
1576 | return ("That type of time stamp is not supported by that device"); |
---|
1577 | |
---|
1578 | case PCAP_WARNING_PROMISC_NOTSUP: |
---|
1579 | return ("That device doesn't support promiscuous mode"); |
---|
1580 | |
---|
1581 | case PCAP_ERROR: |
---|
1582 | return("Generic error"); |
---|
1583 | |
---|
1584 | case PCAP_ERROR_BREAK: |
---|
1585 | return("Loop terminated by pcap_breakloop"); |
---|
1586 | |
---|
1587 | case PCAP_ERROR_NOT_ACTIVATED: |
---|
1588 | return("The pcap_t has not been activated"); |
---|
1589 | |
---|
1590 | case PCAP_ERROR_ACTIVATED: |
---|
1591 | return ("The setting can't be changed after the pcap_t is activated"); |
---|
1592 | |
---|
1593 | case PCAP_ERROR_NO_SUCH_DEVICE: |
---|
1594 | return ("No such device exists"); |
---|
1595 | |
---|
1596 | case PCAP_ERROR_RFMON_NOTSUP: |
---|
1597 | return ("That device doesn't support monitor mode"); |
---|
1598 | |
---|
1599 | case PCAP_ERROR_NOT_RFMON: |
---|
1600 | return ("That operation is supported only in monitor mode"); |
---|
1601 | |
---|
1602 | case PCAP_ERROR_PERM_DENIED: |
---|
1603 | return ("You don't have permission to capture on that device"); |
---|
1604 | |
---|
1605 | case PCAP_ERROR_IFACE_NOT_UP: |
---|
1606 | return ("That device is not up"); |
---|
1607 | |
---|
1608 | case PCAP_ERROR_CANTSET_TSTAMP_TYPE: |
---|
1609 | return ("That device doesn't support setting the time stamp type"); |
---|
1610 | |
---|
1611 | case PCAP_ERROR_PROMISC_PERM_DENIED: |
---|
1612 | return ("You don't have permission to capture in promiscuous mode on that device"); |
---|
1613 | |
---|
1614 | case PCAP_ERROR_TSTAMP_PRECISION_NOTSUP: |
---|
1615 | return ("That device doesn't support that time stamp precision"); |
---|
1616 | } |
---|
1617 | (void)pcap_snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); |
---|
1618 | return(ebuf); |
---|
1619 | } |
---|
1620 | |
---|
1621 | /* |
---|
1622 | * Not all systems have strerror(). |
---|
1623 | */ |
---|
1624 | const char * |
---|
1625 | pcap_strerror(int errnum) |
---|
1626 | { |
---|
1627 | #ifdef HAVE_STRERROR |
---|
1628 | #ifdef _WIN32 |
---|
1629 | static char errbuf[PCAP_ERRBUF_SIZE]; |
---|
1630 | errno_t errno; |
---|
1631 | errno = strerror_s(errbuf, PCAP_ERRBUF_SIZE, errnum); |
---|
1632 | if (errno != 0) /* errno = 0 if successful */ |
---|
1633 | strlcpy(errbuf, "strerror_s() error", PCAP_ERRBUF_SIZE); |
---|
1634 | return (errbuf); |
---|
1635 | #else |
---|
1636 | return (strerror(errnum)); |
---|
1637 | #endif /* _WIN32 */ |
---|
1638 | #else |
---|
1639 | extern int sys_nerr; |
---|
1640 | extern const char *const sys_errlist[]; |
---|
1641 | static char errbuf[PCAP_ERRBUF_SIZE]; |
---|
1642 | |
---|
1643 | if ((unsigned int)errnum < sys_nerr) |
---|
1644 | return ((char *)sys_errlist[errnum]); |
---|
1645 | (void)pcap_snprintf(errbuf, sizeof errbuf, "Unknown error: %d", errnum); |
---|
1646 | return (errbuf); |
---|
1647 | #endif |
---|
1648 | } |
---|
1649 | |
---|
1650 | int |
---|
1651 | pcap_setfilter(pcap_t *p, struct bpf_program *fp) |
---|
1652 | { |
---|
1653 | return (p->setfilter_op(p, fp)); |
---|
1654 | } |
---|
1655 | |
---|
1656 | /* |
---|
1657 | * Set direction flag, which controls whether we accept only incoming |
---|
1658 | * packets, only outgoing packets, or both. |
---|
1659 | * Note that, depending on the platform, some or all direction arguments |
---|
1660 | * might not be supported. |
---|
1661 | */ |
---|
1662 | int |
---|
1663 | pcap_setdirection(pcap_t *p, pcap_direction_t d) |
---|
1664 | { |
---|
1665 | if (p->setdirection_op == NULL) { |
---|
1666 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1667 | "Setting direction is not implemented on this platform"); |
---|
1668 | return (-1); |
---|
1669 | } else |
---|
1670 | return (p->setdirection_op(p, d)); |
---|
1671 | } |
---|
1672 | |
---|
1673 | int |
---|
1674 | pcap_stats(pcap_t *p, struct pcap_stat *ps) |
---|
1675 | { |
---|
1676 | return (p->stats_op(p, ps)); |
---|
1677 | } |
---|
1678 | |
---|
1679 | static int |
---|
1680 | pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_) |
---|
1681 | { |
---|
1682 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1683 | "Statistics aren't available from a pcap_open_dead pcap_t"); |
---|
1684 | return (-1); |
---|
1685 | } |
---|
1686 | |
---|
1687 | #ifdef _WIN32 |
---|
1688 | struct pcap_stat * |
---|
1689 | pcap_stats_ex(pcap_t *p, int *pcap_stat_size) |
---|
1690 | { |
---|
1691 | return (p->stats_ex_op(p, pcap_stat_size)); |
---|
1692 | } |
---|
1693 | |
---|
1694 | int |
---|
1695 | pcap_setbuff(pcap_t *p, int dim) |
---|
1696 | { |
---|
1697 | return (p->setbuff_op(p, dim)); |
---|
1698 | } |
---|
1699 | |
---|
1700 | static int |
---|
1701 | pcap_setbuff_dead(pcap_t *p, int dim) |
---|
1702 | { |
---|
1703 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1704 | "The kernel buffer size cannot be set on a pcap_open_dead pcap_t"); |
---|
1705 | return (-1); |
---|
1706 | } |
---|
1707 | |
---|
1708 | int |
---|
1709 | pcap_setmode(pcap_t *p, int mode) |
---|
1710 | { |
---|
1711 | return (p->setmode_op(p, mode)); |
---|
1712 | } |
---|
1713 | |
---|
1714 | static int |
---|
1715 | pcap_setmode_dead(pcap_t *p, int mode) |
---|
1716 | { |
---|
1717 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1718 | "impossible to set mode on a pcap_open_dead pcap_t"); |
---|
1719 | return (-1); |
---|
1720 | } |
---|
1721 | |
---|
1722 | int |
---|
1723 | pcap_setmintocopy(pcap_t *p, int size) |
---|
1724 | { |
---|
1725 | return (p->setmintocopy_op(p, size)); |
---|
1726 | } |
---|
1727 | |
---|
1728 | static int |
---|
1729 | pcap_setmintocopy_dead(pcap_t *p, int size) |
---|
1730 | { |
---|
1731 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1732 | "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t"); |
---|
1733 | return (-1); |
---|
1734 | } |
---|
1735 | |
---|
1736 | HANDLE |
---|
1737 | pcap_getevent(pcap_t *p) |
---|
1738 | { |
---|
1739 | return (p->getevent_op(p)); |
---|
1740 | } |
---|
1741 | |
---|
1742 | static HANDLE |
---|
1743 | pcap_getevent_dead(pcap_t *p) |
---|
1744 | { |
---|
1745 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1746 | "A pcap_open_dead pcap_t has no event handle"); |
---|
1747 | return (INVALID_HANDLE_VALUE); |
---|
1748 | } |
---|
1749 | |
---|
1750 | int |
---|
1751 | pcap_oid_get_request(pcap_t *p, bpf_u_int32 oid, void *data, size_t *lenp) |
---|
1752 | { |
---|
1753 | return (p->oid_get_request_op(p, oid, data, lenp)); |
---|
1754 | } |
---|
1755 | |
---|
1756 | static int |
---|
1757 | pcap_oid_get_request_dead(pcap_t *p, bpf_u_int32 oid _U_, void *data _U_, |
---|
1758 | size_t *lenp _U_) |
---|
1759 | { |
---|
1760 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1761 | "An OID get request cannot be performed on a pcap_open_dead pcap_t"); |
---|
1762 | return (PCAP_ERROR); |
---|
1763 | } |
---|
1764 | |
---|
1765 | int |
---|
1766 | pcap_oid_set_request(pcap_t *p, bpf_u_int32 oid, const void *data, size_t *lenp) |
---|
1767 | { |
---|
1768 | return (p->oid_set_request_op(p, oid, data, lenp)); |
---|
1769 | } |
---|
1770 | |
---|
1771 | static int |
---|
1772 | pcap_oid_set_request_dead(pcap_t *p, bpf_u_int32 oid _U_, const void *data _U_, |
---|
1773 | size_t *lenp _U_) |
---|
1774 | { |
---|
1775 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1776 | "An OID set request cannot be performed on a pcap_open_dead pcap_t"); |
---|
1777 | return (PCAP_ERROR); |
---|
1778 | } |
---|
1779 | |
---|
1780 | pcap_send_queue * |
---|
1781 | pcap_sendqueue_alloc(u_int memsize) |
---|
1782 | { |
---|
1783 | pcap_send_queue *tqueue; |
---|
1784 | |
---|
1785 | /* Allocate the queue */ |
---|
1786 | tqueue = (pcap_send_queue *)malloc(sizeof(pcap_send_queue)); |
---|
1787 | if (tqueue == NULL){ |
---|
1788 | return (NULL); |
---|
1789 | } |
---|
1790 | |
---|
1791 | /* Allocate the buffer */ |
---|
1792 | tqueue->buffer = (char *)malloc(memsize); |
---|
1793 | if (tqueue->buffer == NULL) { |
---|
1794 | free(tqueue); |
---|
1795 | return (NULL); |
---|
1796 | } |
---|
1797 | |
---|
1798 | tqueue->maxlen = memsize; |
---|
1799 | tqueue->len = 0; |
---|
1800 | |
---|
1801 | return (tqueue); |
---|
1802 | } |
---|
1803 | |
---|
1804 | void |
---|
1805 | pcap_sendqueue_destroy(pcap_send_queue *queue) |
---|
1806 | { |
---|
1807 | free(queue->buffer); |
---|
1808 | free(queue); |
---|
1809 | } |
---|
1810 | |
---|
1811 | int |
---|
1812 | pcap_sendqueue_queue(pcap_send_queue *queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) |
---|
1813 | { |
---|
1814 | if (queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){ |
---|
1815 | return (-1); |
---|
1816 | } |
---|
1817 | |
---|
1818 | /* Copy the pcap_pkthdr header*/ |
---|
1819 | memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr)); |
---|
1820 | queue->len += sizeof(struct pcap_pkthdr); |
---|
1821 | |
---|
1822 | /* copy the packet */ |
---|
1823 | memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen); |
---|
1824 | queue->len += pkt_header->caplen; |
---|
1825 | |
---|
1826 | return (0); |
---|
1827 | } |
---|
1828 | |
---|
1829 | u_int |
---|
1830 | pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue *queue, int sync) |
---|
1831 | { |
---|
1832 | return (p->sendqueue_transmit_op(p, queue, sync)); |
---|
1833 | } |
---|
1834 | |
---|
1835 | static u_int |
---|
1836 | pcap_sendqueue_transmit_dead(pcap_t *p, pcap_send_queue *queue, int sync) |
---|
1837 | { |
---|
1838 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1839 | "Packets cannot be transmitted on a pcap_open_dead pcap_t"); |
---|
1840 | return (0); |
---|
1841 | } |
---|
1842 | |
---|
1843 | int |
---|
1844 | pcap_setuserbuffer(pcap_t *p, int size) |
---|
1845 | { |
---|
1846 | return (p->setuserbuffer_op(p, size)); |
---|
1847 | } |
---|
1848 | |
---|
1849 | static int |
---|
1850 | pcap_setuserbuffer_dead(pcap_t *p, int size) |
---|
1851 | { |
---|
1852 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1853 | "The user buffer cannot be set on a pcap_open_dead pcap_t"); |
---|
1854 | return (-1); |
---|
1855 | } |
---|
1856 | |
---|
1857 | int |
---|
1858 | pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks) |
---|
1859 | { |
---|
1860 | return (p->live_dump_op(p, filename, maxsize, maxpacks)); |
---|
1861 | } |
---|
1862 | |
---|
1863 | static int |
---|
1864 | pcap_live_dump_dead(pcap_t *p, char *filename, int maxsize, int maxpacks) |
---|
1865 | { |
---|
1866 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1867 | "Live packet dumping cannot be performed on a pcap_open_dead pcap_t"); |
---|
1868 | return (-1); |
---|
1869 | } |
---|
1870 | |
---|
1871 | int |
---|
1872 | pcap_live_dump_ended(pcap_t *p, int sync) |
---|
1873 | { |
---|
1874 | return (p->live_dump_ended_op(p, sync)); |
---|
1875 | } |
---|
1876 | |
---|
1877 | static int |
---|
1878 | pcap_live_dump_ended_dead(pcap_t *p, int sync) |
---|
1879 | { |
---|
1880 | pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, |
---|
1881 | "Live packet dumping cannot be performed on a pcap_open_dead pcap_t"); |
---|
1882 | return (-1); |
---|
1883 | } |
---|
1884 | |
---|
1885 | PAirpcapHandle |
---|
1886 | pcap_get_airpcap_handle(pcap_t *p) |
---|
1887 | { |
---|
1888 | PAirpcapHandle handle; |
---|
1889 | |
---|
1890 | handle = p->get_airpcap_handle_op(p); |
---|
1891 | if (handle == NULL) { |
---|
1892 | (void)pcap_snprintf(p->errbuf, sizeof(p->errbuf), |
---|
1893 | "This isn't an AirPcap device"); |
---|
1894 | } |
---|
1895 | return (handle); |
---|
1896 | } |
---|
1897 | |
---|
1898 | static PAirpcapHandle |
---|
1899 | pcap_get_airpcap_handle_dead(pcap_t *p) |
---|
1900 | { |
---|
1901 | return (NULL); |
---|
1902 | } |
---|
1903 | #endif |
---|
1904 | |
---|
1905 | /* |
---|
1906 | * On some platforms, we need to clean up promiscuous or monitor mode |
---|
1907 | * when we close a device - and we want that to happen even if the |
---|
1908 | * application just exits without explicitl closing devices. |
---|
1909 | * On those platforms, we need to register a "close all the pcaps" |
---|
1910 | * routine to be called when we exit, and need to maintain a list of |
---|
1911 | * pcaps that need to be closed to clean up modes. |
---|
1912 | * |
---|
1913 | * XXX - not thread-safe. |
---|
1914 | */ |
---|
1915 | |
---|
1916 | /* |
---|
1917 | * List of pcaps on which we've done something that needs to be |
---|
1918 | * cleaned up. |
---|
1919 | * If there are any such pcaps, we arrange to call "pcap_close_all()" |
---|
1920 | * when we exit, and have it close all of them. |
---|
1921 | */ |
---|
1922 | static struct pcap *pcaps_to_close; |
---|
1923 | |
---|
1924 | /* |
---|
1925 | * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to |
---|
1926 | * be called on exit. |
---|
1927 | */ |
---|
1928 | static int did_atexit; |
---|
1929 | |
---|
1930 | static void |
---|
1931 | pcap_close_all(void) |
---|
1932 | { |
---|
1933 | struct pcap *handle; |
---|
1934 | |
---|
1935 | while ((handle = pcaps_to_close) != NULL) |
---|
1936 | pcap_close(handle); |
---|
1937 | } |
---|
1938 | |
---|
1939 | int |
---|
1940 | pcap_do_addexit(pcap_t *p) |
---|
1941 | { |
---|
1942 | /* |
---|
1943 | * If we haven't already done so, arrange to have |
---|
1944 | * "pcap_close_all()" called when we exit. |
---|
1945 | */ |
---|
1946 | if (!did_atexit) { |
---|
1947 | if (atexit(pcap_close_all) != 0) { |
---|
1948 | /* |
---|
1949 | * "atexit()" failed; let our caller know. |
---|
1950 | */ |
---|
1951 | strlcpy(p->errbuf, "atexit failed", PCAP_ERRBUF_SIZE); |
---|
1952 | return (0); |
---|
1953 | } |
---|
1954 | did_atexit = 1; |
---|
1955 | } |
---|
1956 | return (1); |
---|
1957 | } |
---|
1958 | |
---|
1959 | void |
---|
1960 | pcap_add_to_pcaps_to_close(pcap_t *p) |
---|
1961 | { |
---|
1962 | p->next = pcaps_to_close; |
---|
1963 | pcaps_to_close = p; |
---|
1964 | } |
---|
1965 | |
---|
1966 | void |
---|
1967 | pcap_remove_from_pcaps_to_close(pcap_t *p) |
---|
1968 | { |
---|
1969 | pcap_t *pc, *prevpc; |
---|
1970 | |
---|
1971 | for (pc = pcaps_to_close, prevpc = NULL; pc != NULL; |
---|
1972 | prevpc = pc, pc = pc->next) { |
---|
1973 | if (pc == p) { |
---|
1974 | /* |
---|
1975 | * Found it. Remove it from the list. |
---|
1976 | */ |
---|
1977 | if (prevpc == NULL) { |
---|
1978 | /* |
---|
1979 | * It was at the head of the list. |
---|
1980 | */ |
---|
1981 | pcaps_to_close = pc->next; |
---|
1982 | } else { |
---|
1983 | /* |
---|
1984 | * It was in the middle of the list. |
---|
1985 | */ |
---|
1986 | prevpc->next = pc->next; |
---|
1987 | } |
---|
1988 | break; |
---|
1989 | } |
---|
1990 | } |
---|
1991 | } |
---|
1992 | |
---|
1993 | void |
---|
1994 | pcap_cleanup_live_common(pcap_t *p) |
---|
1995 | { |
---|
1996 | if (p->buffer != NULL) { |
---|
1997 | free(p->buffer); |
---|
1998 | p->buffer = NULL; |
---|
1999 | } |
---|
2000 | if (p->dlt_list != NULL) { |
---|
2001 | free(p->dlt_list); |
---|
2002 | p->dlt_list = NULL; |
---|
2003 | p->dlt_count = 0; |
---|
2004 | } |
---|
2005 | if (p->tstamp_type_list != NULL) { |
---|
2006 | free(p->tstamp_type_list); |
---|
2007 | p->tstamp_type_list = NULL; |
---|
2008 | p->tstamp_type_count = 0; |
---|
2009 | } |
---|
2010 | if (p->tstamp_precision_list != NULL) { |
---|
2011 | free(p->tstamp_precision_list); |
---|
2012 | p->tstamp_precision_list = NULL; |
---|
2013 | p->tstamp_precision_count = 0; |
---|
2014 | } |
---|
2015 | pcap_freecode(&p->fcode); |
---|
2016 | #if !defined(_WIN32) && !defined(MSDOS) |
---|
2017 | if (p->fd >= 0) { |
---|
2018 | close(p->fd); |
---|
2019 | p->fd = -1; |
---|
2020 | } |
---|
2021 | p->selectable_fd = -1; |
---|
2022 | #endif |
---|
2023 | } |
---|
2024 | |
---|
2025 | static void |
---|
2026 | pcap_cleanup_dead(pcap_t *p _U_) |
---|
2027 | { |
---|
2028 | /* Nothing to do. */ |
---|
2029 | } |
---|
2030 | |
---|
2031 | pcap_t * |
---|
2032 | pcap_open_dead_with_tstamp_precision(int linktype, int snaplen, u_int precision) |
---|
2033 | { |
---|
2034 | pcap_t *p; |
---|
2035 | |
---|
2036 | switch (precision) { |
---|
2037 | |
---|
2038 | case PCAP_TSTAMP_PRECISION_MICRO: |
---|
2039 | case PCAP_TSTAMP_PRECISION_NANO: |
---|
2040 | break; |
---|
2041 | |
---|
2042 | default: |
---|
2043 | return NULL; |
---|
2044 | } |
---|
2045 | p = malloc(sizeof(*p)); |
---|
2046 | if (p == NULL) |
---|
2047 | return NULL; |
---|
2048 | memset (p, 0, sizeof(*p)); |
---|
2049 | p->snapshot = snaplen; |
---|
2050 | p->linktype = linktype; |
---|
2051 | p->opt.tstamp_precision = precision; |
---|
2052 | p->stats_op = pcap_stats_dead; |
---|
2053 | #ifdef _WIN32 |
---|
2054 | p->stats_ex_op = (stats_ex_op_t)pcap_not_initialized_ptr; |
---|
2055 | p->setbuff_op = pcap_setbuff_dead; |
---|
2056 | p->setmode_op = pcap_setmode_dead; |
---|
2057 | p->setmintocopy_op = pcap_setmintocopy_dead; |
---|
2058 | p->getevent_op = pcap_getevent_dead; |
---|
2059 | p->oid_get_request_op = pcap_oid_get_request_dead; |
---|
2060 | p->oid_set_request_op = pcap_oid_set_request_dead; |
---|
2061 | p->sendqueue_transmit_op = pcap_sendqueue_transmit_dead; |
---|
2062 | p->setuserbuffer_op = pcap_setuserbuffer_dead; |
---|
2063 | p->live_dump_op = pcap_live_dump_dead; |
---|
2064 | p->live_dump_ended_op = pcap_live_dump_ended_dead; |
---|
2065 | p->get_airpcap_handle_op = pcap_get_airpcap_handle_dead; |
---|
2066 | #endif |
---|
2067 | p->cleanup_op = pcap_cleanup_dead; |
---|
2068 | |
---|
2069 | /* |
---|
2070 | * A "dead" pcap_t never requires special BPF code generation. |
---|
2071 | */ |
---|
2072 | p->bpf_codegen_flags = 0; |
---|
2073 | |
---|
2074 | p->activated = 1; |
---|
2075 | return (p); |
---|
2076 | } |
---|
2077 | |
---|
2078 | pcap_t * |
---|
2079 | pcap_open_dead(int linktype, int snaplen) |
---|
2080 | { |
---|
2081 | return (pcap_open_dead_with_tstamp_precision(linktype, snaplen, |
---|
2082 | PCAP_TSTAMP_PRECISION_MICRO)); |
---|
2083 | } |
---|
2084 | |
---|
2085 | /* |
---|
2086 | * API compatible with WinPcap's "send a packet" routine - returns -1 |
---|
2087 | * on error, 0 otherwise. |
---|
2088 | * |
---|
2089 | * XXX - what if we get a short write? |
---|
2090 | */ |
---|
2091 | int |
---|
2092 | pcap_sendpacket(pcap_t *p, const u_char *buf, int size) |
---|
2093 | { |
---|
2094 | if (p->inject_op(p, buf, size) == -1) |
---|
2095 | return (-1); |
---|
2096 | return (0); |
---|
2097 | } |
---|
2098 | |
---|
2099 | /* |
---|
2100 | * API compatible with OpenBSD's "send a packet" routine - returns -1 on |
---|
2101 | * error, number of bytes written otherwise. |
---|
2102 | */ |
---|
2103 | int |
---|
2104 | pcap_inject(pcap_t *p, const void *buf, size_t size) |
---|
2105 | { |
---|
2106 | return (p->inject_op(p, buf, size)); |
---|
2107 | } |
---|
2108 | |
---|
2109 | void |
---|
2110 | pcap_close(pcap_t *p) |
---|
2111 | { |
---|
2112 | if (p->opt.device != NULL) |
---|
2113 | free(p->opt.device); |
---|
2114 | p->cleanup_op(p); |
---|
2115 | free(p); |
---|
2116 | } |
---|
2117 | |
---|
2118 | /* |
---|
2119 | * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw |
---|
2120 | * data for the packet, check whether the packet passes the filter. |
---|
2121 | * Returns the return value of the filter program, which will be zero if |
---|
2122 | * the packet doesn't pass and non-zero if the packet does pass. |
---|
2123 | */ |
---|
2124 | int |
---|
2125 | pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h, |
---|
2126 | const u_char *pkt) |
---|
2127 | { |
---|
2128 | const struct bpf_insn *fcode = fp->bf_insns; |
---|
2129 | |
---|
2130 | if (fcode != NULL) |
---|
2131 | return (bpf_filter(fcode, pkt, h->len, h->caplen)); |
---|
2132 | else |
---|
2133 | return (0); |
---|
2134 | } |
---|
2135 | |
---|
2136 | #include "pcap_version.h" |
---|
2137 | |
---|
2138 | #ifdef _WIN32 |
---|
2139 | |
---|
2140 | static char *full_pcap_version_string; |
---|
2141 | |
---|
2142 | #ifdef HAVE_VERSION_H |
---|
2143 | /* |
---|
2144 | * libpcap being built for Windows, as part of a WinPcap/Npcap source |
---|
2145 | * tree. Include version.h from that source tree to get the WinPcap/Npcap |
---|
2146 | * version. |
---|
2147 | * |
---|
2148 | * XXX - it'd be nice if we could somehow generate the WinPcap version number |
---|
2149 | * when building WinPcap. (It'd be nice to do so for the packet.dll version |
---|
2150 | * number as well.) |
---|
2151 | */ |
---|
2152 | #include "../../version.h" |
---|
2153 | |
---|
2154 | static const char wpcap_version_string[] = WINPCAP_VER_STRING; |
---|
2155 | static const char pcap_version_string_fmt[] = |
---|
2156 | WINPCAP_PRODUCT_NAME " version %s, based on %s"; |
---|
2157 | static const char pcap_version_string_packet_dll_fmt[] = |
---|
2158 | WINPCAP_PRODUCT_NAME " version %s (packet.dll version %s), based on %s"; |
---|
2159 | |
---|
2160 | const char * |
---|
2161 | pcap_lib_version(void) |
---|
2162 | { |
---|
2163 | char *packet_version_string; |
---|
2164 | size_t full_pcap_version_string_len; |
---|
2165 | |
---|
2166 | if (full_pcap_version_string == NULL) { |
---|
2167 | /* |
---|
2168 | * Generate the version string. |
---|
2169 | */ |
---|
2170 | packet_version_string = PacketGetVersion(); |
---|
2171 | if (strcmp(wpcap_version_string, packet_version_string) == 0) { |
---|
2172 | /* |
---|
2173 | * WinPcap version string and packet.dll version |
---|
2174 | * string are the same; just report the WinPcap |
---|
2175 | * version. |
---|
2176 | */ |
---|
2177 | full_pcap_version_string_len = |
---|
2178 | (sizeof pcap_version_string_fmt - 4) + |
---|
2179 | strlen(wpcap_version_string) + |
---|
2180 | strlen(pcap_version_string); |
---|
2181 | full_pcap_version_string = |
---|
2182 | malloc(full_pcap_version_string_len); |
---|
2183 | if (full_pcap_version_string == NULL) |
---|
2184 | return (NULL); |
---|
2185 | pcap_snprintf(full_pcap_version_string, |
---|
2186 | full_pcap_version_string_len, |
---|
2187 | pcap_version_string_fmt, |
---|
2188 | wpcap_version_string, |
---|
2189 | pcap_version_string); |
---|
2190 | } else { |
---|
2191 | /* |
---|
2192 | * WinPcap version string and packet.dll version |
---|
2193 | * string are different; that shouldn't be the |
---|
2194 | * case (the two libraries should come from the |
---|
2195 | * same version of WinPcap), so we report both |
---|
2196 | * versions. |
---|
2197 | */ |
---|
2198 | full_pcap_version_string_len = |
---|
2199 | (sizeof pcap_version_string_packet_dll_fmt - 6) + |
---|
2200 | strlen(wpcap_version_string) + |
---|
2201 | strlen(packet_version_string) + |
---|
2202 | strlen(pcap_version_string); |
---|
2203 | full_pcap_version_string = malloc(full_pcap_version_string_len); |
---|
2204 | if (full_pcap_version_string == NULL) |
---|
2205 | return (NULL); |
---|
2206 | pcap_snprintf(full_pcap_version_string, |
---|
2207 | full_pcap_version_string_len, |
---|
2208 | pcap_version_string_packet_dll_fmt, |
---|
2209 | wpcap_version_string, |
---|
2210 | packet_version_string, |
---|
2211 | pcap_version_string); |
---|
2212 | } |
---|
2213 | } |
---|
2214 | return (full_pcap_version_string); |
---|
2215 | } |
---|
2216 | |
---|
2217 | #else /* HAVE_VERSION_H */ |
---|
2218 | |
---|
2219 | /* |
---|
2220 | * libpcap being built for Windows, not as part of a WinPcap/Npcap source |
---|
2221 | * tree. |
---|
2222 | */ |
---|
2223 | static const char pcap_version_string_packet_dll_fmt[] = |
---|
2224 | "%s (packet.dll version %s)"; |
---|
2225 | const char * |
---|
2226 | pcap_lib_version(void) |
---|
2227 | { |
---|
2228 | char *packet_version_string; |
---|
2229 | size_t full_pcap_version_string_len; |
---|
2230 | |
---|
2231 | if (full_pcap_version_string == NULL) { |
---|
2232 | /* |
---|
2233 | * Generate the version string. Report the packet.dll |
---|
2234 | * version. |
---|
2235 | */ |
---|
2236 | packet_version_string = PacketGetVersion(); |
---|
2237 | full_pcap_version_string_len = |
---|
2238 | (sizeof pcap_version_string_packet_dll_fmt - 4) + |
---|
2239 | strlen(pcap_version_string) + |
---|
2240 | strlen(packet_version_string); |
---|
2241 | full_pcap_version_string = malloc(full_pcap_version_string_len); |
---|
2242 | if (full_pcap_version_string == NULL) |
---|
2243 | return (NULL); |
---|
2244 | pcap_snprintf(full_pcap_version_string, |
---|
2245 | full_pcap_version_string_len, |
---|
2246 | pcap_version_string_packet_dll_fmt, |
---|
2247 | pcap_version_string, |
---|
2248 | packet_version_string); |
---|
2249 | } |
---|
2250 | return (full_pcap_version_string); |
---|
2251 | } |
---|
2252 | |
---|
2253 | #endif /* HAVE_VERSION_H */ |
---|
2254 | |
---|
2255 | #elif defined(MSDOS) |
---|
2256 | |
---|
2257 | static char *full_pcap_version_string; |
---|
2258 | |
---|
2259 | const char * |
---|
2260 | pcap_lib_version (void) |
---|
2261 | { |
---|
2262 | char *packet_version_string; |
---|
2263 | size_t full_pcap_version_string_len; |
---|
2264 | static char dospfx[] = "DOS-"; |
---|
2265 | |
---|
2266 | if (full_pcap_version_string == NULL) { |
---|
2267 | /* |
---|
2268 | * Generate the version string. |
---|
2269 | */ |
---|
2270 | full_pcap_version_string_len = |
---|
2271 | sizeof dospfx + strlen(pcap_version_string); |
---|
2272 | full_pcap_version_string = |
---|
2273 | malloc(full_pcap_version_string_len); |
---|
2274 | if (full_pcap_version_string == NULL) |
---|
2275 | return (NULL); |
---|
2276 | strcpy(full_pcap_version_string, dospfx); |
---|
2277 | strcat(full_pcap_version_string, pcap_version_string); |
---|
2278 | } |
---|
2279 | return (full_pcap_version_string); |
---|
2280 | } |
---|
2281 | |
---|
2282 | #else /* UN*X */ |
---|
2283 | |
---|
2284 | const char * |
---|
2285 | pcap_lib_version(void) |
---|
2286 | { |
---|
2287 | return (pcap_version_string); |
---|
2288 | } |
---|
2289 | #endif |
---|
2290 | |
---|
2291 | #ifdef YYDEBUG |
---|
2292 | /* |
---|
2293 | * Set the internal "debug printout" flag for the filter expression parser. |
---|
2294 | * The code to print that stuff is present only if YYDEBUG is defined, so |
---|
2295 | * the flag, and the routine to set it, are defined only if YYDEBUG is |
---|
2296 | * defined. |
---|
2297 | * |
---|
2298 | * This is intended for libpcap developers, not for general use. |
---|
2299 | * If you want to set these in a program, you'll have to declare this |
---|
2300 | * routine yourself, with the appropriate DLL import attribute on Windows; |
---|
2301 | * it's not declared in any header file, and won't be declared in any |
---|
2302 | * header file provided by libpcap. |
---|
2303 | */ |
---|
2304 | PCAP_API void pcap_set_parser_debug(int value); |
---|
2305 | |
---|
2306 | PCAP_API_DEF void |
---|
2307 | pcap_set_parser_debug(int value) |
---|
2308 | { |
---|
2309 | extern int pcap_debug; |
---|
2310 | |
---|
2311 | pcap_debug = value; |
---|
2312 | } |
---|
2313 | #endif |
---|
2314 | |
---|
2315 | #ifdef BDEBUG |
---|
2316 | /* |
---|
2317 | * Set the internal "debug printout" flag for the filter expression optimizer. |
---|
2318 | * The code to print that stuff is present only if BDEBUG is defined, so |
---|
2319 | * the flag, and the routine to set it, are defined only if BDEBUG is |
---|
2320 | * defined. |
---|
2321 | * |
---|
2322 | * This is intended for libpcap developers, not for general use. |
---|
2323 | * If you want to set these in a program, you'll have to declare this |
---|
2324 | * routine yourself, with the appropriate DLL import attribute on Windows; |
---|
2325 | * it's not declared in any header file, and won't be declared in any |
---|
2326 | * header file provided by libpcap. |
---|
2327 | */ |
---|
2328 | PCAP_API void pcap_set_optimizer_debug(int value); |
---|
2329 | |
---|
2330 | PCAP_API_DEF void |
---|
2331 | pcap_set_optimizer_debug(int value) |
---|
2332 | { |
---|
2333 | extern int pcap_optimizer_debug; |
---|
2334 | |
---|
2335 | pcap_optimizer_debug = value; |
---|
2336 | } |
---|
2337 | #endif |
---|