1 /**
2 * pcapif.c - This file is part of lwIP pcapif
3 *
4 ****************************************************************************
5 *
6 * This file is derived from an example in lwIP with the following license:
7 *
8 * Copyright (c) 2001, Swedish Institute of Computer Science.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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
37 /* include the port-dependent configuration */
38 #include "lwipcfg.h"
39
40 #include <stdlib.h>
41 #include <stdio.h>
42
43 #ifdef _MSC_VER
44 #pragma warning( push, 3 )
45 #include "pcap.h"
46 #pragma warning ( pop )
47 #else
48 /* e.g. mingw */
49 #define _MSC_VER 1500
50 #include "pcap.h"
51 #undef _MSC_VER
52 #endif
53
54 #include "lwip/opt.h"
55
56 #if LWIP_ETHERNET
57
58 #include "pcapif.h"
59
60 #include <stdlib.h>
61 #include <stdio.h>
62 #include <string.h>
63
64 #include "lwip/debug.h"
65
66 #include "lwip/def.h"
67 #include "lwip/mem.h"
68 #include "lwip/pbuf.h"
69 #include "lwip/stats.h"
70 #include "lwip/sys.h"
71 #include "lwip/ip.h"
72 #include "lwip/snmp.h"
73 #include "lwip/tcpip.h"
74 #include "lwip/timeouts.h"
75 #include "lwip/ethip6.h"
76
77 #include "lwip/etharp.h"
78
79 /* For compatibility with old pcap */
80 #ifndef PCAP_OPENFLAG_PROMISCUOUS
81 #define PCAP_OPENFLAG_PROMISCUOUS 1
82 #endif
83
84 /** Set this to 0 to receive all multicast ethernet destination addresses */
85 #ifndef PCAPIF_FILTER_GROUP_ADDRESSES
86 #define PCAPIF_FILTER_GROUP_ADDRESSES 1
87 #endif
88
89 /** Set this to 1 to receive all frames (also unicast to other addresses)
90 * In this mode, filtering out our own tx packets from loopback receiving
91 * is done via matching rx against recent tx (memcmp).
92 */
93 #ifndef PCAPIF_RECEIVE_PROMISCUOUS
94 #define PCAPIF_RECEIVE_PROMISCUOUS 0
95 #endif
96
97 /* Define those to better describe your network interface.
98 For now, we use 'e0', 'e1', 'e2' and so on */
99 #define IFNAME0 'e'
100 #define IFNAME1 '0'
101
102 /** index of the network adapter to use for lwIP */
103 #ifndef PACKET_LIB_ADAPTER_NR
104 #define PACKET_LIB_ADAPTER_NR 0
105 #endif
106
107 /** If 1, check link state and report it to lwIP.
108 * If 0, don't check link state (lwIP link state is always UP).
109 */
110 #ifndef PCAPIF_HANDLE_LINKSTATE
111 #define PCAPIF_HANDLE_LINKSTATE 1
112 #endif
113
114 /** If 1, use PBUF_REF for RX (for testing purposes mainly).
115 * For this, LWIP_SUPPORT_CUSTOM_PBUF must be enabled.
116 * Also, PBUF_POOL_BUFSIZE must be set high enough to ensure all rx packets
117 * fit into a single pbuf.
118 */
119 #ifndef PCAPIF_RX_REF
120 #define PCAPIF_RX_REF 0
121 #endif
122
123 /** This can be used when netif->state is used for something else in your
124 * application (e.g. when wrapping a class around this interface). Just
125 * make sure this define returns the state pointer set by
126 * pcapif_low_level_init() (e.g. by using an offset or a callback).
127 */
128 #ifndef PCAPIF_GET_STATE_PTR
129 #define PCAPIF_GET_STATE_PTR(netif) ((netif)->state)
130 #endif
131
132 /** Define this to 1 to allocate readonly pbufs for RX (needs PCAPIF_RX_REF,
133 * only implemented for windows, for now)
134 */
135 #ifndef PCAPIF_RX_READONLY
136 #define PCAPIF_RX_READONLY 0
137 #endif
138
139 #if PCAPIF_HANDLE_LINKSTATE
140 #include "pcapif_helper.h"
141
142 /* Define "PHY" delay when "link up" */
143 #ifndef PCAPIF_LINKUP_DELAY
144 #define PCAPIF_LINKUP_DELAY 0
145 #endif
146
147 #define PCAPIF_LINKCHECK_INTERVAL_MS 500
148
149 /* link state notification macro */
150 #if PCAPIF_LINKUP_DELAY
151 #define PCAPIF_NOTIFY_LINKSTATE(netif, linkfunc) sys_timeout(PCAPIF_LINKUP_DELAY, (sys_timeout_handler)linkfunc, netif)
152 #else /* PHY_LINKUP_DELAY */
153 #define PCAPIF_NOTIFY_LINKSTATE(netif, linkfunc) linkfunc(netif)
154 #endif /* PHY_LINKUP_DELAY */
155
156 #endif /* PCAPIF_HANDLE_LINKSTATE */
157
158 /* Define PCAPIF_RX_LOCK_LWIP and PCAPIF_RX_UNLOCK_LWIP if you need to lock the lwIP core
159 before/after pbuf_alloc() or netif->input() are called on RX. */
160 #ifndef PCAPIF_RX_LOCK_LWIP
161 #define PCAPIF_RX_LOCK_LWIP()
162 #endif
163 #ifndef PCAPIF_RX_UNLOCK_LWIP
164 #define PCAPIF_RX_UNLOCK_LWIP()
165 #endif
166
167 #define ETH_MIN_FRAME_LEN 60U
168 #define ETH_MAX_FRAME_LEN 1518U
169
170 #define ADAPTER_NAME_LEN 128
171 #define ADAPTER_DESC_LEN 128
172
173 #if PCAPIF_RECEIVE_PROMISCUOUS
174 #ifndef PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS
175 #define PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS 128
176 #endif
177 struct pcapipf_pending_packet {
178 struct pcapipf_pending_packet *next;
179 u16_t len;
180 u8_t data[ETH_MAX_FRAME_LEN];
181 };
182 #endif /* PCAPIF_RECEIVE_PROMISCUOUS */
183
184 /* Packet Adapter information */
185 struct pcapif_private {
186 void *input_fn_arg;
187 pcap_t *adapter;
188 char name[ADAPTER_NAME_LEN];
189 char description[ADAPTER_DESC_LEN];
190 int shutdown_called;
191 #if PCAPIF_RX_USE_THREAD
192 volatile int rx_run;
193 volatile int rx_running;
194 #endif /* PCAPIF_RX_USE_THREAD */
195 #if PCAPIF_HANDLE_LINKSTATE
196 struct pcapifh_linkstate *link_state;
197 enum pcapifh_link_event last_link_event;
198 #endif /* PCAPIF_HANDLE_LINKSTATE */
199 #if PCAPIF_RECEIVE_PROMISCUOUS
200 struct pcapipf_pending_packet packets[PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS];
201 struct pcapipf_pending_packet *tx_packets;
202 struct pcapipf_pending_packet *free_packets;
203 #endif /* PCAPIF_RECEIVE_PROMISCUOUS */
204 };
205
206 #if PCAPIF_RECEIVE_PROMISCUOUS
207 static void
pcapif_init_tx_packets(struct pcapif_private * priv)208 pcapif_init_tx_packets(struct pcapif_private *priv)
209 {
210 int i;
211 priv->tx_packets = NULL;
212 priv->free_packets = NULL;
213 for (i = 0; i < PCAPIF_LOOPBACKFILTER_NUM_TX_PACKETS; i++) {
214 struct pcapipf_pending_packet *pack = &priv->packets[i];
215 pack->len = 0;
216 pack->next = priv->free_packets;
217 priv->free_packets = pack;
218 }
219 }
220
221 static void
pcapif_add_tx_packet(struct pcapif_private * priv,unsigned char * buf,u16_t tot_len)222 pcapif_add_tx_packet(struct pcapif_private *priv, unsigned char *buf, u16_t tot_len)
223 {
224 struct pcapipf_pending_packet *tx;
225 struct pcapipf_pending_packet *pack;
226 SYS_ARCH_DECL_PROTECT(lev);
227
228 /* get a free packet (locked) */
229 SYS_ARCH_PROTECT(lev);
230 pack = priv->free_packets;
231 if ((pack == NULL) && (priv->tx_packets != NULL)) {
232 /* no free packets, reuse the oldest */
233 pack = priv->tx_packets;
234 priv->tx_packets = pack->next;
235 }
236 LWIP_ASSERT("no free packet", pack != NULL);
237 priv->free_packets = pack->next;
238 pack->next = NULL;
239 SYS_ARCH_UNPROTECT(lev);
240
241 /* set up the packet (unlocked) */
242 pack->len = tot_len;
243 memcpy(pack->data, buf, tot_len);
244
245 /* put the packet on the list (locked) */
246 SYS_ARCH_PROTECT(lev);
247 if (priv->tx_packets != NULL) {
248 for (tx = priv->tx_packets; tx->next != NULL; tx = tx->next);
249 LWIP_ASSERT("bug", tx != NULL);
250 tx->next = pack;
251 } else {
252 priv->tx_packets = pack;
253 }
254 SYS_ARCH_UNPROTECT(lev);
255 }
256
257 static int
pcapif_compare_packets(struct pcapipf_pending_packet * pack,const void * packet,int packet_len)258 pcapif_compare_packets(struct pcapipf_pending_packet *pack, const void *packet, int packet_len)
259 {
260 if (pack->len == packet_len) {
261 if (!memcmp(pack->data, packet, packet_len)) {
262 return 1;
263 }
264 }
265 return 0;
266 }
267
268 static int
pcaipf_is_tx_packet(struct netif * netif,const void * packet,int packet_len)269 pcaipf_is_tx_packet(struct netif *netif, const void *packet, int packet_len)
270 {
271 struct pcapif_private *priv = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
272 struct pcapipf_pending_packet *iter, *last;
273 SYS_ARCH_DECL_PROTECT(lev);
274
275 last = priv->tx_packets;
276 if (last == NULL) {
277 /* list is empty */
278 return 0;
279 }
280 /* compare the first packet */
281 if (pcapif_compare_packets(last, packet, packet_len)) {
282 SYS_ARCH_PROTECT(lev);
283 LWIP_ASSERT("list has changed", last == priv->tx_packets);
284 priv->tx_packets = last->next;
285 last->next = priv->free_packets;
286 priv->free_packets = last;
287 last->len = 0;
288 SYS_ARCH_UNPROTECT(lev);
289 return 1;
290 }
291 SYS_ARCH_PROTECT(lev);
292 for (iter = last->next; iter != NULL; last = iter, iter = iter->next) {
293 /* unlock while comparing (this works because we have a clean threading separation
294 of adding and removing items and adding is only done at the end) */
295 SYS_ARCH_UNPROTECT(lev);
296 if (pcapif_compare_packets(iter, packet, packet_len)) {
297 SYS_ARCH_PROTECT(lev);
298 LWIP_ASSERT("last != NULL", last != NULL);
299 last->next = iter->next;
300 iter->next = priv->free_packets;
301 priv->free_packets = iter;
302 last->len = 0;
303 SYS_ARCH_UNPROTECT(lev);
304 return 1;
305 }
306 SYS_ARCH_PROTECT(lev);
307 }
308 SYS_ARCH_UNPROTECT(lev);
309 return 0;
310 }
311 #else /* PCAPIF_RECEIVE_PROMISCUOUS */
312 #define pcapif_init_tx_packets(priv)
313 #define pcapif_add_tx_packet(priv, buf, tot_len)
314 static int
pcaipf_is_tx_packet(struct netif * netif,const void * packet,int packet_len)315 pcaipf_is_tx_packet(struct netif *netif, const void *packet, int packet_len)
316 {
317 const struct eth_addr *src = (const struct eth_addr *)packet + 1;
318 if (packet_len >= (ETH_HWADDR_LEN * 2)) {
319 /* Don't let feedback packets through (limitation in winpcap?) */
320 if(!memcmp(src, netif->hwaddr, ETH_HWADDR_LEN)) {
321 return 1;
322 }
323 }
324 return 0;
325 }
326 #endif /* PCAPIF_RECEIVE_PROMISCUOUS */
327
328 #if PCAPIF_RX_REF
329 struct pcapif_pbuf_custom
330 {
331 struct pbuf_custom pc;
332 #if PCAPIF_RX_READONLY
333 void *ro_mem;
334 #else
335 struct pbuf* p;
336 #endif
337 };
338 #endif /* PCAPIF_RX_REF */
339
340 /* Forward declarations. */
341 static void pcapif_input(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *packet);
342
343 #ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
344 /** Get the index of an adapter by its network address
345 *
346 * @param netaddr network address of the adapter (e.g. 192.168.1.0)
347 * @return index of the adapter or negative on error
348 */
349 static int
get_adapter_index_from_addr(struct in_addr * netaddr,char * guid,size_t guid_len)350 get_adapter_index_from_addr(struct in_addr *netaddr, char *guid, size_t guid_len)
351 {
352 pcap_if_t *alldevs;
353 pcap_if_t *d;
354 char errbuf[PCAP_ERRBUF_SIZE+1];
355 int index = 0;
356
357 memset(guid, 0, guid_len);
358
359 /* Retrieve the interfaces list */
360 if (pcap_findalldevs(&alldevs, errbuf) == -1) {
361 printf("Error in pcap_findalldevs: %s\n", errbuf);
362 return -1;
363 }
364 /* Scan the list printing every entry */
365 for (d = alldevs; d != NULL; d = d->next, index++) {
366 pcap_addr_t *a;
367 for(a = d->addresses; a != NULL; a = a->next) {
368 if (a->addr->sa_family == AF_INET) {
369 ULONG a_addr = ((struct sockaddr_in *)a->addr)->sin_addr.s_addr;
370 ULONG a_netmask = ((struct sockaddr_in *)a->netmask)->sin_addr.s_addr;
371 ULONG a_netaddr = a_addr & a_netmask;
372 ULONG addr = (*netaddr).s_addr;
373 if (a_netaddr == addr) {
374 int ret = -1;
375 char name[128];
376 char *start, *end;
377 size_t len = strlen(d->name);
378 if(len > 127) {
379 len = 127;
380 }
381 MEMCPY(name, d->name, len);
382 name[len] = 0;
383 start = strstr(name, "{");
384 if (start != NULL) {
385 end = strstr(start, "}");
386 if (end != NULL) {
387 size_t len = end - start + 1;
388 MEMCPY(guid, start, len);
389 ret = index;
390 }
391 }
392 pcap_freealldevs(alldevs);
393 return ret;
394 }
395 }
396 }
397 }
398 printf("Network address not found.\n");
399
400 pcap_freealldevs(alldevs);
401 return -1;
402 }
403 #endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
404
405 #if defined(PACKET_LIB_GET_ADAPTER_NETADDRESS) || defined(PACKET_LIB_ADAPTER_GUID)
406 /** Get the index of an adapter by its GUID
407 *
408 * @param adapter_guid GUID of the adapter
409 * @return index of the adapter or negative on error
410 */
411 static int
get_adapter_index(const char * adapter_guid)412 get_adapter_index(const char* adapter_guid)
413 {
414 pcap_if_t *alldevs;
415 pcap_if_t *d;
416 char errbuf[PCAP_ERRBUF_SIZE+1];
417 int idx = 0;
418
419 /* Retrieve the interfaces list */
420 if (pcap_findalldevs(&alldevs, errbuf) == -1) {
421 printf("Error in pcap_findalldevs: %s\n", errbuf);
422 return -1;
423 }
424 /* Scan the list and compare name vs. adapter_guid */
425 for (d = alldevs; d != NULL; d = d->next, idx++) {
426 if(strstr(d->name, adapter_guid)) {
427 pcap_freealldevs(alldevs);
428 return idx;
429 }
430 }
431 /* not found, dump all adapters */
432 printf("%d available adapters:\n", idx);
433 for (d = alldevs, idx = 0; d != NULL; d = d->next, idx++) {
434 printf("- %d: %s\n", idx, d->name);
435 }
436 pcap_freealldevs(alldevs);
437 return -1;
438 }
439 #endif /* defined(PACKET_LIB_GET_ADAPTER_NETADDRESS) || defined(PACKET_LIB_ADAPTER_GUID) */
440
441 static pcap_t*
pcapif_open_adapter(const char * adapter_name,char * errbuf)442 pcapif_open_adapter(const char* adapter_name, char* errbuf)
443 {
444 pcap_t* adapter = pcap_open_live(adapter_name,/* name of the device */
445 65536, /* portion of the packet to capture */
446 /* 65536 guarantees that the whole packet will be captured on all the link layers */
447 PCAP_OPENFLAG_PROMISCUOUS,/* promiscuous mode */
448 #if PCAPIF_RX_USE_THREAD
449 /*-*/1, /* don't wait at all for lower latency */
450 #else
451 1, /* wait 1 ms in ethernetif_poll */
452 #endif
453 errbuf); /* error buffer */
454 return adapter;
455 }
456
457 #if !PCAPIF_RX_USE_THREAD
458 static void
pcap_reopen_adapter(struct pcapif_private * pa)459 pcap_reopen_adapter(struct pcapif_private *pa)
460 {
461 char errbuf[PCAP_ERRBUF_SIZE+1];
462 pcap_if_t *alldevs;
463 if (pa->adapter != NULL) {
464 pcap_close(pa->adapter);
465 pa->adapter = NULL;
466 }
467 if (pcap_findalldevs(&alldevs, errbuf) != -1) {
468 pcap_if_t *d;
469 for (d = alldevs; d != NULL; d = d->next) {
470 if (!strcmp(d->name, pa->name)) {
471 pa->adapter = pcapif_open_adapter(pa->name, errbuf);
472 if (pa->adapter == NULL) {
473 printf("failed to reopen pcap adapter after failure: %s\n", errbuf);
474 }
475 break;
476 }
477 }
478 pcap_freealldevs(alldevs);
479 }
480 }
481 #endif
482
483 /**
484 * Open a network adapter and set it up for packet input
485 *
486 * @param adapter_num the index of the adapter to use
487 * @param arg argument to pass to input
488 * @return an adapter handle on success, NULL on failure
489 */
490 static struct pcapif_private*
pcapif_init_adapter(int adapter_num,void * arg)491 pcapif_init_adapter(int adapter_num, void *arg)
492 {
493 int i;
494 int number_of_adapters;
495 struct pcapif_private *pa;
496 char errbuf[PCAP_ERRBUF_SIZE+1];
497
498 pcap_if_t *alldevs;
499 pcap_if_t *d;
500 pcap_if_t *used_adapter = NULL;
501
502 pa = (struct pcapif_private *)malloc(sizeof(struct pcapif_private));
503 if (!pa) {
504 printf("Unable to alloc the adapter!\n");
505 return NULL;
506 }
507
508 memset(pa, 0, sizeof(struct pcapif_private));
509 pcapif_init_tx_packets(pa);
510 pa->input_fn_arg = arg;
511
512 /* Retrieve the interfaces list */
513 if (pcap_findalldevs(&alldevs, errbuf) == -1) {
514 free(pa);
515 return NULL; /* no adapters found */
516 }
517 /* get number of adapters and adapter pointer */
518 for (d = alldevs, number_of_adapters = 0; d != NULL; d = d->next, number_of_adapters++) {
519 if (number_of_adapters == adapter_num) {
520 char *desc = d->description;
521 size_t len;
522
523 len = strlen(d->name);
524 LWIP_ASSERT("len < ADAPTER_NAME_LEN", len < ADAPTER_NAME_LEN);
525 strcpy(pa->name, d->name);
526
527 used_adapter = d;
528 /* format vendor description */
529 if (desc != NULL) {
530 len = strlen(desc);
531 if (strstr(desc, " ' on local host") != NULL) {
532 len -= 16;
533 }
534 else if (strstr(desc, "' on local host") != NULL) {
535 len -= 15;
536 }
537 if (strstr(desc, "Network adapter '") == desc) {
538 len -= 17;
539 desc += 17;
540 }
541 len = LWIP_MIN(len, ADAPTER_DESC_LEN-1);
542 while ((desc[len-1] == ' ') || (desc[len-1] == '\t')) {
543 /* don't copy trailing whitespace */
544 len--;
545 }
546 strncpy(pa->description, desc, len);
547 pa->description[len] = 0;
548 } else {
549 strcpy(pa->description, "<no_desc>");
550 }
551 }
552 }
553
554 #ifndef PCAPIF_LIB_QUIET
555 /* Scan the list printing every entry */
556 for (d = alldevs, i = 0; d != NULL; d = d->next, i++) {
557 char *desc = d->description;
558 char descBuf[128];
559 size_t len;
560 const char* devname = d->name;
561 if (d->name == NULL) {
562 devname = "<unnamed>";
563 } else {
564 if (strstr(devname, "\\Device\\") == devname) {
565 /* windows: strip the first part */
566 devname += 8;
567 }
568 }
569 printf("%2i: %s\n", i, devname);
570 if (desc != NULL) {
571 /* format vendor description */
572 len = strlen(desc);
573 if (strstr(desc, " ' on local host") != NULL) {
574 len -= 16;
575 }
576 else if (strstr(desc, "' on local host") != NULL) {
577 len -= 15;
578 }
579 if (strstr(desc, "Network adapter '") == desc) {
580 len -= 17;
581 desc += 17;
582 }
583 len = LWIP_MIN(len, 127);
584 while ((desc[len-1] == ' ') || (desc[len-1] == '\t')) {
585 /* don't copy trailing whitespace */
586 len--;
587 }
588 strncpy(descBuf, desc, len);
589 descBuf[len] = 0;
590 printf(" Desc: \"%s\"\n", descBuf);
591 }
592 }
593 #endif /* PCAPIF_LIB_QUIET */
594
595 /* invalid adapter index -> check this after printing the adapters */
596 if (adapter_num < 0) {
597 printf("Invalid adapter_num: %d\n", adapter_num);
598 free(pa);
599 pcap_freealldevs(alldevs);
600 return NULL;
601 }
602 /* adapter index out of range */
603 if (adapter_num >= number_of_adapters) {
604 printf("Invalid adapter_num: %d\n", adapter_num);
605 free(pa);
606 pcap_freealldevs(alldevs);
607 return NULL;
608 }
609 #ifndef PCAPIF_LIB_QUIET
610 printf("Using adapter_num: %d\n", adapter_num);
611 #endif /* PCAPIF_LIB_QUIET */
612 /* set up the selected adapter */
613
614 LWIP_ASSERT("used_adapter != NULL", used_adapter != NULL);
615
616 /* Open the device */
617 pa->adapter = pcapif_open_adapter(used_adapter->name, errbuf);
618 if (pa->adapter == NULL) {
619 printf("\nUnable to open the adapter. %s is not supported by pcap (\"%s\").\n", used_adapter->name, errbuf);
620 /* Free the device list */
621 pcap_freealldevs(alldevs);
622 free(pa);
623 return NULL;
624 }
625 printf("Using adapter: \"%s\"\n", pa->description);
626 pcap_freealldevs(alldevs);
627
628 #if PCAPIF_HANDLE_LINKSTATE
629 pa->link_state = pcapifh_linkstate_init(pa->name);
630 pa->last_link_event = PCAPIF_LINKEVENT_UNKNOWN;
631 #endif /* PCAPIF_HANDLE_LINKSTATE */
632
633 return pa;
634 }
635
636 #if PCAPIF_HANDLE_LINKSTATE
637 static void
pcapif_check_linkstate(void * netif_ptr)638 pcapif_check_linkstate(void *netif_ptr)
639 {
640 struct netif *netif = (struct netif*)netif_ptr;
641 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
642 enum pcapifh_link_event le;
643
644 le = pcapifh_linkstate_get(pa->link_state);
645
646 if (pa->last_link_event != le) {
647 pa->last_link_event = le;
648 switch (le) {
649 case PCAPIF_LINKEVENT_UP: {
650 PCAPIF_NOTIFY_LINKSTATE(netif, netif_set_link_up);
651 break;
652 }
653 case PCAPIF_LINKEVENT_DOWN: {
654 PCAPIF_NOTIFY_LINKSTATE(netif, netif_set_link_down);
655 break;
656 }
657 case PCAPIF_LINKEVENT_UNKNOWN: /* fall through */
658 default:
659 break;
660 }
661 }
662 sys_timeout(PCAPIF_LINKCHECK_INTERVAL_MS, pcapif_check_linkstate, netif);
663 }
664 #endif /* PCAPIF_HANDLE_LINKSTATE */
665
666
667 /**
668 * Close the adapter (no more packets can be sent or received)
669 *
670 * @param netif netif to shutdown
671 */
672 void
pcapif_shutdown(struct netif * netif)673 pcapif_shutdown(struct netif *netif)
674 {
675 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
676 if (pa) {
677 #if PCAPIF_RX_USE_THREAD
678 pa->rx_run = 0;
679 #endif /* PCAPIF_RX_USE_THREAD */
680 if (pa->adapter) {
681 pcap_breakloop(pa->adapter);
682 pcap_close(pa->adapter);
683 }
684 #if PCAPIF_RX_USE_THREAD
685 /* wait for rxthread to end */
686 while(pa->rx_running);
687 #endif /* PCAPIF_RX_USE_THREAD */
688 #if PCAPIF_HANDLE_LINKSTATE
689 pcapifh_linkstate_close(pa->link_state);
690 #endif /* PCAPIF_HANDLE_LINKSTATE */
691 free(pa);
692 }
693 }
694
695 #if PCAPIF_RX_USE_THREAD
696 /** RX running in its own thread */
697 static void
pcapif_input_thread(void * arg)698 pcapif_input_thread(void *arg)
699 {
700 struct netif *netif = (struct netif *)arg;
701 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
702 do
703 {
704 struct pcap_pkthdr pkt_header;
705 const u_char *packet = pcap_next(pa->adapter, &pkt_header);
706 if(packet != NULL) {
707 pcapif_input((u_char*)pa, &pkt_header, packet);
708 }
709 } while (pa->rx_run);
710 pa->rx_running = 0;
711 }
712 #endif /* PCAPIF_RX_USE_THREAD */
713
714 /** Low-level initialization: find the correct adapter and initialize it.
715 */
716 static void
pcapif_low_level_init(struct netif * netif)717 pcapif_low_level_init(struct netif *netif)
718 {
719 u8_t my_mac_addr[ETH_HWADDR_LEN] = LWIP_MAC_ADDR_BASE;
720 int adapter_num = PACKET_LIB_ADAPTER_NR;
721 struct pcapif_private *pa;
722 #ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
723 ip4_addr_t netaddr;
724 #define GUID_LEN 128
725 char guid[GUID_LEN + 1];
726 #endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
727
728 /* If 'state' is != NULL at this point, we assume it is an 'int' giving
729 the index of the adapter to use (+ 1 because 0==NULL is invalid).
730 This can be used to instantiate multiple PCAP drivers. */
731 if (netif->state != NULL) {
732 adapter_num = (LWIP_PTR_NUMERIC_CAST(int, netif->state)) - 1;
733 if (adapter_num < 0) {
734 printf("ERROR: invalid adapter index \"%d\"!\n", adapter_num);
735 LWIP_ASSERT("ERROR initializing network adapter!", 0);
736 return;
737 }
738 }
739
740 #ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
741 memset(&guid, 0, sizeof(guid));
742 PACKET_LIB_GET_ADAPTER_NETADDRESS(&netaddr);
743 if (get_adapter_index_from_addr((struct in_addr *)&netaddr, guid, GUID_LEN) < 0) {
744 printf("ERROR initializing network adapter, failed to get GUID for network address %s\n", ip4addr_ntoa(&netaddr));
745 LWIP_ASSERT("ERROR initializing network adapter, failed to get GUID for network address!", 0);
746 return;
747 }
748 adapter_num = get_adapter_index(guid);
749 if (adapter_num < 0) {
750 printf("ERROR finding network adapter with GUID \"%s\"!\n", guid);
751 LWIP_ASSERT("ERROR finding network adapter with expected GUID!", 0);
752 return;
753 }
754
755 #else /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
756 #ifdef PACKET_LIB_ADAPTER_GUID
757 /* get adapter index for guid string */
758 adapter_num = get_adapter_index(PACKET_LIB_ADAPTER_GUID);
759 if (adapter_num < 0) {
760 printf("ERROR finding network adapter with GUID \"%s\"!\n", PACKET_LIB_ADAPTER_GUID);
761 LWIP_ASSERT("ERROR initializing network adapter!", 0);
762 return;
763 }
764 #endif /* PACKET_LIB_ADAPTER_GUID */
765 #endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
766
767 /* Do whatever else is needed to initialize interface. */
768 pa = pcapif_init_adapter(adapter_num, netif);
769 if (pa == NULL) {
770 printf("ERROR initializing network adapter %d!\n", adapter_num);
771 LWIP_ASSERT("ERROR initializing network adapter!", 0);
772 return;
773 }
774 netif->state = pa;
775
776 /* change the MAC address to a unique value
777 so that multiple ethernetifs are supported */
778 /* @todo: this does NOT support multiple processes using this adapter! */
779 my_mac_addr[ETH_HWADDR_LEN - 1] += netif->num;
780 /* Copy MAC addr */
781 SMEMCPY(&netif->hwaddr, my_mac_addr, ETH_HWADDR_LEN);
782
783 /* get the initial link state of the selected interface */
784 #if PCAPIF_HANDLE_LINKSTATE
785 pa->last_link_event = pcapifh_linkstate_get(pa->link_state);
786 if (pa->last_link_event == PCAPIF_LINKEVENT_DOWN) {
787 netif_set_link_down(netif);
788 } else {
789 netif_set_link_up(netif);
790 }
791 sys_timeout(PCAPIF_LINKCHECK_INTERVAL_MS, pcapif_check_linkstate, netif);
792 #else /* PCAPIF_HANDLE_LINKSTATE */
793 /* just set the link up so that lwIP can transmit */
794 netif_set_link_up(netif);
795 #endif /* PCAPIF_HANDLE_LINKSTATE */
796
797 #if PCAPIF_RX_USE_THREAD
798 pa->rx_run = 1;
799 pa->rx_running = 1;
800 sys_thread_new("pcapif_rxthread", pcapif_input_thread, netif, 0, 0);
801 #endif
802
803 LWIP_DEBUGF(NETIF_DEBUG, ("pcapif: eth_addr %02X%02X%02X%02X%02X%02X\n",netif->hwaddr[0],netif->hwaddr[1],netif->hwaddr[2],netif->hwaddr[3],netif->hwaddr[4],netif->hwaddr[5]));
804 }
805
806 /** low_level_output():
807 * Transmit a packet. The packet is contained in the pbuf that is passed to
808 * the function. This pbuf might be chained.
809 */
810 static err_t
pcapif_low_level_output(struct netif * netif,struct pbuf * p)811 pcapif_low_level_output(struct netif *netif, struct pbuf *p)
812 {
813 struct pbuf *q;
814 unsigned char buffer[ETH_MAX_FRAME_LEN + ETH_PAD_SIZE];
815 unsigned char *buf = buffer;
816 unsigned char *ptr;
817 struct eth_hdr *ethhdr;
818 u16_t tot_len = p->tot_len - ETH_PAD_SIZE;
819 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
820
821 #if defined(LWIP_DEBUG) && LWIP_NETIF_TX_SINGLE_PBUF && !(LWIP_IPV4 && IP_FRAG) && (LWIP_IPV6 && LWIP_IPV6_FRAG)
822 LWIP_ASSERT("p->next == NULL && p->len == p->tot_len", p->next == NULL && p->len == p->tot_len);
823 #endif
824
825 /* initiate transfer */
826 if ((p->len == p->tot_len) && (p->len >= ETH_MIN_FRAME_LEN + ETH_PAD_SIZE)) {
827 /* no pbuf chain, don't have to copy -> faster */
828 buf = &((unsigned char*)p->payload)[ETH_PAD_SIZE];
829 } else {
830 /* pbuf chain, copy into contiguous buffer */
831 if (p->tot_len >= sizeof(buffer)) {
832 LINK_STATS_INC(link.lenerr);
833 LINK_STATS_INC(link.drop);
834 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
835 return ERR_BUF;
836 }
837 ptr = buffer;
838 for(q = p; q != NULL; q = q->next) {
839 /* Send the data from the pbuf to the interface, one pbuf at a
840 time. The size of the data in each pbuf is kept in the ->len
841 variable. */
842 /* send data from(q->payload, q->len); */
843 LWIP_DEBUGF(NETIF_DEBUG, ("netif: send ptr %p q->payload %p q->len %i q->next %p\n", ptr, q->payload, (int)q->len, (void*)q->next));
844 if (q == p) {
845 MEMCPY(ptr, &((char*)q->payload)[ETH_PAD_SIZE], q->len - ETH_PAD_SIZE);
846 ptr += q->len - ETH_PAD_SIZE;
847 } else {
848 MEMCPY(ptr, q->payload, q->len);
849 ptr += q->len;
850 }
851 }
852 }
853
854 if (tot_len < ETH_MIN_FRAME_LEN) {
855 /* ensure minimal frame length */
856 memset(&buf[tot_len], 0, ETH_MIN_FRAME_LEN - tot_len);
857 tot_len = ETH_MIN_FRAME_LEN;
858 }
859
860 /* signal that packet should be sent */
861 if (pcap_sendpacket(pa->adapter, buf, tot_len) < 0) {
862 LINK_STATS_INC(link.memerr);
863 LINK_STATS_INC(link.drop);
864 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
865 return ERR_BUF;
866 }
867 if (netif_is_link_up(netif)) {
868 pcapif_add_tx_packet(pa, buf, tot_len);
869 }
870
871 LINK_STATS_INC(link.xmit);
872 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, tot_len);
873 ethhdr = (struct eth_hdr *)p->payload;
874 if ((ethhdr->dest.addr[0] & 1) != 0) {
875 /* broadcast or multicast packet*/
876 MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
877 } else {
878 /* unicast packet */
879 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
880 }
881 return ERR_OK;
882 }
883
884 /** low_level_input(): Allocate a pbuf and transfer the bytes of the incoming
885 * packet from the interface into the pbuf.
886 */
887 static struct pbuf *
pcapif_low_level_input(struct netif * netif,const void * packet,int packet_len)888 pcapif_low_level_input(struct netif *netif, const void *packet, int packet_len)
889 {
890 struct pbuf *p, *q;
891 int start;
892 int length = packet_len;
893 const struct eth_addr *dest = (const struct eth_addr*)packet;
894 int unicast;
895 #if PCAPIF_FILTER_GROUP_ADDRESSES && !PCAPIF_RECEIVE_PROMISCUOUS
896 const u8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
897 const u8_t ipv4mcast[] = {0x01, 0x00, 0x5e};
898 const u8_t ipv6mcast[] = {0x33, 0x33};
899 #endif /* PCAPIF_FILTER_GROUP_ADDRESSES && !PCAPIF_RECEIVE_PROMISCUOUS */
900
901 if (pcaipf_is_tx_packet(netif, packet, packet_len)) {
902 /* don't update counters here! */
903 return NULL;
904 }
905
906 unicast = ((dest->addr[0] & 0x01) == 0);
907 #if !PCAPIF_RECEIVE_PROMISCUOUS
908 /* MAC filter: only let my MAC or non-unicast through (pcap receives loopback traffic, too) */
909 if (memcmp(dest, &netif->hwaddr, ETH_HWADDR_LEN) &&
910 #if PCAPIF_FILTER_GROUP_ADDRESSES
911 (memcmp(dest, ipv4mcast, 3) || ((dest->addr[3] & 0x80) != 0)) &&
912 memcmp(dest, ipv6mcast, 2) &&
913 memcmp(dest, bcast, 6)
914 #else /* PCAPIF_FILTER_GROUP_ADDRESSES */
915 unicast
916 #endif /* PCAPIF_FILTER_GROUP_ADDRESSES */
917 ) {
918 /* don't update counters here! */
919 return NULL;
920 }
921 #endif /* !PCAPIF_RECEIVE_PROMISCUOUS */
922
923 /* We allocate a pbuf chain of pbufs from the pool. */
924 p = pbuf_alloc(PBUF_RAW, (u16_t)length + ETH_PAD_SIZE, PBUF_POOL);
925 LWIP_DEBUGF(NETIF_DEBUG, ("netif: recv length %i p->tot_len %i\n", length, (int)p->tot_len));
926
927 if (p != NULL) {
928 /* We iterate over the pbuf chain until we have read the entire
929 packet into the pbuf. */
930 start = 0;
931 for (q = p; q != NULL; q = q->next) {
932 u16_t copy_len = q->len;
933 /* Read enough bytes to fill this pbuf in the chain. The
934 available data in the pbuf is given by the q->len
935 variable. */
936 /* read data into(q->payload, q->len); */
937 LWIP_DEBUGF(NETIF_DEBUG, ("netif: recv start %i length %i q->payload %p q->len %i q->next %p\n", start, length, q->payload, (int)q->len, (void*)q->next));
938 if (q == p) {
939 #if ETH_PAD_SIZE
940 LWIP_ASSERT("q->len >= ETH_PAD_SIZE", q->len >= ETH_PAD_SIZE);
941 copy_len -= ETH_PAD_SIZE;
942 #endif /* ETH_PAD_SIZE*/
943 MEMCPY(&((char*)q->payload)[ETH_PAD_SIZE], &((const char*)packet)[start], copy_len);
944 } else {
945 MEMCPY(q->payload, &((const char*)packet)[start], copy_len);
946 }
947 start += copy_len;
948 length -= copy_len;
949 if (length <= 0) {
950 break;
951 }
952 }
953 LINK_STATS_INC(link.recv);
954 MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len - ETH_PAD_SIZE);
955 if (unicast) {
956 MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
957 } else {
958 MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
959 }
960 } else {
961 /* drop packet */
962 LINK_STATS_INC(link.memerr);
963 LINK_STATS_INC(link.drop);
964 MIB2_STATS_NETIF_INC(netif, ifindiscards);
965 }
966
967 return p;
968 }
969
970 #if PCAPIF_RX_REF
971 static void
pcapif_rx_pbuf_free_custom(struct pbuf * p)972 pcapif_rx_pbuf_free_custom(struct pbuf *p)
973 {
974 struct pcapif_pbuf_custom* ppc;
975 LWIP_ASSERT("NULL pointer", p != NULL);
976 ppc = (struct pcapif_pbuf_custom*)p;
977 #if PCAPIF_RX_READONLY
978 LWIP_ASSERT("NULL pointer", ppc->ro_mem != NULL);
979 pcapifh_free_readonly_mem(ppc->ro_mem);
980 ppc->ro_mem = NULL;
981 #else
982 LWIP_ASSERT("NULL pointer", ppc->p != NULL);
983 pbuf_free(ppc->p);
984 ppc->p = NULL;
985 #endif
986 mem_free(p);
987 }
988
989 static struct pbuf*
pcapif_rx_ref(struct pbuf * p)990 pcapif_rx_ref(struct pbuf* p)
991 {
992 struct pcapif_pbuf_custom* ppc;
993 struct pbuf* q;
994 u16_t len;
995 void *payload_mem;
996
997 LWIP_ASSERT("NULL pointer", p != NULL);
998 LWIP_ASSERT("chained pbuf not supported here", p->next == NULL);
999
1000 ppc = (struct pcapif_pbuf_custom*)mem_malloc(sizeof(struct pcapif_pbuf_custom));
1001 LWIP_ASSERT("out of memory for RX", ppc != NULL);
1002 ppc->pc.custom_free_function = pcapif_rx_pbuf_free_custom;
1003 len = p->tot_len;
1004 #if PCAPIF_RX_READONLY
1005 payload_mem = pcapifh_alloc_readonly_copy(p->payload, len);
1006 LWIP_ASSERT("out of readonly memory for RX", payload_mem != NULL);
1007 pbuf_free(p);
1008 ppc->ro_mem = payload_mem;
1009 #else
1010 ppc->p = p;
1011 payload_mem = p->payload;
1012 #endif
1013
1014 q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &ppc->pc, payload_mem, len);
1015 LWIP_ASSERT("pbuf_alloced_custom returned NULL", q != NULL);
1016 return q;
1017 }
1018 #endif /* PCAPIF_RX_REF */
1019
1020 /** pcapif_input: This function is called when a packet is ready to be read
1021 * from the interface. It uses the function low_level_input() that should
1022 * handle the actual reception of bytes from the network interface.
1023 */
1024 static void
pcapif_input(u_char * user,const struct pcap_pkthdr * pkt_header,const u_char * packet)1025 pcapif_input(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *packet)
1026 {
1027 struct pcapif_private *pa = (struct pcapif_private*)user;
1028 int packet_len = pkt_header->caplen;
1029 struct netif *netif = (struct netif *)pa->input_fn_arg;
1030 struct pbuf *p;
1031
1032 PCAPIF_RX_LOCK_LWIP();
1033
1034 /* move received packet into a new pbuf */
1035 p = pcapif_low_level_input(netif, packet, packet_len);
1036 /* if no packet could be read, silently ignore this */
1037 if (p != NULL) {
1038 #if PCAPIF_RX_REF
1039 p = pcapif_rx_ref(p);
1040 #endif
1041 /* pass all packets to ethernet_input, which decides what packets it supports */
1042 if (netif->input(p, netif) != ERR_OK) {
1043 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
1044 pbuf_free(p);
1045 }
1046 }
1047 PCAPIF_RX_UNLOCK_LWIP();
1048 }
1049
1050 /**
1051 * pcapif_init(): initialization function, pass to netif_add().
1052 */
1053 err_t
pcapif_init(struct netif * netif)1054 pcapif_init(struct netif *netif)
1055 {
1056 static int ethernetif_index;
1057
1058 int local_index;
1059 SYS_ARCH_DECL_PROTECT(lev);
1060
1061 pcapifh_init_npcap();
1062
1063 SYS_ARCH_PROTECT(lev);
1064 local_index = ethernetif_index++;
1065 SYS_ARCH_UNPROTECT(lev);
1066
1067 LWIP_ASSERT("pcapif needs an input callback", netif->input != NULL);
1068
1069 netif->name[0] = IFNAME0;
1070 netif->name[1] = (char)(IFNAME1 + local_index);
1071 netif->linkoutput = pcapif_low_level_output;
1072 #if LWIP_IPV4
1073 #if LWIP_ARP
1074 netif->output = etharp_output;
1075 #else /* LWIP_ARP */
1076 netif->output = NULL; /* not used for PPPoE */
1077 #endif /* LWIP_ARP */
1078 #endif /* LWIP_IPV4 */
1079 #if LWIP_IPV6
1080 netif->output_ip6 = ethip6_output;
1081 #endif /* LWIP_IPV6 */
1082 #if LWIP_NETIF_HOSTNAME
1083 /* Initialize interface hostname */
1084 netif_set_hostname(netif, "lwip");
1085 #endif /* LWIP_NETIF_HOSTNAME */
1086
1087 netif->mtu = 1500;
1088 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
1089 #if LWIP_IPV6 && LWIP_IPV6_MLD
1090 netif->flags |= NETIF_FLAG_MLD6;
1091 #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
1092 netif->hwaddr_len = ETH_HWADDR_LEN;
1093
1094 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
1095
1096 /* sets link up or down based on current status */
1097 pcapif_low_level_init(netif);
1098
1099 return ERR_OK;
1100 }
1101
1102 #if !PCAPIF_RX_USE_THREAD
1103 void
pcapif_poll(struct netif * netif)1104 pcapif_poll(struct netif *netif)
1105 {
1106 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
1107
1108 int ret;
1109 do {
1110 if (pa->adapter != NULL) {
1111 ret = pcap_dispatch(pa->adapter, -1, pcapif_input, (u_char*)pa);
1112 } else {
1113 ret = -1;
1114 }
1115 if (ret < 0) {
1116 /* error (e.g. adapter removed or resume from standby), try to reopen the adapter */
1117 pcap_reopen_adapter(pa);
1118 }
1119 } while (ret > 0);
1120
1121 }
1122 #endif /* !PCAPIF_RX_USE_THREAD */
1123
1124 #endif /* LWIP_ETHERNET */
1125