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