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