1 /*
2     portable interface to "raw sockets"
3 
4     This uses both "libpcap" on systems, but on Linux, we try to use the
5     basic raw sockets, bypassing libpcap for better performance.
6 */
7 #include "rawsock.h"
8 #include "templ-pkt.h"
9 #include "logger.h"
10 #include "main-ptrace.h"
11 #include "string_s.h"
12 #include "stub-pcap.h"
13 #include "stub-pfring.h"
14 #include "pixie-timer.h"
15 #include "main-globals.h"
16 #include "proto-preprocess.h"
17 #include "stack-arpv4.h"
18 #include "stack-ndpv6.h"
19 
20 #include "unusedparm.h"
21 #include "util-malloc.h"
22 #include <assert.h>
23 #include <ctype.h>
24 
25 static int is_pcap_file = 0;
26 
27 #ifdef WIN32
28 #include <winsock.h>
29 #include <iphlpapi.h>
30 
31 #if defined(_MSC_VER)
32 #pragma comment(lib, "IPHLPAPI.lib")
33 #endif
34 
35 #elif defined(__GNUC__)
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <sys/socket.h>
39 #include <sys/ioctl.h>
40 #include <netinet/in.h>
41 #include <net/if.h>
42 #include <arpa/inet.h>
43 
44 #else
45 #endif
46 
47 #include "rawsock-adapter.h"
48 
49 #define SENDQ_SIZE 65536 * 8
50 
51 
52 struct AdapterNames
53 {
54     char *easy_name;
55     char *hard_name;
56 };
57 
58 struct AdapterNames adapter_names[64];
59 unsigned adapter_name_count = 0;
60 
61 /***************************************************************************
62  ***************************************************************************/
63 #ifdef WIN32
pcap_setdirection(pcap_t * pcap,pcap_direction_t direction)64 int pcap_setdirection(pcap_t *pcap, pcap_direction_t direction)
65 {
66     static int (*real_setdirection)(pcap_t *, pcap_direction_t) = 0;
67 
68     if (real_setdirection == 0) {
69         void* h = LoadLibraryA("wpcap.dll");
70         if (h == NULL) {
71             fprintf(stderr, "couldn't load wpcap.dll: %u\n",
72                                 (unsigned)GetLastError());
73             return -1;
74         }
75 
76         real_setdirection = (int (*)(pcap_t*,pcap_direction_t))
77                             GetProcAddress(h, "pcap_setdirection");
78         if (real_setdirection == 0) {
79             fprintf(stderr, "couldn't find pcap_setdirection(): %u\n",
80                                 (unsigned)GetLastError());
81             return -1;
82         }
83     }
84 
85     return real_setdirection(pcap, direction);
86 }
87 #endif
88 
89 /***************************************************************************
90  ***************************************************************************/
91 void
rawsock_init(void)92 rawsock_init(void)
93 {
94 #ifdef WIN32
95     /* Declare and initialize variables */
96 
97 // It is possible for an adapter to have multiple
98 // IPv4 addresses, gateways, and secondary WINS servers
99 // assigned to the adapter.
100 //
101 // Note that this sample code only prints out the
102 // first entry for the IP address/mask, and gateway, and
103 // the primary and secondary WINS server for each adapter.
104 
105     PIP_ADAPTER_INFO pAdapterInfo;
106     PIP_ADAPTER_INFO pAdapter = NULL;
107     DWORD dwRetVal = 0;
108     UINT i;
109 
110 /* variables used to print DHCP time info */
111     //struct tm newtime;
112     //char buffer[32];
113     //errno_t error;
114 
115     ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
116     pAdapterInfo = (IP_ADAPTER_INFO *) malloc(sizeof (IP_ADAPTER_INFO));
117     if (pAdapterInfo == NULL) {
118         printf("Error allocating memory needed to call GetAdaptersinfo\n");
119         return;
120     }
121 // Make an initial call to GetAdaptersInfo to get
122 // the necessary size into the ulOutBufLen variable
123     if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
124         free(pAdapterInfo);
125         pAdapterInfo = (IP_ADAPTER_INFO *) malloc(ulOutBufLen);
126         if (pAdapterInfo == NULL) {
127             printf("Error allocating memory needed to call GetAdaptersinfo\n");
128             return;
129         }
130     }
131 
132     if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
133         for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
134             if (pAdapter->Type != MIB_IF_TYPE_ETHERNET)
135                 continue;
136 
137             //printf("\tComboIndex: \t%d\n", pAdapter->ComboIndex);
138             //printf("\tAdapter Name: \t%s\n", pAdapter->AdapterName);
139             {
140                 size_t name_len = strlen(pAdapter->AdapterName) + 12 + 1;
141                 char *name = (char*)malloc(name_len);
142                 size_t addr_len = pAdapter->AddressLength * 3 + 1;
143                 char *addr = (char*)malloc(addr_len);
144 
145                 if (name == NULL || addr == NULL)
146                     exit(1);
147 
148                 sprintf_s(name, name_len, "\\Device\\NPF_%s", pAdapter->AdapterName);
149 
150                 //printf("\tAdapter Desc: \t%s\n", pAdapter->Description);
151                 //printf("\tAdapter Addr: \t");
152                 for (i = 0; i < pAdapter->AddressLength; i++) {
153                     if (i == (pAdapter->AddressLength - 1))
154                         sprintf_s(addr+i*3, addr_len-i*3, "%.2X", pAdapter->Address[i]);
155                     else
156                         sprintf_s(addr+i*3, addr_len-i*3, "%.2X-", pAdapter->Address[i]);
157                 }
158                 //printf("%s  ->  %s\n", addr, name);
159                 adapter_names[adapter_name_count].easy_name = addr;
160                 adapter_names[adapter_name_count].hard_name = name;
161                 adapter_name_count++;
162             }
163 
164             //printf("\tIndex: \t%d\n", pAdapter->Index);
165 
166             {
167                 size_t name_len = strlen(pAdapter->AdapterName) + 12 + 1;
168                 char *name = (char*)malloc(name_len);
169                 size_t addr_len = strlen(pAdapter->IpAddressList.IpAddress.String) + 1;
170                 char *addr = (char*)malloc(addr_len);
171                 if (name == NULL || addr == NULL)
172                     exit(1);
173                 sprintf_s(name, name_len, "\\Device\\NPF_%s", pAdapter->AdapterName);
174                 sprintf_s(addr, addr_len, "%s", pAdapter->IpAddressList.IpAddress.String);
175                 //printf("%s  ->  %s\n", addr, name);
176                 adapter_names[adapter_name_count].easy_name = addr;
177                 adapter_names[adapter_name_count].hard_name = name;
178                 adapter_name_count++;
179             }
180 
181         }
182     } else {
183         printf("GetAdaptersInfo failed with error: %u\n",
184                                                     (unsigned)dwRetVal);
185 
186     }
187     if (pAdapterInfo)
188         free(pAdapterInfo);
189 #else
190     PFRING_init();
191 #endif
192     return;
193 }
194 
195 /***************************************************************************
196   * This function prints to the command line a list of all the network
197   * intefaces/devices.
198  ***************************************************************************/
199 void
rawsock_list_adapters(void)200 rawsock_list_adapters(void)
201 {
202     pcap_if_t *alldevs;
203     char errbuf[PCAP_ERRBUF_SIZE];
204 
205     if (PCAP.findalldevs(&alldevs, errbuf) != -1) {
206         int i;
207         const pcap_if_t *d;
208         i=0;
209 
210         if (alldevs == NULL) {
211             fprintf(stderr, "ERR:libpcap: no adapters found, are you sure you are root?\n");
212         }
213         /* Print the list */
214         for(d=alldevs; d; d=PCAP.dev_next(d)) {
215             fprintf(stderr, " %d  %s \t", i++, PCAP.dev_name(d));
216             if (PCAP.dev_description(d))
217                 fprintf(stderr, "(%s)\n", PCAP.dev_description(d));
218             else
219                 fprintf(stderr, "(No description available)\n");
220         }
221         fprintf(stderr,"\n");
222         PCAP.freealldevs(alldevs);
223     } else {
224         fprintf(stderr, "%s\n", errbuf);
225     }
226 }
227 
228 /***************************************************************************
229  ***************************************************************************/
230 static const char *
adapter_from_index(unsigned index)231 adapter_from_index(unsigned index)
232 {
233     pcap_if_t *alldevs;
234     char errbuf[PCAP_ERRBUF_SIZE];
235     int x;
236 
237     x = PCAP.findalldevs(&alldevs, errbuf);
238     if (x != -1) {
239         const pcap_if_t *d;
240 
241         if (alldevs == NULL) {
242             fprintf(stderr, "ERR:libpcap: no adapters found, are you sure you are root?\n");
243         }
244         /* Print the list */
245         for(d=alldevs; d; d=PCAP.dev_next(d)) {
246             if (index-- == 0)
247                 return PCAP.dev_name(d);
248         }
249         return 0;
250     } else {
251         return 0;
252     }
253 }
254 
255 /***************************************************************************
256  * Some methods of transmit queue multiple packets in a buffer then
257  * send all queued packets at once. At the end of a scan, we might have
258  * some pending packets that haven't been transmitted yet. Therefore,
259  * we'll have to flush them.
260  ***************************************************************************/
261 void
rawsock_flush(struct Adapter * adapter)262 rawsock_flush(struct Adapter *adapter)
263 {
264     if (adapter->sendq) {
265         PCAP.sendqueue_transmit(adapter->pcap, adapter->sendq, 0);
266 
267         /* Dude, I totally forget why this step is necessary. I vaguely
268          * remember there's a good reason for it though */
269         PCAP.sendqueue_destroy(adapter->sendq);
270         adapter->sendq =  PCAP.sendqueue_alloc(SENDQ_SIZE);
271     }
272 
273 }
274 
275 /***************************************************************************
276  * wrapper for libpcap's sendpacket
277  *
278  * PORTABILITY: WINDOWS and PF_RING
279  * For performance, Windows and PF_RING can queue up multiple packets, then
280  * transmit them all in a chunk. If we stop and wait for a bit, we need
281  * to flush the queue to force packets to be transmitted immediately.
282  ***************************************************************************/
283 int
rawsock_send_packet(struct Adapter * adapter,const unsigned char * packet,unsigned length,unsigned flush)284 rawsock_send_packet(
285     struct Adapter *adapter,
286     const unsigned char *packet,
287     unsigned length,
288     unsigned flush)
289 {
290 
291     /* Why: this happens in "offline mode", when we are benchmarking the
292      * core algorithms without sending packets. */
293     if (adapter == 0)
294         return 0;
295 
296     /* Print --packet-trace if debugging */
297     if (adapter->is_packet_trace) {
298         packet_trace(stdout, adapter->pt_start, packet, length, 1);
299     }
300 
301     /* PF_RING */
302     if (adapter->ring) {
303         int err = PF_RING_ERROR_NO_TX_SLOT_AVAILABLE;
304 
305         while (err == PF_RING_ERROR_NO_TX_SLOT_AVAILABLE) {
306             err = PFRING.send(adapter->ring, packet, length, (unsigned char)flush);
307         }
308         if (err < 0)
309             LOG(1, "pfring:xmit: ERROR %d\n", err);
310         return err;
311     }
312 
313     /* WINDOWS PCAP */
314     if (adapter->sendq) {
315         int err;
316         struct pcap_pkthdr hdr;
317         hdr.len = length;
318         hdr.caplen = length;
319 
320         err = PCAP.sendqueue_queue(adapter->sendq, &hdr, packet);
321         if (err) {
322             rawsock_flush(adapter);
323             PCAP.sendqueue_queue(adapter->sendq, &hdr, packet);
324         }
325 
326         if (flush) {
327             rawsock_flush(adapter);
328         }
329 
330         return 0;
331     }
332 
333     /* LIBPCAP */
334     if (adapter->pcap)
335         return PCAP.sendpacket(adapter->pcap, packet, length);
336 
337     return 0;
338 }
339 
340 
341 /***************************************************************************
342  ***************************************************************************/
rawsock_recv_packet(struct Adapter * adapter,unsigned * length,unsigned * secs,unsigned * usecs,const unsigned char ** packet)343 int rawsock_recv_packet(
344     struct Adapter *adapter,
345     unsigned *length,
346     unsigned *secs,
347     unsigned *usecs,
348     const unsigned char **packet)
349 {
350 
351     if (adapter->ring) {
352         /* This is for doing libpfring instead of libpcap */
353         struct pfring_pkthdr hdr;
354         int err;
355 
356         again:
357         err = PFRING.recv(adapter->ring,
358                         (unsigned char**)packet,
359                         0,  /* zero-copy */
360                         &hdr,
361                         0   /* return immediately */
362                         );
363         if (err == PF_RING_ERROR_NO_PKT_AVAILABLE || hdr.caplen == 0) {
364             PFRING.poll(adapter->ring, 1);
365             if (is_tx_done)
366                 return 1;
367             goto again;
368         }
369         if (err)
370             return 1;
371 
372         *length = hdr.caplen;
373         *secs = (unsigned)hdr.ts.tv_sec;
374         *usecs = (unsigned)hdr.ts.tv_usec;
375 
376     } else if (adapter->pcap) {
377         struct pcap_pkthdr hdr;
378 
379         *packet = PCAP.next(adapter->pcap, &hdr);
380 
381         if (*packet == NULL) {
382             if (is_pcap_file) {
383                 //pixie_time_set_offset(10*100000);
384                 is_tx_done = 1;
385                 is_rx_done = 1;
386             }
387             return 1;
388         }
389 
390         *length = hdr.caplen;
391         *secs = (unsigned)hdr.ts.tv_sec;
392         *usecs = (unsigned)hdr.ts.tv_usec;
393     }
394 
395 
396     return 0;
397 }
398 
399 
400 /***************************************************************************
401  * Sends the TCP SYN probe packet.
402  *
403  * Step 1: format the packet
404  * Step 2: send it in a portable manner
405  ***************************************************************************/
406 void
rawsock_send_probe_ipv4(struct Adapter * adapter,ipv4address ip_them,unsigned port_them,ipv4address ip_me,unsigned port_me,unsigned seqno,unsigned flush,struct TemplateSet * tmplset)407 rawsock_send_probe_ipv4(
408     struct Adapter *adapter,
409     ipv4address ip_them, unsigned port_them,
410     ipv4address ip_me, unsigned port_me,
411     unsigned seqno, unsigned flush,
412     struct TemplateSet *tmplset)
413 {
414     unsigned char px[2048];
415     size_t packet_length;
416 
417     /*
418      * Construct the destination packet
419      */
420     template_set_target_ipv4(tmplset, ip_them, port_them, ip_me, port_me, seqno,
421         px, sizeof(px), &packet_length);
422 
423     /*
424      * Send it
425      */
426     rawsock_send_packet(adapter, px, (unsigned)packet_length, flush);
427 }
428 
429 void
rawsock_send_probe_ipv6(struct Adapter * adapter,ipv6address ip_them,unsigned port_them,ipv6address ip_me,unsigned port_me,unsigned seqno,unsigned flush,struct TemplateSet * tmplset)430 rawsock_send_probe_ipv6(
431     struct Adapter *adapter,
432     ipv6address ip_them, unsigned port_them,
433     ipv6address ip_me, unsigned port_me,
434     unsigned seqno, unsigned flush,
435     struct TemplateSet *tmplset)
436 {
437     unsigned char px[2048];
438     size_t packet_length;
439 
440     /*
441      * Construct the destination packet
442      */
443     template_set_target_ipv6(tmplset, ip_them, port_them, ip_me, port_me, seqno,
444         px, sizeof(px), &packet_length);
445 
446     /*
447      * Send it
448      */
449     rawsock_send_packet(adapter, px, (unsigned)packet_length, flush);
450 }
451 
452 /***************************************************************************
453  * Used on Windows: network adapters have horrible names, so therefore we
454  * use numeric indexes instead. You can which adapter you are looking for
455  * by typing "--iflist" as an option.
456  ***************************************************************************/
457 static int
is_numeric_index(const char * ifname)458 is_numeric_index(const char *ifname)
459 {
460     int result = 1;
461     int i;
462 
463     /* emptry strings aren't numbers */
464     if (ifname[0] == '\0')
465         return 0;
466 
467     /* 'true' if all digits */
468     for (i=0; ifname[i]; i++) {
469         char c = ifname[i];
470 
471         if (c < '0' || '9' < c)
472             result = 0;
473     }
474 
475     return result;
476 }
477 
478 
479 /***************************************************************************
480  * Used on Windows: if the adpter name is a numeric index, convert it to
481  * the full name.
482  ***************************************************************************/
483 const char *
rawsock_win_name(const char * ifname)484 rawsock_win_name(const char *ifname)
485 {
486     if (is_numeric_index(ifname)) {
487         const char *new_adapter_name;
488 
489         new_adapter_name = adapter_from_index(atoi(ifname));
490         if (new_adapter_name)
491             return new_adapter_name;
492     }
493 
494     return ifname;
495 }
496 
497 
498 /***************************************************************************
499  * Configure the socket to not capture transmitted packets. This is needed
500  * because we transmit packets at a rate of millions per second, which will
501  * overwhelm the receive thread.
502  *
503  * PORTABILITY: Windows doesn't seem to support this feature, so instead
504  * what we do is apply a BPF filter to ignore the transmits, so that they
505  * still get filtered at a low level.
506  ***************************************************************************/
507 void
rawsock_ignore_transmits(struct Adapter * adapter,const char * ifname)508 rawsock_ignore_transmits(struct Adapter *adapter, const char *ifname)
509 {
510     if (adapter->ring) {
511         /* PORTABILITY: don't do anything for PF_RING, because it's
512          * actually done when we create the adapter, because we can't
513          * reconfigure the adapter after it's been activated. */
514         return;
515     }
516 
517     if (adapter->pcap) {
518         int err;
519         err = PCAP.setdirection(adapter->pcap, PCAP_D_IN);
520         if (err) {
521             ; //PCAP.perror(adapter->pcap, "if: pcap_setdirection(IN)");
522         } else {
523             LOG(2, "if:%s: not receiving transmits\n", ifname);
524         }
525     }
526 }
527 
528 /***************************************************************************
529  ***************************************************************************/
530 static void
rawsock_close_adapter(struct Adapter * adapter)531 rawsock_close_adapter(struct Adapter *adapter)
532 {
533     if (adapter->ring) {
534         PFRING.close(adapter->ring);
535     }
536     if (adapter->pcap) {
537         PCAP.close(adapter->pcap);
538     }
539     if (adapter->sendq) {
540         PCAP.sendqueue_destroy(adapter->sendq);
541     }
542 
543     free(adapter);
544 }
545 
546 /***************************************************************************
547  * Does the name look like a PF_RING DNA adapter? Common names are:
548  * dna0
549  * dna1
550  * dna0@1
551  *
552  ***************************************************************************/
553 static int
is_pfring_dna(const char * name)554 is_pfring_dna(const char *name)
555 {
556     if (strlen(name) < 4)
557         return 0;
558     if (memcmp(name, "zc:", 3) == 0)
559         return 1;
560     if (memcmp(name, "dna", 3) != 0)
561         return 0;
562 
563     name +=3;
564 
565     if (!isdigit(name[0]&0xFF))
566         return 0;
567     while (isdigit(name[0]&0xFF))
568         name++;
569 
570     if (name[0] == '\0')
571         return 1;
572 
573     if (name[0] != '@')
574         return 0;
575     else
576         name++;
577 
578     if (!isdigit(name[0]&0xFF))
579         return 0;
580     while (isdigit(name[0]&0xFF))
581         name++;
582 
583     if (name[0] == '\0')
584         return 1;
585     else
586         return 0;
587 }
588 
589 
590 
591 /***************************************************************************
592  ***************************************************************************/
593 struct Adapter *
rawsock_init_adapter(const char * adapter_name,unsigned is_pfring,unsigned is_sendq,unsigned is_packet_trace,unsigned is_offline,const char * bpf_filter,unsigned is_vlan,unsigned vlan_id)594 rawsock_init_adapter(const char *adapter_name,
595                      unsigned is_pfring,
596                      unsigned is_sendq,
597                      unsigned is_packet_trace,
598                      unsigned is_offline,
599                      const char *bpf_filter,
600                      unsigned is_vlan,
601                      unsigned vlan_id)
602 {
603     struct Adapter *adapter;
604     char errbuf[PCAP_ERRBUF_SIZE] = "pcap";
605 
606     /* BPF filter not supported on some platforms, so ignore this compiler
607      * warning when unused */
608     UNUSEDPARM(bpf_filter);
609 
610     adapter = CALLOC(1, sizeof(*adapter));
611     adapter->is_packet_trace = is_packet_trace;
612     adapter->pt_start = 1.0 * pixie_gettime() / 1000000.0;
613 
614     adapter->is_vlan = is_vlan;
615     adapter->vlan_id = vlan_id;
616 
617     if (is_offline)
618         return adapter;
619 
620     /*----------------------------------------------------------------
621      * PORTABILITY: WINDOWS
622      * If is all digits index, then look in indexed list
623      *----------------------------------------------------------------*/
624     if (is_numeric_index(adapter_name)) {
625         const char *new_adapter_name;
626 
627         new_adapter_name = adapter_from_index(atoi(adapter_name));
628         if (new_adapter_name == 0) {
629             fprintf(stderr, "pcap_open_live(%s) error: bad index\n",
630                     adapter_name);
631             return 0;
632         } else
633             adapter_name = new_adapter_name;
634     }
635 
636     /*----------------------------------------------------------------
637      * PORTABILITY: PF_RING
638      *  If we've been told to use --pfring, then attempt to open the
639      *  network adapter usign the PF_RING API rather than libpcap.
640      *  Since a lot of things can go wrong, we do a lot of extra
641      *  logging here.
642      *----------------------------------------------------------------*/
643     if(is_pfring && !is_pfring_dna(adapter_name)){ /*First ensure pfring dna adapter is available*/
644         fprintf(stderr,"No pfring adapter available. Please install pfring or run masscan without the --pfring option.\n");
645         return 0;
646     }
647 
648     if (is_pfring_dna(adapter_name)) {
649         int err;
650         unsigned version;
651 
652         /*
653          * Open
654          *
655          * TODO: Do we need the PF_RING_REENTRANT flag? We only have one
656          * transmit and one receive thread, so I don't think we need it.
657          * Also, this reduces performance in half, from 12-mpps to
658          * 6-mpps.
659          * NOTE: I don't think it needs the "re-entrant" flag, because it
660          * transmit and receive are separate functions?
661          */
662         LOG(2, "pfring:'%s': opening...\n", adapter_name);
663         adapter->ring = PFRING.open(adapter_name, 1500, 0);//PF_RING_REENTRANT);
664         adapter->pcap = (pcap_t*)adapter->ring;
665         adapter->link_type = 1;
666         if (adapter->ring == NULL) {
667             LOG(0, "pfring:'%s': OPEN ERROR: %s\n",
668                 adapter_name, strerror_x(errno));
669             return 0;
670         } else
671             LOG(1, "pfring:'%s': successfully opened\n", adapter_name);
672 
673         /*
674          * Housekeeping
675          */
676         PFRING.set_application_name(adapter->ring, "masscan");
677         PFRING.version(adapter->ring, &version);
678         LOG(1, "pfring: version %d.%d.%d\n",
679                 (version >> 16) & 0xFFFF,
680                 (version >> 8) & 0xFF,
681                 (version >> 0) & 0xFF);
682 
683         LOG(2, "pfring:'%s': setting direction\n", adapter_name);
684         err = PFRING.set_direction(adapter->ring, rx_only_direction);
685         if (err) {
686             fprintf(stderr, "pfring:'%s': setdirection = %d\n",
687                     adapter_name, err);
688         } else
689             LOG(2, "pfring:'%s': direction success\n", adapter_name);
690 
691         /*
692          * Activate
693          *
694          * PF_RING requires a separate activation step.
695          */
696         LOG(2, "pfring:'%s': activating\n", adapter_name);
697         err = PFRING.enable_ring(adapter->ring);
698         if (err != 0) {
699                 LOG(0, "pfring: '%s': ENABLE ERROR: %s\n",
700                     adapter_name, strerror_x(errno));
701                 PFRING.close(adapter->ring);
702                 adapter->ring = 0;
703                 return 0;
704         } else
705             LOG(1, "pfring:'%s': successfully enabled\n", adapter_name);
706 
707         return adapter;
708     }
709 
710     /*----------------------------------------------------------------
711      * Kludge: for using files
712      *----------------------------------------------------------------*/
713     if (memcmp(adapter_name, "file:", 5) == 0) {
714         LOG(1, "pcap: file: %s\n", adapter_name+5);
715         is_pcap_file = 1;
716 
717         adapter->pcap = PCAP.open_offline(adapter_name+5, errbuf);
718         adapter->link_type = PCAP.datalink(adapter->pcap);
719     }
720     /*----------------------------------------------------------------
721      * PORTABILITY: LIBPCAP
722      *
723      * This is the standard that should work everywhere.
724      *----------------------------------------------------------------*/
725     {
726         int err;
727         LOG(1, "[+] if(%s): pcap: %s\n", adapter_name, PCAP.lib_version());
728         LOG(2, "[+] if(%s): opening...\n", adapter_name);
729 
730         /* This reserves resources, but doesn't actually open the
731          * adapter until we call pcap_activate */
732         adapter->pcap = PCAP.create(adapter_name, errbuf);
733         if (adapter->pcap == NULL) {
734             adapter->pcap = PCAP.open_live(
735                         adapter_name,           /* interface name */
736                         65536,                  /* max packet size */
737                         8,                      /* promiscuous mode */
738                         1000,                   /* read timeout in milliseconds */
739                         errbuf);
740             if (adapter->pcap == NULL) {
741                 LOG(0, "FAIL:%s: can't open adapter: %s\n", adapter_name, errbuf);
742                 if (strstr(errbuf, "perm")) {
743                     LOG(0, "FAIL: permission denied\n");
744                     LOG(0, " [hint] need to sudo or run as root or something\n");
745                 }
746                 return 0;
747             }
748         } else {
749             err = PCAP.set_snaplen(adapter->pcap, 65536);
750             if (err) {
751                 PCAP.perror(adapter->pcap, "if: set_snaplen");
752                 goto pcap_error;
753             }
754 
755             err = PCAP.set_promisc(adapter->pcap, 8);
756             if (err) {
757                 PCAP.perror(adapter->pcap, "if: set_promisc");
758                 goto pcap_error;
759             }
760 
761             err = PCAP.set_timeout(adapter->pcap, 1000);
762             if (err) {
763                 PCAP.perror(adapter->pcap, "if: set_timeout");
764                 goto pcap_error;
765             }
766 
767             err = PCAP.set_immediate_mode(adapter->pcap, 1);
768             if (err) {
769                 PCAP.perror(adapter->pcap, "if: set_immediate_mode");
770                 goto pcap_error;
771             }
772 
773             /* If errors happen, they aren't likely to happen above, but will
774              * happen where when they are applied */
775             err = PCAP.activate(adapter->pcap);
776             switch (err) {
777             case 0:
778                 /* drop down below */
779                 break;
780             case PCAP_ERROR_PERM_DENIED:
781                 LOG(0, "[-] FAIL: permission denied\n");
782                 LOG(0, "    [hint] need to sudo or run as root or something\n");
783                 goto pcap_error;
784             default:
785 	            LOG(0, "[-] if(%s): activate:%d: %s\n", adapter_name, err, PCAP.geterr(adapter->pcap));
786                 if (err < 0)
787                     goto pcap_error;
788             }
789         }
790 
791         LOG(1, "[+] if(%s): successfully opened\n", adapter_name);
792 
793 
794 
795         /* Figure out the link-type. We suport Ethernet and IP */
796         adapter->link_type = PCAP.datalink(adapter->pcap);
797         switch (adapter->link_type) {
798             case -1:
799                 PCAP.perror(adapter->pcap, "if: datalink");
800                 goto pcap_error;
801             case 0: /* Null/Loopback [VPN tunnel] */
802                 LOG(1, "[+] if(%s): VPN tunnel interface found\n", adapter_name);
803                 break;
804             case 1: /* Ethernet */
805             case 12: /* IP Raw */
806                 break;
807             default:
808                 LOG(0, "[-] if(%s): unknown data link type: %u(%s)\n",
809                         adapter_name,
810                         adapter->link_type,
811                         PCAP.datalink_val_to_name(adapter->link_type));
812                 break;
813         }
814 
815     }
816 
817     /*----------------------------------------------------------------
818      * PORTABILITY: WINDOWS
819      *
820      * The transmit rate on Windows is really slow, like 40-kpps.
821      * The speed can be increased by using the "sendqueue" feature
822      * to roughly 300-kpps.
823      *----------------------------------------------------------------*/
824     adapter->sendq = 0;
825 #if defined(WIN32)
826     if (is_sendq)
827         adapter->sendq = PCAP.sendqueue_alloc(SENDQ_SIZE);
828 #endif
829 
830 
831     return adapter;
832 pcap_error:
833     if (adapter->pcap) {
834         PCAP.close(adapter->pcap);
835         adapter->pcap = NULL;
836     }
837     if (adapter->pcap == NULL) {
838         if (strcmp(adapter_name, "vmnet1") == 0) {
839             LOG(0, " [hint] VMware on Macintosh doesn't support masscan\n");
840         }
841         return 0;
842     }
843 
844     return NULL;
845 }
846 
847 
848 
849 /***************************************************************************
850  * for testing when two Windows adapters have the same name. Sometimes
851  * the \Device\NPF_ string is prepended, sometimes not.
852  ***************************************************************************/
853 int
rawsock_is_adapter_names_equal(const char * lhs,const char * rhs)854 rawsock_is_adapter_names_equal(const char *lhs, const char *rhs)
855 {
856     if (memcmp(lhs, "\\Device\\NPF_", 12) == 0)
857         lhs += 12;
858     if (memcmp(rhs, "\\Device\\NPF_", 12) == 0)
859         rhs += 12;
860     return strcmp(lhs, rhs) == 0;
861 }
862 
863 
864 /***************************************************************************
865  * Runs some tests when the "--debug if" option is given on the
866  * command-line. This is useful to figure out why the interface you
867  * are accessing doesn't work.
868  ***************************************************************************/
869 int
rawsock_selftest_if(const char * ifname)870 rawsock_selftest_if(const char *ifname)
871 {
872     int err;
873     ipv4address_t ipv4 = 0;
874     ipv6address_t ipv6;
875     ipv4address_t router_ipv4 = 0;
876     macaddress_t source_mac = {{0,0,0,0,0,0}};
877     struct Adapter *adapter;
878     char ifname2[246];
879     ipaddress_formatted_t fmt;
880 
881     /*
882      * Get the interface
883      */
884     if (ifname == NULL || ifname[0] == 0) {
885         err = rawsock_get_default_interface(ifname2, sizeof(ifname2));
886         if (err) {
887             printf("[-] if = not found (err=%d)\n", err);
888             return -1;
889         }
890         ifname = ifname2;
891     }
892     printf("[+] if = %s\n", ifname);
893 
894     /*
895      * Initialize the adapter.
896      */
897     adapter = rawsock_init_adapter(ifname, 0, 0, 0, 0, 0, 0, 0);
898     if (adapter == 0) {
899         printf("[-] pcap = failed\n");
900         return -1;
901     } else {
902         printf("[+] pcap = opened\n");
903     }
904 
905     /* IPv4 address */
906     ipv4 = rawsock_get_adapter_ip(ifname);
907     if (ipv4 == 0) {
908         printf("[-] source-ipv4 = not found (err)\n");
909     } else {
910         fmt = ipv4address_fmt(ipv4);
911         printf("[+] source-ipv4 = %s\n", fmt.string);
912     }
913 
914     /* IPv6 address */
915     ipv6 = rawsock_get_adapter_ipv6(ifname);
916     if (ipv6address_is_zero(ipv6)) {
917         printf("[-] source-ipv6 = not found\n");
918     } else {
919         fmt = ipv6address_fmt(ipv6);
920         printf("[+] source-ipv6 = [%s]\n", fmt.string);
921     }
922 
923     /* MAC address */
924     err = rawsock_get_adapter_mac(ifname, source_mac.addr);
925     if (err) {
926         printf("[-] source-mac = not found (err=%d)\n", err);
927     } else {
928         fmt = macaddress_fmt(source_mac);
929         printf("[+] source-mac = %s\n", fmt.string);
930     }
931 
932     switch (adapter->link_type) {
933     case 0:
934             printf("[+] router-ip = implicit\n");
935             printf("[+] router-mac = implicit\n");
936             break;
937     default:
938         /* IPv4 router IP address */
939         err = rawsock_get_default_gateway(ifname, &router_ipv4);
940         if (err) {
941             fprintf(stderr, "[-] router-ip = not found(err=%d)\n", err);
942         } else {
943             fmt = ipv4address_fmt(router_ipv4);
944             printf("[+] router-ip = %s\n", fmt.string);
945         }
946 
947         /* IPv4 router MAC address */
948         {
949             macaddress_t router_mac = {{0,0,0,0,0,0}};
950 
951             stack_arp_resolve(
952                     adapter,
953                     ipv4,
954                     source_mac,
955                     router_ipv4,
956                     &router_mac);
957 
958             if (macaddress_is_zero(router_mac)) {
959                 printf("[-] router-mac-ipv4 = not found\n");
960             } else {
961                 fmt = macaddress_fmt(router_mac);
962                 printf("[+] router-mac-ipv4 = %s\n", fmt.string);
963             }
964         }
965 
966 
967         /*
968          * IPv6 router MAC address.
969          * If it's not configured, then we need to send a (synchronous) query
970          * to the network in order to discover the location of routers on
971          * the local network
972          */
973         if (!ipv6address_is_zero(ipv6)) {
974             macaddress_t router_mac = {{0,0,0,0,0,0}};
975 
976             stack_ndpv6_resolve(
977                     adapter,
978                     ipv6,
979                     source_mac,
980                     &router_mac);
981 
982             if (macaddress_is_zero(router_mac)) {
983                 printf("[-] router-mac-ipv6 = not found\n");
984             } else {
985                 fmt = macaddress_fmt(router_mac);
986                 printf("[+] router-mac-ipv6 = %s\n", fmt.string);
987             }
988         }
989     }
990 
991     rawsock_close_adapter(adapter);
992     return 0;
993 }
994 
995 
996 
997 /***************************************************************************
998  ***************************************************************************/
999 int
rawsock_selftest()1000 rawsock_selftest()
1001 {
1002 
1003     return 0;
1004 }
1005 
1006