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 }
683 #if PCAPIF_RX_USE_THREAD
684 /* wait for rxthread to end */
685 while (pa->rx_running) {
686 Sleep(100);
687 }
688 #endif /* PCAPIF_RX_USE_THREAD */
689 if (pa->adapter) {
690 pcap_close(pa->adapter);
691 pa->adapter = NULL;
692 }
693 #if PCAPIF_HANDLE_LINKSTATE
694 pcapifh_linkstate_close(pa->link_state);
695 #endif /* PCAPIF_HANDLE_LINKSTATE */
696 free(pa);
697 }
698 }
699
700 #if PCAPIF_RX_USE_THREAD
701 /** RX running in its own thread */
702 static void
pcapif_input_thread(void * arg)703 pcapif_input_thread(void *arg)
704 {
705 struct netif *netif = (struct netif *)arg;
706 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
707 do
708 {
709 struct pcap_pkthdr pkt_header;
710 const u_char *packet = pcap_next(pa->adapter, &pkt_header);
711 if(packet != NULL) {
712 pcapif_input((u_char*)pa, &pkt_header, packet);
713 }
714 } while (pa->rx_run);
715 pa->rx_running = 0;
716 }
717 #endif /* PCAPIF_RX_USE_THREAD */
718
719 /** Low-level initialization: find the correct adapter and initialize it.
720 */
721 static void
pcapif_low_level_init(struct netif * netif)722 pcapif_low_level_init(struct netif *netif)
723 {
724 u8_t my_mac_addr[ETH_HWADDR_LEN] = LWIP_MAC_ADDR_BASE;
725 int adapter_num = PACKET_LIB_ADAPTER_NR;
726 struct pcapif_private *pa;
727 #ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
728 ip4_addr_t netaddr;
729 #define GUID_LEN 128
730 char guid[GUID_LEN + 1];
731 #endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
732
733 /* If 'state' is != NULL at this point, we assume it is an 'int' giving
734 the index of the adapter to use (+ 1 because 0==NULL is invalid).
735 This can be used to instantiate multiple PCAP drivers. */
736 if (netif->state != NULL) {
737 adapter_num = (LWIP_PTR_NUMERIC_CAST(int, netif->state)) - 1;
738 if (adapter_num < 0) {
739 printf("ERROR: invalid adapter index \"%d\"!\n", adapter_num);
740 LWIP_ASSERT("ERROR initializing network adapter!", 0);
741 return;
742 }
743 }
744
745 #ifdef PACKET_LIB_GET_ADAPTER_NETADDRESS
746 memset(&guid, 0, sizeof(guid));
747 PACKET_LIB_GET_ADAPTER_NETADDRESS(&netaddr);
748 if (get_adapter_index_from_addr((struct in_addr *)&netaddr, guid, GUID_LEN) < 0) {
749 printf("ERROR initializing network adapter, failed to get GUID for network address %s\n", ip4addr_ntoa(&netaddr));
750 LWIP_ASSERT("ERROR initializing network adapter, failed to get GUID for network address!", 0);
751 return;
752 }
753 adapter_num = get_adapter_index(guid);
754 if (adapter_num < 0) {
755 printf("ERROR finding network adapter with GUID \"%s\"!\n", guid);
756 LWIP_ASSERT("ERROR finding network adapter with expected GUID!", 0);
757 return;
758 }
759
760 #else /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
761 #ifdef PACKET_LIB_ADAPTER_GUID
762 /* get adapter index for guid string */
763 adapter_num = get_adapter_index(PACKET_LIB_ADAPTER_GUID);
764 if (adapter_num < 0) {
765 printf("ERROR finding network adapter with GUID \"%s\"!\n", PACKET_LIB_ADAPTER_GUID);
766 LWIP_ASSERT("ERROR initializing network adapter!", 0);
767 return;
768 }
769 #endif /* PACKET_LIB_ADAPTER_GUID */
770 #endif /* PACKET_LIB_GET_ADAPTER_NETADDRESS */
771
772 /* Do whatever else is needed to initialize interface. */
773 pa = pcapif_init_adapter(adapter_num, netif);
774 if (pa == NULL) {
775 printf("ERROR initializing network adapter %d!\n", adapter_num);
776 LWIP_ASSERT("ERROR initializing network adapter!", 0);
777 return;
778 }
779 netif->state = pa;
780
781 /* change the MAC address to a unique value
782 so that multiple ethernetifs are supported */
783 /* @todo: this does NOT support multiple processes using this adapter! */
784 my_mac_addr[ETH_HWADDR_LEN - 1] += netif->num;
785 /* Copy MAC addr */
786 SMEMCPY(&netif->hwaddr, my_mac_addr, ETH_HWADDR_LEN);
787
788 /* get the initial link state of the selected interface */
789 #if PCAPIF_HANDLE_LINKSTATE
790 pa->last_link_event = pcapifh_linkstate_get(pa->link_state);
791 if (pa->last_link_event == PCAPIF_LINKEVENT_DOWN) {
792 netif_set_link_down(netif);
793 } else {
794 netif_set_link_up(netif);
795 }
796 sys_timeout(PCAPIF_LINKCHECK_INTERVAL_MS, pcapif_check_linkstate, netif);
797 #else /* PCAPIF_HANDLE_LINKSTATE */
798 /* just set the link up so that lwIP can transmit */
799 netif_set_link_up(netif);
800 #endif /* PCAPIF_HANDLE_LINKSTATE */
801
802 #if PCAPIF_RX_USE_THREAD
803 pa->rx_run = 1;
804 pa->rx_running = 1;
805 sys_thread_new("pcapif_rxthread", pcapif_input_thread, netif, 0, 0);
806 #endif
807
808 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]));
809 }
810
811 /** low_level_output():
812 * Transmit a packet. The packet is contained in the pbuf that is passed to
813 * the function. This pbuf might be chained.
814 */
815 static err_t
pcapif_low_level_output(struct netif * netif,struct pbuf * p)816 pcapif_low_level_output(struct netif *netif, struct pbuf *p)
817 {
818 struct pbuf *q;
819 unsigned char buffer[ETH_MAX_FRAME_LEN + ETH_PAD_SIZE];
820 unsigned char *buf = buffer;
821 unsigned char *ptr;
822 struct eth_hdr *ethhdr;
823 u16_t tot_len = p->tot_len - ETH_PAD_SIZE;
824 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
825
826 #if defined(LWIP_DEBUG) && LWIP_NETIF_TX_SINGLE_PBUF && !(LWIP_IPV4 && IP_FRAG) && (LWIP_IPV6 && LWIP_IPV6_FRAG)
827 LWIP_ASSERT("p->next == NULL && p->len == p->tot_len", p->next == NULL && p->len == p->tot_len);
828 #endif
829
830 /* initiate transfer */
831 if ((p->len == p->tot_len) && (p->len >= ETH_MIN_FRAME_LEN + ETH_PAD_SIZE)) {
832 /* no pbuf chain, don't have to copy -> faster */
833 buf = &((unsigned char*)p->payload)[ETH_PAD_SIZE];
834 } else {
835 /* pbuf chain, copy into contiguous buffer */
836 if (p->tot_len >= sizeof(buffer)) {
837 LINK_STATS_INC(link.lenerr);
838 LINK_STATS_INC(link.drop);
839 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
840 return ERR_BUF;
841 }
842 ptr = buffer;
843 for(q = p; q != NULL; q = q->next) {
844 /* Send the data from the pbuf to the interface, one pbuf at a
845 time. The size of the data in each pbuf is kept in the ->len
846 variable. */
847 /* send data from(q->payload, q->len); */
848 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));
849 if (q == p) {
850 MEMCPY(ptr, &((char*)q->payload)[ETH_PAD_SIZE], q->len - ETH_PAD_SIZE);
851 ptr += q->len - ETH_PAD_SIZE;
852 } else {
853 MEMCPY(ptr, q->payload, q->len);
854 ptr += q->len;
855 }
856 }
857 }
858
859 if (tot_len < ETH_MIN_FRAME_LEN) {
860 /* ensure minimal frame length */
861 memset(&buf[tot_len], 0, ETH_MIN_FRAME_LEN - tot_len);
862 tot_len = ETH_MIN_FRAME_LEN;
863 }
864
865 /* signal that packet should be sent */
866 if (pcap_sendpacket(pa->adapter, buf, tot_len) < 0) {
867 LINK_STATS_INC(link.memerr);
868 LINK_STATS_INC(link.drop);
869 MIB2_STATS_NETIF_INC(netif, ifoutdiscards);
870 return ERR_BUF;
871 }
872 if (netif_is_link_up(netif)) {
873 pcapif_add_tx_packet(pa, buf, tot_len);
874 }
875
876 LINK_STATS_INC(link.xmit);
877 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, tot_len);
878 ethhdr = (struct eth_hdr *)p->payload;
879 if ((ethhdr->dest.addr[0] & 1) != 0) {
880 /* broadcast or multicast packet*/
881 MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
882 } else {
883 /* unicast packet */
884 MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
885 }
886 return ERR_OK;
887 }
888
889 /** low_level_input(): Allocate a pbuf and transfer the bytes of the incoming
890 * packet from the interface into the pbuf.
891 */
892 static struct pbuf *
pcapif_low_level_input(struct netif * netif,const void * packet,int packet_len)893 pcapif_low_level_input(struct netif *netif, const void *packet, int packet_len)
894 {
895 struct pbuf *p, *q;
896 int start;
897 int length = packet_len;
898 const struct eth_addr *dest = (const struct eth_addr*)packet;
899 int unicast;
900 #if PCAPIF_FILTER_GROUP_ADDRESSES && !PCAPIF_RECEIVE_PROMISCUOUS
901 const u8_t bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
902 const u8_t ipv4mcast[] = {0x01, 0x00, 0x5e};
903 const u8_t ipv6mcast[] = {0x33, 0x33};
904 #endif /* PCAPIF_FILTER_GROUP_ADDRESSES && !PCAPIF_RECEIVE_PROMISCUOUS */
905
906 if (pcaipf_is_tx_packet(netif, packet, packet_len)) {
907 /* don't update counters here! */
908 return NULL;
909 }
910
911 unicast = ((dest->addr[0] & 0x01) == 0);
912 #if !PCAPIF_RECEIVE_PROMISCUOUS
913 /* MAC filter: only let my MAC or non-unicast through (pcap receives loopback traffic, too) */
914 if (memcmp(dest, &netif->hwaddr, ETH_HWADDR_LEN) &&
915 #if PCAPIF_FILTER_GROUP_ADDRESSES
916 (memcmp(dest, ipv4mcast, 3) || ((dest->addr[3] & 0x80) != 0)) &&
917 memcmp(dest, ipv6mcast, 2) &&
918 memcmp(dest, bcast, 6)
919 #else /* PCAPIF_FILTER_GROUP_ADDRESSES */
920 unicast
921 #endif /* PCAPIF_FILTER_GROUP_ADDRESSES */
922 ) {
923 /* don't update counters here! */
924 return NULL;
925 }
926 #endif /* !PCAPIF_RECEIVE_PROMISCUOUS */
927
928 /* We allocate a pbuf chain of pbufs from the pool. */
929 p = pbuf_alloc(PBUF_RAW, (u16_t)length + ETH_PAD_SIZE, PBUF_POOL);
930 LWIP_DEBUGF(NETIF_DEBUG, ("netif: recv length %i p->tot_len %i\n", length, (int)p->tot_len));
931
932 if (p != NULL) {
933 /* We iterate over the pbuf chain until we have read the entire
934 packet into the pbuf. */
935 start = 0;
936 for (q = p; q != NULL; q = q->next) {
937 u16_t copy_len = q->len;
938 /* Read enough bytes to fill this pbuf in the chain. The
939 available data in the pbuf is given by the q->len
940 variable. */
941 /* read data into(q->payload, q->len); */
942 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));
943 if (q == p) {
944 #if ETH_PAD_SIZE
945 LWIP_ASSERT("q->len >= ETH_PAD_SIZE", q->len >= ETH_PAD_SIZE);
946 copy_len -= ETH_PAD_SIZE;
947 #endif /* ETH_PAD_SIZE*/
948 MEMCPY(&((char*)q->payload)[ETH_PAD_SIZE], &((const char*)packet)[start], copy_len);
949 } else {
950 MEMCPY(q->payload, &((const char*)packet)[start], copy_len);
951 }
952 start += copy_len;
953 length -= copy_len;
954 if (length <= 0) {
955 break;
956 }
957 }
958 LINK_STATS_INC(link.recv);
959 MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len - ETH_PAD_SIZE);
960 if (unicast) {
961 MIB2_STATS_NETIF_INC(netif, ifinucastpkts);
962 } else {
963 MIB2_STATS_NETIF_INC(netif, ifinnucastpkts);
964 }
965 } else {
966 /* drop packet */
967 LINK_STATS_INC(link.memerr);
968 LINK_STATS_INC(link.drop);
969 MIB2_STATS_NETIF_INC(netif, ifindiscards);
970 }
971
972 return p;
973 }
974
975 #if PCAPIF_RX_REF
976 static void
pcapif_rx_pbuf_free_custom(struct pbuf * p)977 pcapif_rx_pbuf_free_custom(struct pbuf *p)
978 {
979 struct pcapif_pbuf_custom* ppc;
980 LWIP_ASSERT("NULL pointer", p != NULL);
981 ppc = (struct pcapif_pbuf_custom*)p;
982 #if PCAPIF_RX_READONLY
983 LWIP_ASSERT("NULL pointer", ppc->ro_mem != NULL);
984 pcapifh_free_readonly_mem(ppc->ro_mem);
985 ppc->ro_mem = NULL;
986 #else
987 LWIP_ASSERT("NULL pointer", ppc->p != NULL);
988 pbuf_free(ppc->p);
989 ppc->p = NULL;
990 #endif
991 mem_free(p);
992 }
993
994 static struct pbuf*
pcapif_rx_ref(struct pbuf * p)995 pcapif_rx_ref(struct pbuf* p)
996 {
997 struct pcapif_pbuf_custom* ppc;
998 struct pbuf* q;
999 u16_t len;
1000 void *payload_mem;
1001
1002 LWIP_ASSERT("NULL pointer", p != NULL);
1003 LWIP_ASSERT("chained pbuf not supported here", p->next == NULL);
1004
1005 ppc = (struct pcapif_pbuf_custom*)mem_malloc(sizeof(struct pcapif_pbuf_custom));
1006 LWIP_ASSERT("out of memory for RX", ppc != NULL);
1007 ppc->pc.custom_free_function = pcapif_rx_pbuf_free_custom;
1008 len = p->tot_len;
1009 #if PCAPIF_RX_READONLY
1010 payload_mem = pcapifh_alloc_readonly_copy(p->payload, len);
1011 LWIP_ASSERT("out of readonly memory for RX", payload_mem != NULL);
1012 pbuf_free(p);
1013 ppc->ro_mem = payload_mem;
1014 #else
1015 ppc->p = p;
1016 payload_mem = p->payload;
1017 #endif
1018
1019 q = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &ppc->pc, payload_mem, len);
1020 LWIP_ASSERT("pbuf_alloced_custom returned NULL", q != NULL);
1021 return q;
1022 }
1023 #endif /* PCAPIF_RX_REF */
1024
1025 /** pcapif_input: This function is called when a packet is ready to be read
1026 * from the interface. It uses the function low_level_input() that should
1027 * handle the actual reception of bytes from the network interface.
1028 */
1029 static void
pcapif_input(u_char * user,const struct pcap_pkthdr * pkt_header,const u_char * packet)1030 pcapif_input(u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *packet)
1031 {
1032 struct pcapif_private *pa = (struct pcapif_private*)user;
1033 int packet_len = pkt_header->caplen;
1034 struct netif *netif = (struct netif *)pa->input_fn_arg;
1035 struct pbuf *p;
1036
1037 PCAPIF_RX_LOCK_LWIP();
1038
1039 /* move received packet into a new pbuf */
1040 p = pcapif_low_level_input(netif, packet, packet_len);
1041 /* if no packet could be read, silently ignore this */
1042 if (p != NULL) {
1043 #if PCAPIF_RX_REF
1044 p = pcapif_rx_ref(p);
1045 #endif
1046 /* pass all packets to ethernet_input, which decides what packets it supports */
1047 if (netif->input(p, netif) != ERR_OK) {
1048 LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
1049 pbuf_free(p);
1050 }
1051 }
1052 PCAPIF_RX_UNLOCK_LWIP();
1053 }
1054
1055 /**
1056 * pcapif_init(): initialization function, pass to netif_add().
1057 */
1058 err_t
pcapif_init(struct netif * netif)1059 pcapif_init(struct netif *netif)
1060 {
1061 static int ethernetif_index;
1062
1063 int local_index;
1064 SYS_ARCH_DECL_PROTECT(lev);
1065
1066 pcapifh_init_npcap();
1067
1068 SYS_ARCH_PROTECT(lev);
1069 local_index = ethernetif_index++;
1070 SYS_ARCH_UNPROTECT(lev);
1071
1072 LWIP_ASSERT("pcapif needs an input callback", netif->input != NULL);
1073
1074 netif->name[0] = IFNAME0;
1075 netif->name[1] = (char)(IFNAME1 + local_index);
1076 netif->linkoutput = pcapif_low_level_output;
1077 #if LWIP_IPV4
1078 #if LWIP_ARP
1079 netif->output = etharp_output;
1080 #else /* LWIP_ARP */
1081 netif->output = NULL; /* not used for PPPoE */
1082 #endif /* LWIP_ARP */
1083 #endif /* LWIP_IPV4 */
1084 #if LWIP_IPV6
1085 netif->output_ip6 = ethip6_output;
1086 #endif /* LWIP_IPV6 */
1087 #if LWIP_NETIF_HOSTNAME
1088 /* Initialize interface hostname */
1089 netif_set_hostname(netif, "lwip");
1090 #endif /* LWIP_NETIF_HOSTNAME */
1091
1092 netif->mtu = 1500;
1093 netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP;
1094 #if LWIP_IPV6 && LWIP_IPV6_MLD
1095 netif->flags |= NETIF_FLAG_MLD6;
1096 #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
1097 netif->hwaddr_len = ETH_HWADDR_LEN;
1098
1099 NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 100000000);
1100
1101 /* sets link up or down based on current status */
1102 pcapif_low_level_init(netif);
1103
1104 return ERR_OK;
1105 }
1106
1107 #if !PCAPIF_RX_USE_THREAD
1108 void
pcapif_poll(struct netif * netif)1109 pcapif_poll(struct netif *netif)
1110 {
1111 struct pcapif_private *pa = (struct pcapif_private*)PCAPIF_GET_STATE_PTR(netif);
1112
1113 int ret;
1114 do {
1115 if (pa->adapter != NULL) {
1116 ret = pcap_dispatch(pa->adapter, -1, pcapif_input, (u_char*)pa);
1117 } else {
1118 ret = -1;
1119 }
1120 if (ret < 0) {
1121 /* error (e.g. adapter removed or resume from standby), try to reopen the adapter */
1122 pcap_reopen_adapter(pa);
1123 }
1124 } while (ret > 0);
1125
1126 }
1127 #endif /* !PCAPIF_RX_USE_THREAD */
1128
1129 #endif /* LWIP_ETHERNET */
1130