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