1 /*
2 * The ARP Scanner (arp-scan) is Copyright (C) 2005-2019 Roy Hills,
3 * NTA Monitor Ltd.
4 *
5 * This file is part of arp-scan.
6 *
7 * arp-scan is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * arp-scan is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with arp-scan. If not, see <http://www.gnu.org/licenses/>.
19 *
20 * arp-scan -- The ARP Scanner
21 *
22 * Author: Roy Hills
23 * Date: 13 October 2005
24 *
25 * Usage:
26 * arp-scan [options] [host...]
27 *
28 * Description:
29 *
30 * arp-scan sends the specified ARP packet to the specified hosts
31 * and displays any responses received.
32 *
33 * The ARP protocol is defined in RFC 826 Ethernet Address Resolution Protocol
34 *
35 */
36
37 #include "arp-scan.h"
38
39 /* Global variables */
40 static host_entry *helist = NULL; /* Array of host entries */
41 static host_entry **helistptr; /* Array of pointers to host entries */
42 static host_entry **cursor; /* Pointer to current host entry ptr */
43 static unsigned num_hosts = 0; /* Number of entries in the list */
44 static unsigned responders = 0; /* Number of hosts which responded */
45 static unsigned live_count; /* Number of entries awaiting reply */
46 static int verbose=0; /* Verbose level */
47 static char filename[MAXLINE]; /* Target list file name */
48 static int filename_flag=0; /* Set if using target list file */
49 static int random_flag=0; /* Randomise the list */
50 static int numeric_flag=0; /* IP addresses only */
51 static unsigned interval=0; /* Desired interval between packets */
52 static unsigned bandwidth=DEFAULT_BANDWIDTH; /* Bandwidth in bits per sec */
53 static unsigned retry = DEFAULT_RETRY; /* Number of retries */
54 static unsigned timeout = DEFAULT_TIMEOUT; /* Per-host timeout */
55 static float backoff_factor = DEFAULT_BACKOFF_FACTOR; /* Backoff factor */
56 static int snaplen = SNAPLEN; /* Pcap snap length */
57 static char *if_name=NULL; /* Interface name, e.g. "eth0" */
58 static int quiet_flag=0; /* Don't decode the packet */
59 static int ignore_dups=0; /* Don't display duplicate packets */
60 static uint32_t arp_spa; /* Source IP address */
61 static int arp_spa_flag=0; /* Source IP address specified */
62 static int arp_spa_is_tpa=0; /* Source IP is dest IP */
63 static unsigned char arp_sha[ETH_ALEN]; /* Source Ethernet MAC Address */
64 static int arp_sha_flag=0; /* Source MAC address specified */
65 static char ouifilename[MAXLINE]; /* OUI filename */
66 static char iabfilename[MAXLINE]; /* IAB filename */
67 static char macfilename[MAXLINE]; /* MAC filename */
68 static char pcap_savefile[MAXLINE]; /* pcap savefile filename */
69 static int arp_op=DEFAULT_ARP_OP; /* ARP Operation code */
70 static int arp_hrd=DEFAULT_ARP_HRD; /* ARP hardware type */
71 static int arp_pro=DEFAULT_ARP_PRO; /* ARP protocol */
72 static int arp_hln=DEFAULT_ARP_HLN; /* Hardware address length */
73 static int arp_pln=DEFAULT_ARP_PLN; /* Protocol address length */
74 static int eth_pro=DEFAULT_ETH_PRO; /* Ethernet protocol type */
75 static unsigned char arp_tha[6] = {0, 0, 0, 0, 0, 0};
76 static unsigned char target_mac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
77 static unsigned char source_mac[6];
78 static int source_mac_flag = 0;
79 static unsigned char *padding=NULL;
80 static size_t padding_len=0;
81 static int localnet_flag=0; /* Scan local network */
82 static int llc_flag=0; /* Use 802.2 LLC with SNAP */
83 static int ieee_8021q_vlan=-1; /* Use 802.1Q VLAN tagging if >= 0 */
84 static int pkt_write_file_flag=0; /* Write packet to file flag */
85 static int pkt_read_file_flag=0; /* Read packet from file flag */
86 static char pkt_filename[MAXLINE]; /* Read/Write packet to file filename */
87 static int write_pkt_to_file=0; /* Write packet to file for debugging */
88 static int rtt_flag=0; /* Display round-trip time */
89 static pcap_dumper_t *pcap_dump_handle = NULL; /* pcap savefile handle */
90 static int plain_flag=0; /* Only show host information */
91 unsigned int random_seed=0;
92
93 int
main(int argc,char * argv[])94 main(int argc, char *argv[]) {
95 struct timeval now;
96 struct timeval diff; /* Difference between two timevals */
97 int select_timeout; /* Select timeout */
98 uint64_t loop_timediff; /* Time since last packet sent in us */
99 uint64_t host_timediff; /* Time since last pkt sent to this host (us) */
100 struct timeval last_packet_time; /* Time last packet was sent */
101 int req_interval; /* Requested per-packet interval */
102 int cum_err=0; /* Cumulative timing error */
103 struct timeval start_time; /* Program start time */
104 struct timeval end_time; /* Program end time */
105 struct timeval elapsed_time; /* Elapsed time as timeval */
106 double elapsed_seconds; /* Elapsed time in seconds */
107 int reset_cum_err;
108 int pass_no = 0;
109 int first_timeout=1;
110 unsigned i;
111 char errbuf[PCAP_ERRBUF_SIZE];
112 struct bpf_program filter;
113 char *filter_string;
114 bpf_u_int32 netmask;
115 bpf_u_int32 localnet;
116 int datalink;
117 int ret_status = 0;
118 int pcap_fd; /* Pcap file descriptor */
119 unsigned char interface_mac[ETH_ALEN];
120 pcap_t *pcap_handle; /* pcap handle */
121 struct in_addr interface_ip_addr;
122 /*
123 * Initialise file names to the empty string.
124 */
125 ouifilename[0] = '\0';
126 iabfilename[0] = '\0';
127 macfilename[0] = '\0';
128 pcap_savefile[0] = '\0';
129 /*
130 * Process options.
131 */
132 process_options(argc, argv);
133 /*
134 * Get program start time for statistics displayed on completion.
135 */
136 Gettimeofday(&start_time);
137 /*
138 * Open the network device for reading with pcap, or the pcap file if we
139 * have specified --readpktfromfile. If we are writing packets to a binary
140 * file, then set pcap_handle to NULL as we don't need to read packets in
141 * this case.
142 */
143 if (pkt_read_file_flag) {
144 if (!(pcap_handle = pcap_open_offline(pkt_filename, errbuf)))
145 err_msg("pcap_open_offline: %s", errbuf);
146 } else if (!pkt_write_file_flag) {
147 /*
148 * Determine network interface to use. If the interface was specified
149 * with the --interface option then use that, otherwise use
150 * my_lookupdev() to pick a suitable interface.
151 */
152 if (!if_name) {
153 if (!(if_name=my_lookupdev(errbuf))) {
154 err_msg("my_lookupdev: %s", errbuf);
155 }
156 }
157 if (!(pcap_handle = pcap_create(if_name, errbuf)))
158 err_msg("pcap_create: %s", errbuf);
159 if ((pcap_set_snaplen(pcap_handle, snaplen)) < 0)
160 err_msg("pcap_set_snaplen: %s", pcap_geterr(pcap_handle));
161 if ((pcap_set_promisc(pcap_handle, PROMISC)) < 0)
162 err_msg("pcap_set_promisc: %s", pcap_geterr(pcap_handle));
163 if ((pcap_set_immediate_mode(pcap_handle, 1)) < 0)
164 err_msg("pcap_set_immediate_mode: %s", pcap_geterr(pcap_handle));
165 if ((pcap_set_timeout(pcap_handle, TO_MS)) < 0) /* Is this still needed? */
166 err_msg("pcap_set_timeout: %s", pcap_geterr(pcap_handle));
167 ret_status = pcap_activate(pcap_handle);
168 if (ret_status < 0) { /* Error from pcap_activate() */
169 char *cp;
170
171 cp = pcap_geterr(pcap_handle);
172 if (ret_status == PCAP_ERROR)
173 err_msg("pcap_activate: %s", cp);
174 else if ((ret_status == PCAP_ERROR_NO_SUCH_DEVICE ||
175 ret_status == PCAP_ERROR_PERM_DENIED) && *cp != '\0')
176 err_msg("pcap_activate: %s: %s\n(%s)", if_name,
177 pcap_statustostr(ret_status), cp);
178 else
179 err_msg("pcap_activate: %s: %s", if_name,
180 pcap_statustostr(ret_status));
181 } else if (ret_status > 0) { /* Warning from pcap_activate() */
182 char *cp;
183
184 cp = pcap_geterr(pcap_handle);
185 if (ret_status == PCAP_WARNING)
186 warn_msg("pcap_activate: %s", cp);
187 else if (ret_status == PCAP_WARNING_PROMISC_NOTSUP && *cp != '\0')
188 warn_msg("pcap_activate: %s: %s\n(%s)", if_name,
189 pcap_statustostr(ret_status), cp);
190 else
191 warn_msg("pcap_activate: %s: %s", if_name,
192 pcap_statustostr(ret_status));
193 }
194 /*
195 * Obtain the MAC address for the selected interface, and use this
196 * as the default value for the source hardware addresses in the frame
197 * header and ARP packet if the user has not specified their values.
198 *
199 * Die with an error if we can't get the MAC address, as this
200 * indicates that the interface doesn't have a MAC address, so is
201 * probably not a compatible interface type.
202 */
203 get_hardware_address(if_name, interface_mac);
204 if (interface_mac[0]==0 && interface_mac[1]==0 &&
205 interface_mac[2]==0 && interface_mac[3]==0 &&
206 interface_mac[4]==0 && interface_mac[5]==0) {
207 err_msg("ERROR: Could not obtain MAC address for interface %s",
208 if_name);
209 }
210 if (source_mac_flag == 0)
211 memcpy(source_mac, interface_mac, ETH_ALEN);
212 if (arp_sha_flag == 0)
213 memcpy(arp_sha, interface_mac, ETH_ALEN);
214 /*
215 * Obtain the interface IP address, and use that as the default value
216 * if the user has not manually specified the ARP source address.
217 *
218 * Give a warning and use 0.0.0.0 if the interface has no IP address.
219 */
220 ret_status = get_source_ip(if_name, &interface_ip_addr);
221 if (arp_spa_flag == 0) {
222 if (ret_status == -1) {
223 warn_msg("WARNING: Could not obtain IP address for interface %s. "
224 "Using 0.0.0.0 for", if_name);
225 warn_msg("the source address, which may not be what you want.");
226 warn_msg("Either configure %s with an IP address, or manually specify"
227 " the address", if_name);
228 warn_msg("with the --arpspa option.");
229 }
230 memcpy(&arp_spa, &(interface_ip_addr.s_addr), sizeof(arp_spa));
231 }
232 } else {
233 pcap_handle = NULL;
234 }
235 /*
236 * If we are reading data with pcap, get and display the datalink details
237 */
238 if (pcap_handle) {
239 if ((datalink=pcap_datalink(pcap_handle)) < 0)
240 err_msg("pcap_datalink: %s", pcap_geterr(pcap_handle));
241 if (!plain_flag) {
242 if (!pkt_read_file_flag) {
243 printf("Interface: %s, type: %s, "
244 "MAC: %.2x:%.2x:%.2x:%.2x:%.2x:%.2x, IPv4: %s\n",
245 if_name, pcap_datalink_val_to_name(datalink),
246 interface_mac[0], interface_mac[1], interface_mac[2],
247 interface_mac[3], interface_mac[4], interface_mac[5],
248 (interface_ip_addr.s_addr==0) ? "(none)" : my_ntoa(interface_ip_addr));
249 } else {
250 printf("Interface: pcap file\n");
251 }
252 }
253 if (datalink != DLT_EN10MB) {
254 warn_msg("WARNING: Unsupported datalink type");
255 }
256 }
257 /*
258 * If we are reading from a network device, then get the associated file
259 * descriptor and configure it, determine the interface IP network and
260 * netmask, and install a pcap filter to receive only ARP responses.
261 * If we are reading from a pcap file, or writing to a binary file, just
262 * set the file descriptor to -1 to indicate that it is not associated
263 * with a network device.
264 */
265 if (!pkt_read_file_flag && !pkt_write_file_flag) {
266 if ((pcap_fd=pcap_get_selectable_fd(pcap_handle)) < 0)
267 err_msg("pcap_fileno: %s", pcap_geterr(pcap_handle));
268 if ((pcap_setnonblock(pcap_handle, 1, errbuf)) < 0)
269 err_msg("pcap_setnonblock: %s", errbuf);
270
271 if (pcap_lookupnet(if_name, &localnet, &netmask, errbuf) < 0) {
272 memset(&localnet, '\0', sizeof(localnet));
273 memset(&netmask, '\0', sizeof(netmask));
274 if (localnet_flag) {
275 warn_msg("ERROR: Could not obtain interface IP address and netmask");
276 err_msg("ERROR: pcap_lookupnet: %s", errbuf);
277 }
278 }
279 /*
280 * The filter string selects packets addressed to the ARP source address
281 * that are Ethernet-II ARP packets, 802.3 LLC/SNAP ARP packets,
282 * 802.1Q tagged ARP packets or 802.1Q tagged 802.3 LLC/SNAP ARP packets.
283 */
284 filter_string=make_message("ether dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x and "
285 "(arp or (ether[14:4]=0xaaaa0300 and "
286 "ether[20:2]=0x0806) or (ether[12:2]=0x8100 "
287 "and ether[16:2]=0x0806) or "
288 "(ether[12:2]=0x8100 and "
289 "ether[18:4]=0xaaaa0300 and "
290 "ether[24:2]=0x0806))",
291 arp_sha[0], arp_sha[1],
292 arp_sha[2], arp_sha[3],
293 arp_sha[4], arp_sha[5]);
294 if (verbose > 1)
295 warn_msg("DEBUG: pcap filter string: \"%s\"", filter_string);
296 if ((pcap_compile(pcap_handle, &filter, filter_string, OPTIMISE,
297 netmask)) < 0)
298 err_msg("pcap_compile: %s", pcap_geterr(pcap_handle));
299 free(filter_string);
300 if ((pcap_setfilter(pcap_handle, &filter)) < 0)
301 err_msg("pcap_setfilter: %s", pcap_geterr(pcap_handle));
302 } else { /* Reading packets from file */
303 pcap_fd = -1;
304 }
305 /*
306 * Drop SUID privileges.
307 */
308 if ((setuid(getuid())) < 0) {
309 err_sys("setuid");
310 }
311 /*
312 * Open pcap savefile is the --pcapsavefile (-W) option was specified
313 */
314 if (*pcap_savefile != '\0') {
315 if (!(pcap_dump_handle=pcap_dump_open(pcap_handle, pcap_savefile))) {
316 err_msg("pcap_dump_open: %s", pcap_geterr(pcap_handle));
317 }
318 }
319 /*
320 * Check that the combination of specified options and arguments is
321 * valid.
322 */
323 if (interval && bandwidth != DEFAULT_BANDWIDTH)
324 err_msg("ERROR: You cannot specify both --bandwidth and --interval.");
325 if (localnet_flag) {
326 if ((argc - optind) > 0)
327 err_msg("ERROR: You can not specify targets with the --localnet option");
328 if (filename_flag)
329 err_msg("ERROR: You can not specify both --file and --localnet options");
330 }
331 /*
332 * If we're not reading from a file, and --localnet was not specified, then
333 * we must have some hosts given as command line arguments.
334 */
335 if (!filename_flag && !localnet_flag)
336 if ((argc - optind) < 1)
337 usage(EXIT_FAILURE, 0);
338 /*
339 * Create MAC/Vendor hash table if quiet if not in effect.
340 */
341 if (!quiet_flag) {
342 char *fn;
343 int count;
344
345 if ((hcreate(HASH_TABLE_SIZE)) == 0)
346 err_sys("hcreate");
347
348 fn = get_mac_vendor_filename(ouifilename, DATADIR, OUIFILENAME);
349 count = add_mac_vendor(fn);
350 if (verbose > 1 && count > 0)
351 warn_msg("DEBUG: Loaded %d IEEE OUI/Vendor entries from %s.",
352 count, fn);
353 free(fn);
354
355 fn = get_mac_vendor_filename(iabfilename, DATADIR, IABFILENAME);
356 count = add_mac_vendor(fn);
357 if (verbose > 1 && count > 0)
358 warn_msg("DEBUG: Loaded %d IEEE IAB/Vendor entries from %s.",
359 count, fn);
360 free(fn);
361
362 fn = get_mac_vendor_filename(macfilename, DATADIR, MACFILENAME);
363 count = add_mac_vendor(fn);
364 if (verbose > 1 && count > 0)
365 warn_msg("DEBUG: Loaded %d MAC/Vendor entries from %s.",
366 count, fn);
367 free(fn);
368 }
369 /*
370 * Populate the list from the specified file if --file was specified, or
371 * from the interface address and mask if --localnet was specified, or
372 * otherwise from the remaining command line arguments.
373 */
374 if (filename_flag) { /* Populate list from file */
375 FILE *fp;
376 char line[MAXLINE];
377 char *cp;
378
379 if ((strcmp(filename, "-")) == 0) { /* Filename "-" means stdin */
380 fp = stdin;
381 } else {
382 if ((fp = fopen(filename, "r")) == NULL) {
383 err_sys("fopen");
384 }
385 }
386
387 while (fgets(line, MAXLINE, fp)) {
388 for (cp = line; !isspace((unsigned char)*cp) && *cp != '\0'; cp++)
389 ;
390 *cp = '\0';
391 add_host_pattern(line, timeout);
392 }
393 if (fp != stdin) {
394 fclose(fp);
395 }
396 } else if (localnet_flag) { /* Populate list from i/f addr & mask */
397 struct in_addr if_network;
398 struct in_addr if_netmask;
399 char *c_network;
400 char *c_netmask;
401 const char *cp;
402 char localnet_descr[32];
403
404 if_network.s_addr = localnet;
405 if_netmask.s_addr = netmask;
406 cp = my_ntoa(if_network);
407 c_network = make_message("%s", cp);
408 cp = my_ntoa(if_netmask);
409 c_netmask = make_message("%s", cp);
410 snprintf(localnet_descr, 32, "%s:%s", c_network, c_netmask);
411 free(c_network);
412 free(c_netmask);
413
414 if (verbose) {
415 warn_msg("Using %s for localnet", localnet_descr);
416 }
417 add_host_pattern(localnet_descr, timeout);
418 } else { /* Populate list from command line arguments */
419 argv=&argv[optind];
420 while (*argv) {
421 add_host_pattern(*argv, timeout);
422 argv++;
423 }
424 }
425 /*
426 * Check that we have at least one entry in the list.
427 */
428 if (!num_hosts)
429 err_msg("ERROR: No hosts to process.");
430 /*
431 * If --writepkttofile was specified, open the specified output file.
432 */
433 if (pkt_write_file_flag) {
434 write_pkt_to_file = open(pkt_filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
435 if (write_pkt_to_file == -1)
436 err_sys("open %s", pkt_filename);
437 }
438 /*
439 * Create and initialise array of pointers to host entries.
440 */
441 helistptr = Malloc(num_hosts * sizeof(host_entry *));
442 for (i=0; i<num_hosts; i++)
443 helistptr[i] = &helist[i];
444 /*
445 * Randomise the list if required.
446 * Uses Knuth's shuffle algorithm.
447 */
448 if (random_flag) {
449 int r;
450 host_entry *temp;
451 /*
452 * Seed random number generator.
453 * If the random seed has been specified (is non-zero), then use that.
454 * Otherwise, seed the RNG with an unpredictable value.
455 */
456 if (!random_seed) {
457 struct timeval tv;
458
459 Gettimeofday(&tv);
460 random_seed = tv.tv_usec ^ getpid(); /* Unpredictable value */
461 }
462 init_genrand(random_seed);
463
464 for (i=num_hosts-1; i>0; i--) {
465 r = (int)(genrand_real2() * i); /* 0<=r<i */
466 temp = helistptr[i];
467 helistptr[i] = helistptr[r];
468 helistptr[r] = temp;
469 }
470 }
471 /*
472 * Set current host pointer (cursor) to start of list, zero
473 * last packet sent time, and set last receive time to now.
474 */
475 live_count = num_hosts;
476 cursor = helistptr;
477 last_packet_time.tv_sec=0;
478 last_packet_time.tv_usec=0;
479 /*
480 * Calculate the required interval to achieve the required outgoing
481 * bandwidth unless the interval was manually specified with --interval.
482 */
483 if (!interval) {
484 size_t packet_out_len;
485
486 packet_out_len=send_packet(NULL, NULL, NULL); /* Get packet data size */
487 if (packet_out_len < MINIMUM_FRAME_SIZE)
488 packet_out_len = MINIMUM_FRAME_SIZE; /* Adjust to minimum size */
489 packet_out_len += PACKET_OVERHEAD; /* Add layer 2 overhead */
490 interval = ((uint64_t)packet_out_len * 8 * 1000000) / bandwidth;
491 if (verbose > 1) {
492 warn_msg("DEBUG: pkt len=%u bytes, bandwidth=%u bps, interval=%u us",
493 packet_out_len, bandwidth, interval);
494 }
495 }
496 /*
497 * Display initial message.
498 */
499 if (!plain_flag) {
500 printf("Starting %s with %u hosts (https://github.com/royhills/arp-scan)\n",
501 PACKAGE_STRING, num_hosts);
502 }
503 /*
504 * Display the lists if verbose setting is 3 or more.
505 */
506 if (verbose > 2)
507 dump_list();
508 /*
509 * Main loop: send packets to all hosts in order until a response
510 * has been received or the host has exhausted its retry limit.
511 *
512 * The loop exits when all hosts have either responded or timed out.
513 */
514 reset_cum_err = 1;
515 req_interval = interval;
516 while (live_count) {
517 /*
518 * Obtain current time and calculate deltas since last packet and
519 * last packet to this host.
520 */
521 Gettimeofday(&now);
522 /*
523 * If the last packet was sent more than interval us ago, then we can
524 * potentially send a packet to the current host.
525 */
526 timeval_diff(&now, &last_packet_time, &diff);
527 loop_timediff = (uint64_t)1000000*diff.tv_sec + diff.tv_usec;
528 if (loop_timediff >= (unsigned)req_interval) {
529 /*
530 * If the last packet to this host was sent more than the current
531 * timeout for this host us ago, then we can potentially send a packet
532 * to it.
533 */
534 timeval_diff(&now, &((*cursor)->last_send_time), &diff);
535 host_timediff = (uint64_t)1000000*diff.tv_sec + diff.tv_usec;
536 if (host_timediff >= (*cursor)->timeout) {
537 if (reset_cum_err) {
538 cum_err = 0;
539 req_interval = interval;
540 reset_cum_err = 0;
541 } else {
542 cum_err += loop_timediff - interval;
543 if (req_interval >= cum_err) {
544 req_interval = req_interval - cum_err;
545 } else {
546 req_interval = 0;
547 }
548 }
549 select_timeout = req_interval;
550 /*
551 * If we've exceeded our retry limit, then this host has timed out so
552 * remove it from the list. Otherwise, increase the timeout by the
553 * backoff factor if this is not the first packet sent to this host
554 * and send a packet.
555 */
556 if (verbose && (*cursor)->num_sent > pass_no) {
557 warn_msg("---\tPass %d complete", pass_no+1);
558 pass_no = (*cursor)->num_sent;
559 }
560 if ((*cursor)->num_sent >= retry) {
561 if (verbose > 1)
562 warn_msg("---\tRemoving host %s - Timeout",
563 my_ntoa((*cursor)->addr));
564 remove_host(cursor); /* Automatically calls advance_cursor() */
565 if (first_timeout) {
566 timeval_diff(&now, &((*cursor)->last_send_time), &diff);
567 host_timediff = (uint64_t)1000000*diff.tv_sec +
568 diff.tv_usec;
569 while (host_timediff >= (*cursor)->timeout && live_count) {
570 if ((*cursor)->live) {
571 if (verbose > 1)
572 warn_msg("---\tRemoving host %s - Catch-Up Timeout",
573 my_ntoa((*cursor)->addr));
574 remove_host(cursor);
575 } else {
576 advance_cursor();
577 }
578 timeval_diff(&now, &((*cursor)->last_send_time), &diff);
579 host_timediff = (uint64_t)1000000*diff.tv_sec +
580 diff.tv_usec;
581 }
582 first_timeout=0;
583 }
584 Gettimeofday(&last_packet_time);
585 } else { /* Retry limit not reached for this host */
586 if ((*cursor)->num_sent)
587 (*cursor)->timeout *= backoff_factor;
588 send_packet(pcap_handle, *cursor, &last_packet_time);
589 advance_cursor();
590 }
591 } else { /* We can't send a packet to this host yet */
592 /*
593 * Note that there is no point calling advance_cursor() here because if
594 * host n is not ready to send, then host n+1 will not be ready either.
595 */
596 select_timeout = (*cursor)->timeout - host_timediff;
597 reset_cum_err = 1; /* Zero cumulative error */
598 } /* End If */
599 } else { /* We can't send a packet yet */
600 select_timeout = req_interval - loop_timediff;
601 } /* End If */
602 recvfrom_wto(pcap_fd, select_timeout, pcap_handle);
603 } /* End While */
604
605 if (!plain_flag) {
606 printf("\n"); /* Ensure we have a blank line */
607 }
608
609 clean_up(pcap_handle);
610 if (write_pkt_to_file)
611 close(write_pkt_to_file);
612
613 Gettimeofday(&end_time);
614 timeval_diff(&end_time, &start_time, &elapsed_time);
615 elapsed_seconds = (elapsed_time.tv_sec*1000 +
616 elapsed_time.tv_usec/1000) / 1000.0;
617
618 if (!plain_flag) {
619 printf("Ending %s: %u hosts scanned in %.3f seconds (%.2f hosts/sec). %u responded\n",
620 PACKAGE_STRING, num_hosts, elapsed_seconds,
621 num_hosts/elapsed_seconds, responders);
622 }
623 return 0;
624 }
625
626 /*
627 * display_packet -- Check and display received packet
628 *
629 * Inputs:
630 *
631 * he The host entry corresponding to the received packet
632 * arpei ARP packet structure
633 * extra_data Extra data after ARP packet (padding)
634 * extra_data_len Length of extra data
635 * framing Framing type (e.g. Ethernet II, LLC)
636 * vlan_id 802.1Q VLAN identifier, or -1 if not 802.1Q
637 * frame_hdr The Ethernet frame header
638 * pcap_header The PCAP header struct
639 *
640 * Returns:
641 *
642 * None.
643 *
644 * This checks the received packet and displays details of what
645 * was received in the format: <IP-Address><TAB><Details>.
646 */
647 void
display_packet(host_entry * he,arp_ether_ipv4 * arpei,const unsigned char * extra_data,size_t extra_data_len,int framing,int vlan_id,ether_hdr * frame_hdr,const struct pcap_pkthdr * pcap_header)648 display_packet(host_entry *he, arp_ether_ipv4 *arpei,
649 const unsigned char *extra_data, size_t extra_data_len,
650 int framing, int vlan_id, ether_hdr *frame_hdr,
651 const struct pcap_pkthdr *pcap_header) {
652 char *msg;
653 char *cp;
654 char *cp2;
655 int nonzero=0;
656 /*
657 * Set msg to the IP address of the host entry and a tab.
658 */
659 msg = make_message("%s\t", my_ntoa(he->addr));
660 /*
661 * Decode ARP packet
662 */
663 cp = msg;
664 msg = make_message("%s%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", cp,
665 arpei->ar_sha[0], arpei->ar_sha[1],
666 arpei->ar_sha[2], arpei->ar_sha[3],
667 arpei->ar_sha[4], arpei->ar_sha[5]);
668 free(cp);
669 /*
670 * Check that the source address in the Ethernet frame header is the same
671 * as ar$sha in the ARP packet, and display the Ethernet source address
672 * if it is different.
673 */
674 if ((memcmp(arpei->ar_sha, frame_hdr->src_addr, ETH_ALEN)) != 0) {
675 cp = msg;
676 msg = make_message("%s (%.2x:%.2x:%.2x:%.2x:%.2x:%.2x)", cp,
677 frame_hdr->src_addr[0], frame_hdr->src_addr[1],
678 frame_hdr->src_addr[2], frame_hdr->src_addr[3],
679 frame_hdr->src_addr[4], frame_hdr->src_addr[5]);
680 free(cp);
681 }
682 /*
683 * Find vendor from hash table and add to message if quiet if not in
684 * effect.
685 *
686 * We start with more specific matches (against larger parts of the
687 * hardware address), and work towards less specific matches until
688 * we find a match or exhaust all possible matches.
689 */
690 if (!quiet_flag) {
691 char oui_string[13]; /* Space for full hw addr plus NULL */
692 const char *vendor=NULL;
693 int oui_end=12;
694 ENTRY hash_query;
695 ENTRY *hash_result;
696
697 snprintf(oui_string, 13, "%.2X%.2X%.2X%.2X%.2X%.2X",
698 arpei->ar_sha[0], arpei->ar_sha[1], arpei->ar_sha[2],
699 arpei->ar_sha[3], arpei->ar_sha[4], arpei->ar_sha[5]);
700 while (vendor == NULL && oui_end > 1) {
701 oui_string[oui_end] = '\0'; /* Truncate oui string */
702 hash_query.key = oui_string;
703 hash_result = hsearch(hash_query, FIND);
704 if (hash_result) {
705 vendor = hash_result->data;
706 } else {
707 vendor = NULL;
708 }
709 oui_end--;
710 }
711 cp = msg;
712 if (vendor)
713 msg = make_message("%s\t%s", cp, vendor);
714 else
715 /* Of the first octet of the address, check the second-least-significant bit */
716 if (arpei->ar_sha[0] & (1<<1))
717 msg = make_message("%s\t%s", cp, "(Unknown: locally administered)");
718 else
719 msg = make_message("%s\t%s", cp, "(Unknown)");
720 free(cp);
721 /*
722 * Check that any data after the ARP packet is zero.
723 * If it is non-zero, and verbose is selected, then print the padding.
724 */
725 if (extra_data_len > 0) {
726 unsigned i;
727 const unsigned char *ucp = extra_data;
728
729 for (i=0; i<extra_data_len; i++) {
730 if (ucp[i] != '\0') {
731 nonzero=1;
732 break;
733 }
734 }
735 }
736 if (nonzero && verbose) {
737 cp = msg;
738 cp2 = hexstring(extra_data, extra_data_len);
739 msg = make_message("%s\tPadding=%s", cp, cp2);
740 free(cp2);
741 free(cp);
742 }
743 /*
744 * If the framing type is not Ethernet II, then report the framing type.
745 */
746 if (framing != FRAMING_ETHERNET_II) {
747 cp = msg;
748 if (framing == FRAMING_LLC_SNAP) {
749 msg = make_message("%s (802.2 LLC/SNAP)", cp);
750 }
751 free(cp);
752 }
753 /*
754 * If the packet uses 802.1Q VLAN tagging, report the VLAN ID.
755 */
756 if (vlan_id != -1) {
757 cp = msg;
758 msg = make_message("%s (802.1Q VLAN=%d)", cp, vlan_id);
759 free(cp);
760 }
761 /*
762 * If the ARP protocol type is not IP (0x0800), report it.
763 * This can occur with trailer encapsulation ARP replies.
764 */
765 if (ntohs(arpei->ar_pro) != 0x0800) {
766 cp = msg;
767 msg = make_message("%s (ARP Proto=0x%04x)", cp, ntohs(arpei->ar_pro));
768 free(cp);
769 }
770 /*
771 * If the host entry is not live, then flag this as a duplicate.
772 */
773 if (!he->live) {
774 cp = msg;
775 msg = make_message("%s (DUP: %u)", cp, he->num_recv);
776 free(cp);
777 }
778 /*
779 * If the rtt_flag is set, calculate and report the packet round-trip
780 * time.
781 */
782 if (rtt_flag) {
783 struct timeval rtt;
784 struct timeval pcap_timestamp;
785 unsigned long rtt_us; /* round-trip time in microseconds */
786 /*
787 * We can't pass a pointer to pcap_header->ts directly to timeval_diff
788 * because it's not guaranteed to have the same size as a struct timeval.
789 * E.g. OpenBSD 5.1 on amd64.
790 */
791 pcap_timestamp.tv_sec = pcap_header->ts.tv_sec;
792 pcap_timestamp.tv_usec = pcap_header->ts.tv_usec;
793 timeval_diff(&pcap_timestamp, &(he->last_send_time), &rtt);
794 rtt_us = rtt.tv_sec * 1000000 + rtt.tv_usec;
795 cp=msg;
796 msg=make_message("%s\tRTT=%lu.%03lu ms", cp, rtt_us/1000, rtt_us%1000);
797 free(cp);
798 }
799 } /* End if (!quiet_flag) */
800 /*
801 * Print the message.
802 */
803 printf("%s\n", msg);
804 free(msg);
805 }
806
807 /*
808 * send_packet -- Construct and send a packet to the specified host
809 *
810 * Inputs:
811 *
812 * pcap_handle Pcap handle
813 * he Host entry to send to. If NULL, then no packet is sent
814 * last_packet_time Time when last packet was sent
815 *
816 * Returns:
817 *
818 * The size of the packet that was sent.
819 *
820 * This constructs an appropriate packet and sends it to the host
821 * identified by "he" using the socket "s". It also updates the
822 * "last_send_time" field for the host entry.
823 *
824 * If we are using the undocumented --writepkttofile option, then we
825 * write the packet to the write_pkt_to_file file descriptor instead of
826 * transmitting it on the network.
827 *
828 * If we are using the undocumented --readpktfromfile option, then we
829 * don't send anything.
830 */
831 int
send_packet(pcap_t * pcap_handle,host_entry * he,struct timeval * last_packet_time)832 send_packet(pcap_t *pcap_handle, host_entry *he,
833 struct timeval *last_packet_time) {
834 unsigned char buf[MAX_FRAME];
835 size_t buflen;
836 ether_hdr frame_hdr;
837 arp_ether_ipv4 arpei;
838 int nsent = 0;
839 /*
840 * Construct Ethernet frame header
841 */
842 memcpy(frame_hdr.dest_addr, target_mac, ETH_ALEN);
843 memcpy(frame_hdr.src_addr, source_mac, ETH_ALEN);
844 frame_hdr.frame_type = htons(eth_pro);
845 /*
846 * Construct the ARP Header.
847 */
848 memset(&arpei, '\0', sizeof(arp_ether_ipv4));
849 arpei.ar_hrd = htons(arp_hrd);
850 arpei.ar_pro = htons(arp_pro);
851 arpei.ar_hln = arp_hln;
852 arpei.ar_pln = arp_pln;
853 arpei.ar_op = htons(arp_op);
854 memcpy(arpei.ar_sha, arp_sha, ETH_ALEN);
855 memcpy(arpei.ar_tha, arp_tha, ETH_ALEN);
856 if (arp_spa_is_tpa) {
857 if (he) {
858 arpei.ar_sip = he->addr.s_addr;
859 }
860 } else {
861 arpei.ar_sip = arp_spa;
862 }
863 if (he)
864 arpei.ar_tip = he->addr.s_addr;
865 /*
866 * Copy the required data into the output buffer "buf" and set "buflen"
867 * to the number of bytes in this buffer.
868 */
869 marshal_arp_pkt(buf, &frame_hdr, &arpei, &buflen, padding, padding_len);
870 /*
871 * If he is NULL, just return with the packet length.
872 */
873 if (he == NULL)
874 return buflen;
875 /*
876 * Check that the host is live. Complain if not.
877 */
878 if (!he->live) {
879 warn_msg("***\tsend_packet called on non-live host: SHOULDN'T HAPPEN");
880 return 0;
881 }
882 /*
883 * Update the last send times for this host.
884 */
885 Gettimeofday(last_packet_time);
886 he->last_send_time.tv_sec = last_packet_time->tv_sec;
887 he->last_send_time.tv_usec = last_packet_time->tv_usec;
888 he->num_sent++;
889 /*
890 * Send the packet.
891 */
892 if (verbose > 1)
893 warn_msg("---\tSending packet #%u to host %s tmo %d", he->num_sent,
894 my_ntoa(he->addr), he->timeout);
895 if (write_pkt_to_file) {
896 nsent = write(write_pkt_to_file, buf, buflen);
897 } else if (!pkt_read_file_flag) {
898 nsent = pcap_sendpacket(pcap_handle, buf, buflen);
899 }
900 if (nsent < 0)
901 err_sys("ERROR: failed to send packet");
902
903 return buflen;
904 }
905
906 /*
907 * clean_up -- Protocol-specific Clean-Up routine.
908 *
909 * Inputs:
910 *
911 * None.
912 *
913 * Returns:
914 *
915 * None.
916 *
917 * This is called once after all hosts have been processed. It can be
918 * used to perform any tidying-up or statistics-displaying required.
919 * It does not have to do anything.
920 */
921 void
clean_up(pcap_t * pcap_handle)922 clean_up(pcap_t *pcap_handle) {
923 struct pcap_stat stats;
924
925 if (!plain_flag) {
926 if (pcap_handle && !pkt_read_file_flag) {
927 if ((pcap_stats(pcap_handle, &stats)) < 0)
928 err_msg("pcap_stats: %s", pcap_geterr(pcap_handle));
929
930 printf("%u packets received by filter, %u packets dropped by kernel\n",
931 stats.ps_recv, stats.ps_drop);
932 }
933 }
934 if (pcap_dump_handle) {
935 pcap_dump_close(pcap_dump_handle);
936 }
937 if (pcap_handle) {
938 pcap_close(pcap_handle);
939 }
940 }
941
942 /*
943 * usage -- display usage message and exit
944 *
945 * Inputs:
946 *
947 * status Status code to pass to exit()
948 * detailed zero for brief output, non-zero for detailed output
949 *
950 * Returns:
951 *
952 * None (this function never returns).
953 */
954 void
usage(int status,int detailed)955 usage(int status, int detailed) {
956 fprintf(stdout, "Usage: arp-scan [options] [hosts...]\n");
957 fprintf(stdout, "\n");
958 fprintf(stdout, "Target hosts must be specified on the command line unless the --file option is\n");
959 fprintf(stdout, "given, in which case the targets are read from the specified file instead, or\n");
960 fprintf(stdout, "the --localnet option is used, in which case the targets are generated from\n");
961 fprintf(stdout, "the network interface IP address and netmask.\n");
962 fprintf(stdout, "\n");
963 fprintf(stdout, "You will need to be root, or arp-scan must be SUID root, in order to run\n");
964 fprintf(stdout, "arp-scan, because the functions that it uses to read and write packets\n");
965 fprintf(stdout, "require root privilege.\n");
966 fprintf(stdout, "\n");
967 fprintf(stdout, "The target hosts can be specified as IP addresses or hostnames. You can also\n");
968 fprintf(stdout, "specify the target as IPnetwork/bits (e.g. 192.168.1.0/24) to specify all hosts\n");
969 fprintf(stdout, "in the given network (network and broadcast addresses included), or\n");
970 fprintf(stdout, "IPstart-IPend (e.g. 192.168.1.3-192.168.1.27) to specify all hosts in the\n");
971 fprintf(stdout, "inclusive range, or IPnetwork:NetMask (e.g. 192.168.1.0:255.255.255.0) to\n");
972 fprintf(stdout, "specify all hosts in the given network and mask.\n");
973 fprintf(stdout, "\n");
974 fprintf(stdout, "These different options for specifying target hosts may be used both on the\n");
975 fprintf(stdout, "command line, and also in the file specified with the --file option.\n");
976 fprintf(stdout, "\n");
977 if (detailed) {
978 fprintf(stdout, "Options:\n");
979 fprintf(stdout, "\n");
980 fprintf(stdout, "Note: where an option takes a value, that value is specified as a letter in\n");
981 fprintf(stdout, "angle brackets. The letter indicates the type of data that is expected:\n");
982 fprintf(stdout, "\n");
983 fprintf(stdout, "<s> A character string, e.g. --file=hostlist.txt.\n");
984 fprintf(stdout, "\n");
985 fprintf(stdout, "<i> An integer, which can be specified as a decimal number or as a hexadecimal\n");
986 fprintf(stdout, " number if preceded with 0x, e.g. --arppro=2048 or --arpro=0x0800.\n");
987 fprintf(stdout, "\n");
988 fprintf(stdout, "<f> A floating point decimal number, e.g. --backoff=1.5.\n");
989 fprintf(stdout, "\n");
990 fprintf(stdout, "<m> An Ethernet MAC address, which can be specified either in the format\n");
991 fprintf(stdout, " 01:23:45:67:89:ab, or as 01-23-45-67-89-ab. The alphabetic hex characters\n");
992 fprintf(stdout, " may be either upper or lower case. E.g. --arpsha=01:23:45:67:89:ab.\n");
993 fprintf(stdout, "\n");
994 fprintf(stdout, "<a> An IPv4 address, e.g. --arpspa=10.0.0.1\n");
995 fprintf(stdout, "\n");
996 fprintf(stdout, "<h> Binary data specified as a hexadecimal string, which should not\n");
997 fprintf(stdout, " include a leading 0x. The alphabetic hex characters may be either\n");
998 fprintf(stdout, " upper or lower case. E.g. --padding=aaaaaaaaaaaa\n");
999 fprintf(stdout, "\n");
1000 fprintf(stdout, "<x> Something else. See the description of the option for details.\n");
1001 fprintf(stdout, "\n--help or -h\t\tDisplay this usage message and exit.\n");
1002 fprintf(stdout, "\n--file=<s> or -f <s>\tRead hostnames or addresses from the specified file\n");
1003 fprintf(stdout, "\t\t\tinstead of from the command line. One name or IP\n");
1004 fprintf(stdout, "\t\t\taddress per line. Use \"-\" for standard input.\n");
1005 fprintf(stdout, "\n--localnet or -l\tGenerate addresses from network interface configuration.\n");
1006 fprintf(stdout, "\t\t\tUse the network interface IP address and network mask\n");
1007 fprintf(stdout, "\t\t\tto generate the list of target host addresses.\n");
1008 fprintf(stdout, "\t\t\tThe list will include the network and broadcast\n");
1009 fprintf(stdout, "\t\t\taddresses, so an interface address of 10.0.0.1 with\n");
1010 fprintf(stdout, "\t\t\tnetmask 255.255.255.0 would generate 256 target\n");
1011 fprintf(stdout, "\t\t\thosts from 10.0.0.0 to 10.0.0.255 inclusive.\n");
1012 fprintf(stdout, "\t\t\tIf you use this option, you cannot specify the --file\n");
1013 fprintf(stdout, "\t\t\toption or specify any target hosts on the command line.\n");
1014 fprintf(stdout, "\t\t\tThe interface specifications are taken from the\n");
1015 fprintf(stdout, "\t\t\tinterface that arp-scan will use, which can be\n");
1016 fprintf(stdout, "\t\t\tchanged with the --interface option.\n");
1017 fprintf(stdout, "\n--retry=<i> or -r <i>\tSet total number of attempts per host to <i>,\n");
1018 fprintf(stdout, "\t\t\tdefault=%d.\n", DEFAULT_RETRY);
1019 fprintf(stdout, "\n--timeout=<i> or -t <i>\tSet initial per host timeout to <i> ms, default=%d.\n", DEFAULT_TIMEOUT);
1020 fprintf(stdout, "\t\t\tThis timeout is for the first packet sent to each host.\n");
1021 fprintf(stdout, "\t\t\tsubsequent timeouts are multiplied by the backoff\n");
1022 fprintf(stdout, "\t\t\tfactor which is set with --backoff.\n");
1023 fprintf(stdout, "\n--interval=<x> or -i <x> Set minimum packet interval to <x>.\n");
1024 fprintf(stdout, "\t\t\tThis controls the outgoing bandwidth usage by limiting\n");
1025 fprintf(stdout, "\t\t\tthe rate at which packets can be sent. The packet\n");
1026 fprintf(stdout, "\t\t\tinterval will be no smaller than this number.\n");
1027 fprintf(stdout, "\t\t\tIf you want to use up to a given bandwidth, then it is\n");
1028 fprintf(stdout, "\t\t\teasier to use the --bandwidth option instead.\n");
1029 fprintf(stdout, "\t\t\tThe interval specified is in milliseconds by default,\n");
1030 fprintf(stdout, "\t\t\tor in microseconds if \"u\" is appended to the value.\n");
1031 fprintf(stdout, "\n--bandwidth=<x> or -B <x> Set desired outbound bandwidth to <x>, default=%d.\n", DEFAULT_BANDWIDTH);
1032 fprintf(stdout, "\t\t\tThe value is in bits per second by default. If you\n");
1033 fprintf(stdout, "\t\t\tappend \"K\" to the value, then the units are kilobits\n");
1034 fprintf(stdout, "\t\t\tper sec; and if you append \"M\" to the value, the\n");
1035 fprintf(stdout, "\t\t\tunits are megabits per second.\n");
1036 fprintf(stdout, "\t\t\tThe \"K\" and \"M\" suffixes represent the decimal, not\n");
1037 fprintf(stdout, "\t\t\tbinary, multiples. So 64K is 64000, not 65536.\n");
1038 fprintf(stdout, "\t\t\tYou cannot specify both --interval and --bandwidth\n");
1039 fprintf(stdout, "\t\t\tbecause they are just different ways to change the\n");
1040 fprintf(stdout, "\t\t\tsame underlying parameter.\n");
1041 fprintf(stdout, "\n--backoff=<f> or -b <f>\tSet timeout backoff factor to <f>, default=%.2f.\n", DEFAULT_BACKOFF_FACTOR);
1042 fprintf(stdout, "\t\t\tThe per-host timeout is multiplied by this factor\n");
1043 fprintf(stdout, "\t\t\tafter each timeout. So, if the number of retries\n");
1044 fprintf(stdout, "\t\t\tis 3, the initial per-host timeout is 500ms and the\n");
1045 fprintf(stdout, "\t\t\tbackoff factor is 1.5, then the first timeout will be\n");
1046 fprintf(stdout, "\t\t\t500ms, the second 750ms and the third 1125ms.\n");
1047 fprintf(stdout, "\n--verbose or -v\t\tDisplay verbose progress messages.\n");
1048 fprintf(stdout, "\t\t\tUse more than once for greater effect:\n");
1049 fprintf(stdout, "\t\t\t1 - Display the network address and mask used when the\n");
1050 fprintf(stdout, "\t\t\t --localnet option is specified, display any\n");
1051 fprintf(stdout, "\t\t\t nonzero packet padding, display packets received\n");
1052 fprintf(stdout, "\t\t\t from unknown hosts, and show when each pass through\n");
1053 fprintf(stdout, "\t\t\t the list completes.\n");
1054 fprintf(stdout, "\t\t\t2 - Show each packet sent and received, when entries\n");
1055 fprintf(stdout, "\t\t\t are removed from the list, the pcap filter string,\n");
1056 fprintf(stdout, "\t\t\t and counts of MAC/Vendor mapping entries.\n");
1057 fprintf(stdout, "\t\t\t3 - Display the host list before scanning starts.\n");
1058 fprintf(stdout, "\n--version or -V\t\tDisplay program version and exit.\n");
1059 fprintf(stdout, "\n--random or -R\t\tRandomise the host list.\n");
1060 fprintf(stdout, "\t\t\tThis option randomises the order of the hosts in the\n");
1061 fprintf(stdout, "\t\t\thost list, so the ARP packets are sent to the hosts in\n");
1062 fprintf(stdout, "\t\t\ta random order. It uses the Knuth shuffle algorithm.\n");
1063 fprintf(stdout, "\n--randomseed=<i>\tUse <i> to seed the pseudo random number generator.\n");
1064 fprintf(stdout, "\t\t\tThis option seeds the PRNG with the specified number,\n");
1065 fprintf(stdout, "\t\t\twhich can be useful if you want to ensure that the\n");
1066 fprintf(stdout, "\t\t\trandom host list is reproducible. By default, the PRNG\n");
1067 fprintf(stdout, "\t\t\tis seeded with an unpredictable value. This option is\n");
1068 fprintf(stdout, "\t\t\tonly effective in conjunction with the --random (-R)\n");
1069 fprintf(stdout, "\t\t\toption.\n");
1070 fprintf(stdout, "\n--numeric or -N\t\tIP addresses only, no hostnames.\n");
1071 fprintf(stdout, "\t\t\tWith this option, all hosts must be specified as\n");
1072 fprintf(stdout, "\t\t\tIP addresses. Hostnames are not permitted. No DNS\n");
1073 fprintf(stdout, "\t\t\tlookups will be performed.\n");
1074 fprintf(stdout, "\n--snap=<i> or -n <i>\tSet the pcap snap length to <i>. Default=%d.\n", SNAPLEN);
1075 fprintf(stdout, "\t\t\tThis specifies the frame capture length. This\n");
1076 fprintf(stdout, "\t\t\tlength includes the data-link header.\n");
1077 fprintf(stdout, "\t\t\tThe default is normally sufficient.\n");
1078 fprintf(stdout, "\n--interface=<s> or -I <s> Use network interface <s>.\n");
1079 fprintf(stdout, "\t\t\tIf this option is not specified, arp-scan will search\n");
1080 fprintf(stdout, "\t\t\tthe system interface list for the lowest numbered,\n");
1081 fprintf(stdout, "\t\t\tconfigured up interface (excluding loopback).\n");
1082 fprintf(stdout, "\t\t\tThe interface specified must support ARP.\n");
1083 fprintf(stdout, "\n--quiet or -q\t\tOnly display minimal output. No protocol decoding.\n");
1084 fprintf(stdout, "\t\t\tIf this option is specified, then only the IP address\n");
1085 fprintf(stdout, "\t\t\tand MAC address are displayed for each responding host.\n");
1086 fprintf(stdout, "\t\t\tNo protocol decoding is performed and the OUI mapping\n");
1087 fprintf(stdout, "\t\t\tfiles are not used.\n");
1088 fprintf(stdout, "\n--plain or -x\t\tDisplay plain output showing only responding hosts.\n");
1089 fprintf(stdout, "\t\t\tThis option suppresses the printing of the header and\n");
1090 fprintf(stdout, "\t\t\tfooter text, and only displays one line for each\n");
1091 fprintf(stdout, "\t\t\tresponding host. Useful if the output will be\n");
1092 fprintf(stdout, "\t\t\tparsed by a script.\n");
1093 fprintf(stdout, "\n--ignoredups or -g\tDon't display duplicate packets.\n");
1094 fprintf(stdout, "\t\t\tBy default, duplicate packets are displayed and are\n");
1095 fprintf(stdout, "\t\t\tflagged with \"(DUP: n)\".\n");
1096 fprintf(stdout, "\n--ouifile=<s> or -O <s>\tUse IEEE Ethernet OUI to vendor mapping file <s>.\n");
1097 fprintf(stdout, "\t\t\tIf this option is not specified, the default filename\n");
1098 fprintf(stdout, "\t\t\tis %s in the current directory. If that is\n", OUIFILENAME);
1099 fprintf(stdout, "\t\t\tnot found, then the file\n");
1100 fprintf(stdout, "\t\t\t%s/%s is used.\n", DATADIR, OUIFILENAME);
1101 fprintf(stdout, "\n--iabfile=<s> or -O <s>\tUse IEEE Ethernet IAB to vendor mapping file <s>.\n");
1102 fprintf(stdout, "\t\t\tIf this option is not specified, the default filename\n");
1103 fprintf(stdout, "\t\t\tis %s in the current directory. If that is\n", IABFILENAME);
1104 fprintf(stdout, "\t\t\tnot found, then the file\n");
1105 fprintf(stdout, "\t\t\t%s/%s is used.\n", DATADIR, IABFILENAME);
1106 fprintf(stdout, "\n--macfile=<s> or -O <s>\tUse custom Ethernet MAC to vendor mapping file <s>.\n");
1107 fprintf(stdout, "\t\t\tIf this option is not specified, the default filename\n");
1108 fprintf(stdout, "\t\t\tis %s in the current directory. If that is\n", MACFILENAME);
1109 fprintf(stdout, "\t\t\tnot found, then the file\n");
1110 fprintf(stdout, "\t\t\t%s/%s is used.\n", DATADIR, MACFILENAME);
1111 fprintf(stdout, "\n--srcaddr=<m> or -S <m> Set the source Ethernet MAC address to <m>.\n");
1112 fprintf(stdout, "\t\t\tThis sets the 48-bit hardware address in the Ethernet\n");
1113 fprintf(stdout, "\t\t\tframe header for outgoing ARP packets. It does not\n");
1114 fprintf(stdout, "\t\t\tchange the hardware address in the ARP packet, see\n");
1115 fprintf(stdout, "\t\t\t--arpsha for details on how to change that address.\n");
1116 fprintf(stdout, "\t\t\tThe default is the Ethernet address of the outgoing\n");
1117 fprintf(stdout, "\t\t\tinterface.\n");
1118 fprintf(stdout, "\n--destaddr=<m> or -T <m> Send the packets to Ethernet MAC address <m>\n");
1119 fprintf(stdout, "\t\t\tThis sets the 48-bit destination address in the\n");
1120 fprintf(stdout, "\t\t\tEthernet frame header.\n");
1121 fprintf(stdout, "\t\t\tThe default is the broadcast address ff:ff:ff:ff:ff:ff.\n");
1122 fprintf(stdout, "\t\t\tMost operating systems will also respond if the ARP\n");
1123 fprintf(stdout, "\t\t\trequest is sent to their MAC address, or to a\n");
1124 fprintf(stdout, "\t\t\tmulticast address that they are listening on.\n");
1125 fprintf(stdout, "\n--arpsha=<m> or -u <m>\tUse <m> as the ARP source Ethernet address\n");
1126 fprintf(stdout, "\t\t\tThis sets the 48-bit ar$sha field in the ARP packet\n");
1127 fprintf(stdout, "\t\t\tIt does not change the hardware address in the frame\n");
1128 fprintf(stdout, "\t\t\theader, see --srcaddr for details on how to change\n");
1129 fprintf(stdout, "\t\t\tthat address. The default is the Ethernet address of\n");
1130 fprintf(stdout, "\t\t\tthe outgoing interface.\n");
1131 fprintf(stdout, "\n--arptha=<m> or -w <m>\tUse <m> as the ARP target Ethernet address\n");
1132 fprintf(stdout, "\t\t\tThis sets the 48-bit ar$tha field in the ARP packet\n");
1133 fprintf(stdout, "\t\t\tThe default is zero, because this field is not used\n");
1134 fprintf(stdout, "\t\t\tfor ARP request packets.\n");
1135 fprintf(stdout, "\n--prototype=<i> or -y <i> Set the Ethernet protocol type to <i>, default=0x%.4x.\n", DEFAULT_ETH_PRO);
1136 fprintf(stdout, "\t\t\tThis sets the 16-bit protocol type field in the\n");
1137 fprintf(stdout, "\t\t\tEthernet frame header.\n");
1138 fprintf(stdout, "\t\t\tSetting this to a non-default value will result in the\n");
1139 fprintf(stdout, "\t\t\tpacket being ignored by the target, or sent to the\n");
1140 fprintf(stdout, "\t\t\twrong protocol stack.\n");
1141 fprintf(stdout, "\n--arphrd=<i> or -H <i>\tUse <i> for the ARP hardware type, default=%d.\n", DEFAULT_ARP_HRD);
1142 fprintf(stdout, "\t\t\tThis sets the 16-bit ar$hrd field in the ARP packet.\n");
1143 fprintf(stdout, "\t\t\tThe normal value is 1 (ARPHRD_ETHER). Most, but not\n");
1144 fprintf(stdout, "\t\t\tall, operating systems will also respond to 6\n");
1145 fprintf(stdout, "\t\t\t(ARPHRD_IEEE802). A few systems respond to any value.\n");
1146 fprintf(stdout, "\n--arppro=<i> or -p <i>\tUse <i> for the ARP protocol type, default=0x%.4x.\n", DEFAULT_ARP_PRO);
1147 fprintf(stdout, "\t\t\tThis sets the 16-bit ar$pro field in the ARP packet.\n");
1148 fprintf(stdout, "\t\t\tMost operating systems only respond to 0x0800 (IPv4)\n");
1149 fprintf(stdout, "\t\t\tbut some will respond to other values as well.\n");
1150 fprintf(stdout, "\n--arphln=<i> or -a <i>\tSet the hardware address length to <i>, default=%d.\n", DEFAULT_ARP_HLN);
1151 fprintf(stdout, "\t\t\tThis sets the 8-bit ar$hln field in the ARP packet.\n");
1152 fprintf(stdout, "\t\t\tIt sets the claimed length of the hardware address\n");
1153 fprintf(stdout, "\t\t\tin the ARP packet. Setting it to any value other than\n");
1154 fprintf(stdout, "\t\t\tthe default will make the packet non RFC compliant.\n");
1155 fprintf(stdout, "\t\t\tSome operating systems may still respond to it though.\n");
1156 fprintf(stdout, "\t\t\tNote that the actual lengths of the ar$sha and ar$tha\n");
1157 fprintf(stdout, "\t\t\tfields in the ARP packet are not changed by this\n");
1158 fprintf(stdout, "\t\t\toption; it only changes the ar$hln field.\n");
1159 fprintf(stdout, "\n--arppln=<i> or -P <i>\tSet the protocol address length to <i>, default=%d.\n", DEFAULT_ARP_PLN);
1160 fprintf(stdout, "\t\t\tThis sets the 8-bit ar$pln field in the ARP packet.\n");
1161 fprintf(stdout, "\t\t\tIt sets the claimed length of the protocol address\n");
1162 fprintf(stdout, "\t\t\tin the ARP packet. Setting it to any value other than\n");
1163 fprintf(stdout, "\t\t\tthe default will make the packet non RFC compliant.\n");
1164 fprintf(stdout, "\t\t\tSome operating systems may still respond to it though.\n");
1165 fprintf(stdout, "\t\t\tNote that the actual lengths of the ar$spa and ar$tpa\n");
1166 fprintf(stdout, "\t\t\tfields in the ARP packet are not changed by this\n");
1167 fprintf(stdout, "\t\t\toption; it only changes the ar$pln field.\n");
1168 fprintf(stdout, "\n--arpop=<i> or -o <i>\tUse <i> for the ARP operation, default=%d.\n", DEFAULT_ARP_OP);
1169 fprintf(stdout, "\t\t\tThis sets the 16-bit ar$op field in the ARP packet.\n");
1170 fprintf(stdout, "\t\t\tMost operating systems will only respond to the value 1\n");
1171 fprintf(stdout, "\t\t\t(ARPOP_REQUEST). However, some systems will respond\n");
1172 fprintf(stdout, "\t\t\tto other values as well.\n");
1173 fprintf(stdout, "\n--arpspa=<a> or -s <a>\tUse <a> as the source IP address.\n");
1174 fprintf(stdout, "\t\t\tThe address should be specified in dotted quad format;\n");
1175 fprintf(stdout, "\t\t\tor the literal string \"dest\", which sets the source\n");
1176 fprintf(stdout, "\t\t\taddress to be the same as the target host address.\n");
1177 fprintf(stdout, "\t\t\tThis sets the 32-bit ar$spa field in the ARP packet.\n");
1178 fprintf(stdout, "\t\t\tSome operating systems check this, and will only\n");
1179 fprintf(stdout, "\t\t\trespond if the source address is within the network\n");
1180 fprintf(stdout, "\t\t\tof the receiving interface. Others don't care, and\n");
1181 fprintf(stdout, "\t\t\twill respond to any source address.\n");
1182 fprintf(stdout, "\t\t\tBy default, the outgoing interface address is used.\n");
1183 fprintf(stdout, "\n\t\t\tWARNING: Setting ar$spa to the destination IP address\n");
1184 fprintf(stdout, "\t\t\tcan disrupt some operating systems, as they assume\n");
1185 fprintf(stdout, "\t\t\tthere is an IP address clash if they receive an ARP\n");
1186 fprintf(stdout, "\t\t\trequest for their own address.\n");
1187 fprintf(stdout, "\n--padding=<h> or -A <h>\tSpecify padding after packet data.\n");
1188 fprintf(stdout, "\t\t\tSet the padding data to hex value <h>. This data is\n");
1189 fprintf(stdout, "\t\t\tappended to the end of the ARP packet, after the data.\n");
1190 fprintf(stdout, "\t\t\tMost, if not all, operating systems will ignore any\n");
1191 fprintf(stdout, "\t\t\tpadding. The default is no padding, although the\n");
1192 fprintf(stdout, "\t\t\tEthernet driver on the sending system may pad the\n");
1193 fprintf(stdout, "\t\t\tpacket to the minimum Ethernet frame length.\n");
1194 fprintf(stdout, "\n--llc or -L\t\tUse RFC 1042 LLC framing with SNAP.\n");
1195 fprintf(stdout, "\t\t\tThis option causes the outgoing ARP packets to use\n");
1196 fprintf(stdout, "\t\t\tIEEE 802.2 framing with a SNAP header as described\n");
1197 fprintf(stdout, "\t\t\tin RFC 1042. The default is to use Ethernet-II\n");
1198 fprintf(stdout, "\t\t\tframing.\n");
1199 fprintf(stdout, "\t\t\tarp-scan will decode and display received ARP packets\n");
1200 fprintf(stdout, "\t\t\tin either Ethernet-II or IEEE 802.2 formats\n");
1201 fprintf(stdout, "\t\t\tirrespective of this option.\n");
1202 fprintf(stdout, "\n--vlan=<i> or -Q <i>\tUse 802.1Q tagging with VLAN id <i>.\n");
1203 fprintf(stdout, "\t\t\tThis option causes the outgoing ARP packets to use\n");
1204 fprintf(stdout, "\t\t\t802.1Q VLAN tagging with a VLAN ID of <i>, which should\n");
1205 fprintf(stdout, "\t\t\tbe in the range 0 to 4095 inclusive.\n");
1206 fprintf(stdout, "\t\t\tarp-scan will always decode and display received ARP\n");
1207 fprintf(stdout, "\t\t\tpackets in 802.1Q format irrespective of this option.\n");
1208 fprintf(stdout, "\n--pcapsavefile=<s> or -W <s>\tWrite received packets to pcap savefile <s>.\n");
1209 fprintf(stdout, "\t\t\tThis option causes received ARP responses to be written\n");
1210 fprintf(stdout, "\t\t\tto the specified pcap savefile as well as being decoded\n");
1211 fprintf(stdout, "\t\t\tand displayed. This savefile can be analysed with\n");
1212 fprintf(stdout, "\t\t\tprograms that understand the pcap file format, such as\n");
1213 fprintf(stdout, "\t\t\t\"tcpdump\" and \"wireshark\".\n");
1214 fprintf(stdout, "\n--rtt or -D\t\tDisplay the packet round-trip time.\n");
1215 } else {
1216 fprintf(stdout, "use \"arp-scan --help\" for detailed information on the available options.\n");
1217 }
1218 fprintf(stdout, "\n");
1219 fprintf(stdout, "Report bugs or send suggestions at %s\n", PACKAGE_BUGREPORT);
1220 fprintf(stdout, "See the arp-scan homepage at https://github.com/royhills/arp-scan\n");
1221 exit(status);
1222 }
1223
1224 /*
1225 * add_host_pattern -- Add one or more new host to the list.
1226 *
1227 * Inputs:
1228 *
1229 * pattern = The host pattern to add.
1230 * host_timeout = Per-host timeout in ms.
1231 *
1232 * Returns: None
1233 *
1234 * This adds one or more new hosts to the list. The pattern argument
1235 * can either be a single host or IP address, in which case one host
1236 * will be added to the list, or it can specify a number of hosts with
1237 * the IPnet/bits or IPstart-IPend formats.
1238 *
1239 * The host_timeout and num_hosts arguments are passed unchanged to
1240 * add_host().
1241 */
1242 void
add_host_pattern(const char * pattern,unsigned host_timeout)1243 add_host_pattern(const char *pattern, unsigned host_timeout) {
1244 char *patcopy;
1245 struct in_addr in_val;
1246 struct in_addr mask_val;
1247 unsigned numbits;
1248 char *cp;
1249 uint32_t ipnet_val;
1250 uint32_t network;
1251 uint32_t mask;
1252 unsigned long hoststart;
1253 unsigned long hostend;
1254 unsigned i;
1255 uint32_t x;
1256 static int first_call=1;
1257 static regex_t iprange_pat;
1258 static regex_t ipslash_pat;
1259 static regex_t ipmask_pat;
1260 static const char *iprange_pat_str =
1261 "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+-[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+";
1262 static const char *ipslash_pat_str =
1263 "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+/[0-9]+";
1264 static const char *ipmask_pat_str =
1265 "[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+:[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+";
1266 /*
1267 * Compile regex patterns if this is the first time we've been called.
1268 */
1269 if (first_call) {
1270 int result;
1271
1272 first_call = 0;
1273 if ((result=regcomp(&iprange_pat, iprange_pat_str,
1274 REG_EXTENDED|REG_NOSUB))) {
1275 char errbuf[MAXLINE];
1276 regerror(result, &iprange_pat, errbuf, MAXLINE);
1277 err_msg("ERROR: cannot compile regex pattern \"%s\": %s",
1278 iprange_pat_str, errbuf);
1279 }
1280 if ((result=regcomp(&ipslash_pat, ipslash_pat_str,
1281 REG_EXTENDED|REG_NOSUB))) {
1282 char errbuf[MAXLINE];
1283 regerror(result, &ipslash_pat, errbuf, MAXLINE);
1284 err_msg("ERROR: cannot compile regex pattern \"%s\": %s",
1285 ipslash_pat_str, errbuf);
1286 }
1287 if ((result=regcomp(&ipmask_pat, ipmask_pat_str,
1288 REG_EXTENDED|REG_NOSUB))) {
1289 char errbuf[MAXLINE];
1290 regerror(result, &ipmask_pat, errbuf, MAXLINE);
1291 err_msg("ERROR: cannot compile regex pattern \"%s\": %s",
1292 ipmask_pat_str, errbuf);
1293 }
1294 }
1295 /*
1296 * Make a copy of pattern because we don't want to modify our argument.
1297 */
1298 patcopy = dupstr(pattern);
1299
1300 if (!(regexec(&ipslash_pat, patcopy, 0, NULL, 0))) { /* IPnet/bits */
1301 /*
1302 * Get IPnet and bits as integers. Perform basic error checking.
1303 */
1304 cp=strchr(patcopy, '/');
1305 *(cp++)='\0'; /* patcopy points to IPnet, cp points to bits */
1306 if (!(inet_aton(patcopy, &in_val)))
1307 err_msg("ERROR: %s is not a valid IP address", patcopy);
1308 ipnet_val=ntohl(in_val.s_addr); /* We need host byte order */
1309 numbits=Strtoul(cp, 10);
1310 if (numbits<3 || numbits>32)
1311 err_msg("ERROR: Number of bits in %s must be between 3 and 32",
1312 pattern);
1313 /*
1314 * Construct 32-bit network bitmask from number of bits.
1315 */
1316 mask=0;
1317 for (i=0; i<numbits; i++)
1318 mask += 1 << i;
1319 mask = mask << (32-i);
1320 /*
1321 * Mask off the network. Warn if the host bits were non-zero.
1322 */
1323 network=ipnet_val & mask;
1324 if (network != ipnet_val)
1325 warn_msg("WARNING: host part of %s is non-zero", pattern);
1326 /*
1327 * Determine maximum and minimum host values. We include the host
1328 * and broadcast.
1329 */
1330 hoststart=0;
1331 hostend=(1<<(32-numbits))-1;
1332 /*
1333 * Calculate all host addresses in the range and feed to add_host()
1334 * in dotted-quad format.
1335 */
1336 for (i=hoststart; i<=hostend; i++) {
1337 uint32_t hostip;
1338 int b1, b2, b3, b4;
1339 char ipstr[16];
1340
1341 hostip = network+i;
1342 b1 = (hostip & 0xff000000) >> 24;
1343 b2 = (hostip & 0x00ff0000) >> 16;
1344 b3 = (hostip & 0x0000ff00) >> 8;
1345 b4 = (hostip & 0x000000ff);
1346 snprintf(ipstr, sizeof(ipstr), "%d.%d.%d.%d", b1,b2,b3,b4);
1347 add_host(ipstr, host_timeout, 1);
1348 }
1349 } else if (!(regexec(&ipmask_pat, patcopy, 0, NULL, 0))) { /* IPnet:netmask */
1350 /*
1351 * Get IPnet and bits as integers. Perform basic error checking.
1352 */
1353 cp=strchr(patcopy, ':');
1354 *(cp++)='\0'; /* patcopy points to IPnet, cp points to netmask */
1355 if (!(inet_aton(patcopy, &in_val)))
1356 err_msg("ERROR: %s is not a valid IP address", patcopy);
1357 ipnet_val=ntohl(in_val.s_addr); /* We need host byte order */
1358 if (!(inet_aton(cp, &mask_val)))
1359 err_msg("ERROR: %s is not a valid netmask", patcopy);
1360 mask=ntohl(mask_val.s_addr); /* We need host byte order */
1361 /*
1362 * Calculate the number of bits in the network.
1363 */
1364 x = mask;
1365 for (numbits=0; x != 0; x>>=1) {
1366 if (x & 0x01) {
1367 numbits++;
1368 }
1369 }
1370 /*
1371 * Mask off the network. Warn if the host bits were non-zero.
1372 */
1373 network=ipnet_val & mask;
1374 if (network != ipnet_val)
1375 warn_msg("WARNING: host part of %s is non-zero", pattern);
1376 /*
1377 * Determine maximum and minimum host values. We include the host
1378 * and broadcast.
1379 */
1380 hoststart=0;
1381 hostend=(1<<(32-numbits))-1;
1382 /*
1383 * Calculate all host addresses in the range and feed to add_host()
1384 * in dotted-quad format.
1385 */
1386 for (i=hoststart; i<=hostend; i++) {
1387 uint32_t hostip;
1388 int b1, b2, b3, b4;
1389 char ipstr[16];
1390
1391 hostip = network+i;
1392 b1 = (hostip & 0xff000000) >> 24;
1393 b2 = (hostip & 0x00ff0000) >> 16;
1394 b3 = (hostip & 0x0000ff00) >> 8;
1395 b4 = (hostip & 0x000000ff);
1396 snprintf(ipstr, sizeof(ipstr), "%d.%d.%d.%d", b1,b2,b3,b4);
1397 add_host(ipstr, host_timeout, 1);
1398 }
1399 } else if (!(regexec(&iprange_pat, patcopy, 0, NULL, 0))) { /* IPstart-IPend */
1400 /*
1401 * Get IPstart and IPend as integers.
1402 */
1403 cp=strchr(patcopy, '-');
1404 *(cp++)='\0'; /* patcopy points to IPstart, cp points to IPend */
1405 if (!(inet_aton(patcopy, &in_val)))
1406 err_msg("ERROR: %s is not a valid IP address", patcopy);
1407 hoststart=ntohl(in_val.s_addr); /* We need host byte order */
1408 if (!(inet_aton(cp, &in_val)))
1409 err_msg("ERROR: %s is not a valid IP address", cp);
1410 hostend=ntohl(in_val.s_addr); /* We need host byte order */
1411 /*
1412 * Calculate all host addresses in the range and feed to add_host()
1413 * in dotted-quad format.
1414 */
1415 for (i=hoststart; i<=hostend; i++) {
1416 int b1, b2, b3, b4;
1417 char ipstr[16];
1418
1419 b1 = (i & 0xff000000) >> 24;
1420 b2 = (i & 0x00ff0000) >> 16;
1421 b3 = (i & 0x0000ff00) >> 8;
1422 b4 = (i & 0x000000ff);
1423 snprintf(ipstr, sizeof(ipstr), "%d.%d.%d.%d", b1,b2,b3,b4);
1424 add_host(ipstr, host_timeout, 1);
1425 }
1426 } else { /* Single host or IP address */
1427 add_host(patcopy, host_timeout, numeric_flag);
1428 }
1429 free(patcopy);
1430 }
1431
1432 /*
1433 * add_host -- Add a new host to the list.
1434 *
1435 * Inputs:
1436 *
1437 * host_name = The Name or IP address of the host.
1438 * host_timeout = The initial host timeout in ms.
1439 * numeric_only = 1 if the host name is definitely an IP address in
1440 * dotted quad format, or 0 if it may be a hostname or
1441 * IP address.
1442 *
1443 * Returns:
1444 *
1445 * None.
1446 *
1447 * This function is called before the helistptr array is created, so
1448 * we use the helist array directly.
1449 */
1450 void
add_host(const char * host_name,unsigned host_timeout,int numeric_only)1451 add_host(const char *host_name, unsigned host_timeout, int numeric_only) {
1452 struct in_addr *hp=NULL;
1453 struct in_addr addr;
1454 host_entry *he;
1455 static int num_left=0; /* Number of free entries left */
1456 int result;
1457 char *ga_err_msg;
1458
1459 if (numeric_only) {
1460 result = inet_pton(AF_INET, host_name, &addr);
1461 if (result < 0) {
1462 err_sys("ERROR: inet_pton failed for %s", host_name);
1463 } else if (result == 0) {
1464 warn_msg("WARNING: \"%s\" is not a valid IPv4 address - target ignored", host_name);
1465 return;
1466 }
1467 } else {
1468 hp = get_host_address(host_name, AF_INET, &addr, &ga_err_msg);
1469 if (hp == NULL) {
1470 warn_msg("WARNING: get_host_address failed for \"%s\": %s - target ignored",
1471 host_name, ga_err_msg);
1472 return;
1473 }
1474 }
1475
1476 if (!num_left) { /* No entries left, allocate some more */
1477 if (helist)
1478 helist=Realloc(helist, (num_hosts * sizeof(host_entry)) +
1479 REALLOC_COUNT*sizeof(host_entry));
1480 else
1481 helist=Malloc(REALLOC_COUNT*sizeof(host_entry));
1482 num_left = REALLOC_COUNT;
1483 }
1484
1485 he = helist + num_hosts; /* Would array notation be better? */
1486 num_hosts++;
1487 num_left--;
1488
1489 memcpy(&(he->addr), &addr, sizeof(struct in_addr));
1490 he->live = 1;
1491 he->timeout = host_timeout * 1000; /* Convert from ms to us */
1492 he->num_sent = 0;
1493 he->num_recv = 0;
1494 he->last_send_time.tv_sec=0;
1495 he->last_send_time.tv_usec=0;
1496 }
1497
1498 /*
1499 * remove_host -- Remove the specified host from the list
1500 *
1501 * inputs:
1502 *
1503 * he = Pointer to host entry to remove.
1504 *
1505 * Returns:
1506 *
1507 * None.
1508 *
1509 * If the host being removed is the one pointed to by the cursor, this
1510 * function updates cursor so that it points to the next entry.
1511 */
1512 void
remove_host(host_entry ** he)1513 remove_host(host_entry **he) {
1514 if ((*he)->live) {
1515 (*he)->live = 0;
1516 live_count--;
1517 if (*he == *cursor)
1518 advance_cursor();
1519 } else {
1520 if (verbose > 1)
1521 warn_msg("***\tremove_host called on non-live host: SHOULDN'T HAPPEN");
1522 }
1523 }
1524
1525 /*
1526 * advance_cursor -- Advance the cursor to point at next live entry
1527 *
1528 * Inputs:
1529 *
1530 * None.
1531 *
1532 * Returns:
1533 *
1534 * None.
1535 *
1536 * Does nothing if there are no live entries in the list.
1537 */
1538 void
advance_cursor(void)1539 advance_cursor(void) {
1540 if (live_count) {
1541 do {
1542 if (cursor == (helistptr+(num_hosts-1)))
1543 cursor = helistptr; /* Wrap round to beginning */
1544 else
1545 cursor++;
1546 } while (!(*cursor)->live);
1547 } /* End If */
1548 }
1549
1550 /*
1551 * find_host -- Find a host in the list
1552 *
1553 * Inputs:
1554 *
1555 * he Pointer to the current position in the list. Search runs
1556 * backwards starting from this point.
1557 * addr The source IP address that the packet came from.
1558 *
1559 * Returns a pointer to the host entry associated with the specified IP
1560 * or NULL if no match found.
1561 *
1562 * This routine finds the host by IP address by comparing "addr" against
1563 * "he->addr" for each entry in the list.
1564 */
1565 host_entry *
find_host(host_entry ** he,struct in_addr * addr)1566 find_host(host_entry **he, struct in_addr *addr) {
1567 host_entry **p;
1568 int found = 0;
1569 unsigned iterations = 0; /* Used for debugging */
1570 /*
1571 * Don't try to match if host ptr is NULL.
1572 * This should never happen, but we check just in case.
1573 */
1574 if (*he == NULL) {
1575 return NULL;
1576 }
1577 /*
1578 * Try to match against out host list.
1579 */
1580 p = he;
1581
1582 do {
1583 iterations++;
1584 if ((*p)->addr.s_addr == addr->s_addr) {
1585 found = 1;
1586 } else {
1587 if (p == helistptr) {
1588 p = helistptr + (num_hosts-1); /* Wrap round to end */
1589 } else {
1590 p--;
1591 }
1592 }
1593 } while (!found && p != he);
1594
1595
1596 if (found)
1597 return *p;
1598 else
1599 return NULL;
1600 }
1601
1602 /*
1603 * recvfrom_wto -- Receive packet with timeout
1604 *
1605 * Inputs:
1606 *
1607 * sock_fd = Socket file descriptor.
1608 * tmo = Select timeout in us.
1609 * pcap_handle = pcap handle
1610 *
1611 * Returns:
1612 *
1613 * None.
1614 *
1615 * If the socket file descriptor is -1, this indicates that we are
1616 * reading packets from a pcap file and there is no associated network
1617 * device.
1618 */
1619 void
recvfrom_wto(int sock_fd,int tmo,pcap_t * pcap_handle)1620 recvfrom_wto(int sock_fd, int tmo, pcap_t *pcap_handle) {
1621 fd_set readset;
1622 struct timeval to;
1623 int n;
1624
1625 FD_ZERO(&readset);
1626 if (sock_fd >= 0)
1627 FD_SET(sock_fd, &readset);
1628 to.tv_sec = tmo/1000000;
1629 to.tv_usec = (tmo - 1000000*to.tv_sec);
1630 n = select(sock_fd+1, &readset, NULL, NULL, &to);
1631 if (n < 0) {
1632 err_sys("select");
1633 } else if (n == 0 && sock_fd >= 0) {
1634 return; /* Timeout */
1635 }
1636 /*
1637 * Call pcap_dispatch() to process the packet if we are reading packets.
1638 */
1639 if (pcap_handle) {
1640 if ((pcap_dispatch(pcap_handle, -1, callback, NULL)) == -1)
1641 err_sys("pcap_dispatch: %s\n", pcap_geterr(pcap_handle));
1642 }
1643 }
1644
1645 /*
1646 * dump_list -- Display contents of host list for debugging
1647 *
1648 * Inputs:
1649 *
1650 * None.
1651 *
1652 * Returns:
1653 *
1654 * None.
1655 */
1656 void
dump_list(void)1657 dump_list(void) {
1658 unsigned i;
1659
1660 printf("Host List:\n\n");
1661 printf("Entry\tIP Address\n");
1662 for (i=0; i<num_hosts; i++)
1663 printf("%u\t%s\n", i+1, my_ntoa(helistptr[i]->addr));
1664 printf("\nTotal of %u host entries.\n\n", num_hosts);
1665 }
1666
1667 /*
1668 * callback -- pcap callback function
1669 *
1670 * Inputs:
1671 *
1672 * args Special args (not used)
1673 * header pcap header structure
1674 * packet_in The captured packet
1675 *
1676 * Returns:
1677 *
1678 * None
1679 */
1680 void
callback(u_char * args ATTRIBUTE_UNUSED,const struct pcap_pkthdr * header,const u_char * packet_in)1681 callback(u_char *args ATTRIBUTE_UNUSED,
1682 const struct pcap_pkthdr *header, const u_char *packet_in) {
1683 arp_ether_ipv4 arpei;
1684 ether_hdr frame_hdr;
1685 int n = header->caplen;
1686 struct in_addr source_ip;
1687 host_entry *temp_cursor;
1688 unsigned char extra_data[MAX_FRAME];
1689 size_t extra_data_len;
1690 int vlan_id;
1691 int framing;
1692 /*
1693 * Check that the packet is large enough to decode.
1694 */
1695 if (n < ETHER_HDR_SIZE + ARP_PKT_SIZE) {
1696 printf("%d byte packet too short to decode\n", n);
1697 return;
1698 }
1699 /*
1700 * Unmarshal packet buffer into structures and determine framing type
1701 */
1702 framing = unmarshal_arp_pkt(packet_in, n, &frame_hdr, &arpei, extra_data,
1703 &extra_data_len, &vlan_id);
1704 /*
1705 * Determine source IP address.
1706 */
1707 source_ip.s_addr = arpei.ar_sip;
1708 /*
1709 * We've received a response. Try to match up the packet by IP address
1710 *
1711 * We should really start searching at the host before the cursor, as we
1712 * know that the host to match cannot be the one at the cursor position
1713 * because we call advance_cursor() after sending each packet. However,
1714 * the time saved is minimal, and it's not worth the extra complexity.
1715 */
1716 temp_cursor=find_host(cursor, &source_ip);
1717 if (temp_cursor) {
1718 /*
1719 * We found an IP match for the packet.
1720 */
1721 /*
1722 * Display the packet and increment the number of responders if
1723 * the entry is "live" or we are not ignoring duplicates.
1724 */
1725 temp_cursor->num_recv++;
1726 if (verbose > 1)
1727 warn_msg("---\tReceived packet #%u from %s",
1728 temp_cursor->num_recv ,my_ntoa(source_ip));
1729 if ((temp_cursor->live || !ignore_dups)) {
1730 if (pcap_dump_handle) {
1731 pcap_dump((unsigned char *)pcap_dump_handle, header, packet_in);
1732 }
1733 display_packet(temp_cursor, &arpei, extra_data, extra_data_len,
1734 framing, vlan_id, &frame_hdr, header);
1735 responders++;
1736 }
1737 if (verbose > 1)
1738 warn_msg("---\tRemoving host %s - Received %d bytes",
1739 my_ntoa(source_ip), n);
1740 remove_host(&temp_cursor);
1741 } else {
1742 /*
1743 * The received packet is not from an IP address in the list
1744 * Issue a message to that effect and ignore the packet.
1745 */
1746 if (verbose)
1747 warn_msg("---\tIgnoring %d bytes from unknown host %s", n, my_ntoa(source_ip));
1748 }
1749 }
1750
1751 /*
1752 * process_options -- Process options and arguments.
1753 *
1754 * Inputs:
1755 *
1756 * argc Command line arg count
1757 * argv Command line args
1758 *
1759 * Returns:
1760 *
1761 * None.
1762 */
1763 void
process_options(int argc,char * argv[])1764 process_options(int argc, char *argv[]) {
1765 struct option long_options[] = {
1766 {"file", required_argument, 0, 'f'},
1767 {"help", no_argument, 0, 'h'},
1768 {"retry", required_argument, 0, 'r'},
1769 {"timeout", required_argument, 0, 't'},
1770 {"interval", required_argument, 0, 'i'},
1771 {"backoff", required_argument, 0, 'b'},
1772 {"verbose", no_argument, 0, 'v'},
1773 {"version", no_argument, 0, 'V'},
1774 {"snap", required_argument, 0, 'n'},
1775 {"interface", required_argument, 0, 'I'},
1776 {"quiet", no_argument, 0, 'q'},
1777 {"ignoredups", no_argument, 0, 'g'},
1778 {"random", no_argument, 0, 'R'},
1779 {"numeric", no_argument, 0, 'N'},
1780 {"bandwidth", required_argument, 0, 'B'},
1781 {"ouifile", required_argument, 0, 'O'},
1782 {"iabfile", required_argument, 0, 'F'},
1783 {"macfile", required_argument, 0, 'm'},
1784 {"arpspa", required_argument, 0, 's'},
1785 {"arpop", required_argument, 0, 'o'},
1786 {"arphrd", required_argument, 0, 'H'},
1787 {"arppro", required_argument, 0, 'p'},
1788 {"destaddr", required_argument, 0, 'T'},
1789 {"arppln", required_argument, 0, 'P'},
1790 {"arphln", required_argument, 0, 'a'},
1791 {"padding", required_argument, 0, 'A'},
1792 {"prototype", required_argument, 0, 'y'},
1793 {"arpsha", required_argument, 0, 'u'},
1794 {"arptha", required_argument, 0, 'w'},
1795 {"srcaddr", required_argument, 0, 'S'},
1796 {"localnet", no_argument, 0, 'l'},
1797 {"llc", no_argument, 0, 'L'},
1798 {"vlan", required_argument, 0, 'Q'},
1799 {"pcapsavefile", required_argument, 0, 'W'},
1800 {"writepkttofile", required_argument, 0, OPT_WRITEPKTTOFILE},
1801 {"readpktfromfile", required_argument, 0, OPT_READPKTFROMFILE},
1802 {"rtt", no_argument, 0, 'D'},
1803 {"plain", no_argument, 0, 'x'},
1804 {"randomseed", required_argument, 0, OPT_RANDOMSEED},
1805 {0, 0, 0, 0}
1806 };
1807 /*
1808 * available short option characters:
1809 *
1810 * lower: --cde----jk--------------z
1811 * UPPER: --C-E-G--JK-M-------U--XYZ
1812 * Digits: 0123456789
1813 */
1814 const char *short_options =
1815 "f:hr:t:i:b:vVn:I:qgRNB:O:s:o:H:p:T:P:a:A:y:u:w:S:F:m:lLQ:W:Dx";
1816 int arg;
1817 int options_index=0;
1818
1819 while ((arg=getopt_long_only(argc, argv, short_options, long_options, &options_index)) != -1) {
1820 switch (arg) {
1821 struct in_addr source_ip_address;
1822 int result;
1823
1824 case 'f': /* --file */
1825 strlcpy(filename, optarg, sizeof(filename));
1826 filename_flag=1;
1827 break;
1828 case 'h': /* --help */
1829 usage(EXIT_SUCCESS, 1);
1830 break; /* NOTREACHED */
1831 case 'r': /* --retry */
1832 retry=Strtoul(optarg, 10);
1833 break;
1834 case 't': /* --timeout */
1835 timeout=Strtoul(optarg, 10);
1836 break;
1837 case 'i': /* --interval */
1838 interval=str_to_interval(optarg);
1839 break;
1840 case 'b': /* --backoff */
1841 backoff_factor=atof(optarg);
1842 break;
1843 case 'v': /* --verbose */
1844 verbose++;
1845 break;
1846 case 'V': /* --version */
1847 arp_scan_version();
1848 exit(0);
1849 break; /* NOTREACHED */
1850 case 'n': /* --snap */
1851 snaplen=Strtol(optarg, 0);
1852 break;
1853 case 'I': /* --interface */
1854 if_name = make_message("%s", optarg);
1855 break;
1856 case 'q': /* --quiet */
1857 quiet_flag=1;
1858 break;
1859 case 'g': /* --ignoredups */
1860 ignore_dups=1;
1861 break;
1862 case 'R': /* --random */
1863 random_flag=1;
1864 break;
1865 case 'N': /* --numeric */
1866 numeric_flag=1;
1867 break;
1868 case 'B': /* --bandwidth */
1869 bandwidth=str_to_bandwidth(optarg);
1870 break;
1871 case 'O': /* --ouifile */
1872 strlcpy(ouifilename, optarg, sizeof(ouifilename));
1873 break;
1874 case 'F': /* --iabfile */
1875 strlcpy(iabfilename, optarg, sizeof(iabfilename));
1876 break;
1877 case 'm': /* --macfile */
1878 strlcpy(macfilename, optarg, sizeof(macfilename));
1879 break;
1880 case 's': /* --arpspa */
1881 arp_spa_flag = 1;
1882 if ((strcmp(optarg,"dest")) == 0) {
1883 arp_spa_is_tpa = 1;
1884 } else {
1885 if ((inet_pton(AF_INET, optarg, &source_ip_address)) <= 0)
1886 err_sys("inet_pton failed for %s", optarg);
1887 memcpy(&arp_spa, &(source_ip_address.s_addr), sizeof(arp_spa));
1888 }
1889 break;
1890 case 'o': /* --arpop */
1891 arp_op=Strtol(optarg, 0);
1892 break;
1893 case 'H': /* --arphrd */
1894 arp_hrd=Strtol(optarg, 0);
1895 break;
1896 case 'p': /* --arppro */
1897 arp_pro=Strtol(optarg, 0);
1898 break;
1899 case 'T': /* --destaddr */
1900 result = get_ether_addr(optarg, target_mac);
1901 if (result != 0)
1902 err_msg("Invalid target MAC address: %s", optarg);
1903 break;
1904 case 'P': /* --arppln */
1905 arp_pln=Strtol(optarg, 0);
1906 break;
1907 case 'a': /* --arphln */
1908 arp_hln=Strtol(optarg, 0);
1909 break;
1910 case 'A': /* --padding */
1911 if (strlen(optarg) % 2) /* Length is odd */
1912 err_msg("ERROR: Length of --padding argument must be even (multiple of 2).");
1913 padding=hex2data(optarg, &padding_len);
1914 break;
1915 case 'y': /* --prototype */
1916 eth_pro=Strtol(optarg, 0);
1917 break;
1918 case 'u': /* --arpsha */
1919 result = get_ether_addr(optarg, arp_sha);
1920 if (result != 0)
1921 err_msg("Invalid source MAC address: %s", optarg);
1922 arp_sha_flag = 1;
1923 break;
1924 case 'w': /* --arptha */
1925 result = get_ether_addr(optarg, arp_tha);
1926 if (result != 0)
1927 err_msg("Invalid target MAC address: %s", optarg);
1928 break;
1929 case 'S': /* --srcaddr */
1930 result = get_ether_addr(optarg, source_mac);
1931 if (result != 0)
1932 err_msg("Invalid target MAC address: %s", optarg);
1933 source_mac_flag = 1;
1934 break;
1935 case 'l': /* --localnet */
1936 localnet_flag = 1;
1937 break;
1938 case 'L': /* --llc */
1939 llc_flag = 1;
1940 break;
1941 case 'Q': /* --vlan */
1942 ieee_8021q_vlan = Strtol(optarg, 0);
1943 break;
1944 case 'W': /* --pcapsavefile */
1945 strlcpy(pcap_savefile, optarg, sizeof(pcap_savefile));
1946 break;
1947 case OPT_WRITEPKTTOFILE: /* --writepkttofile */
1948 strlcpy(pkt_filename, optarg, sizeof(pkt_filename));
1949 pkt_write_file_flag=1;
1950 break;
1951 case OPT_READPKTFROMFILE: /* --readpktfromfile */
1952 strlcpy(pkt_filename, optarg, sizeof(pkt_filename));
1953 pkt_read_file_flag=1;
1954 break;
1955 case 'D': /* --rtt */
1956 rtt_flag = 1;
1957 break;
1958 case 'x': /* --plain */
1959 plain_flag = 1;
1960 break;
1961 case OPT_RANDOMSEED: /* --randomseed */
1962 random_seed=Strtoul(optarg, 0);
1963 break;
1964 default: /* Unknown option */
1965 usage(EXIT_FAILURE, 0);
1966 break; /* NOTREACHED */
1967 }
1968 }
1969 }
1970
1971 /*
1972 * arp_scan_version -- display version information
1973 *
1974 * Inputs:
1975 *
1976 * None.
1977 *
1978 * Returns:
1979 *
1980 * None.
1981 *
1982 * This displays the arp-scan version information.
1983 */
1984 void
arp_scan_version(void)1985 arp_scan_version (void) {
1986 fprintf(stdout, "%s\n\n", PACKAGE_STRING);
1987 fprintf(stdout, "Copyright (C) 2005-2019 Roy Hills, NTA Monitor Ltd.\n");
1988 fprintf(stdout, "arp-scan comes with NO WARRANTY to the extent permitted by law.\n");
1989 fprintf(stdout, "You may redistribute copies of arp-scan under the terms of the GNU\n");
1990 fprintf(stdout, "General Public License.\n");
1991 fprintf(stdout, "For more information about these matters, see the file named COPYING.\n");
1992 fprintf(stdout, "\n");
1993 fprintf(stdout, "%s\n", pcap_lib_version());
1994 }
1995
1996 /*
1997 * get_host_address -- Obtain target host IP address
1998 *
1999 * Inputs:
2000 *
2001 * name The name to lookup
2002 * af The address family
2003 * addr Pointer to the IP address buffer
2004 * error_msg The error message, or NULL if no problem.
2005 *
2006 * Returns:
2007 *
2008 * Pointer to the IP address, or NULL if an error occurred.
2009 *
2010 * This function is basically a wrapper for getaddrinfo().
2011 */
2012 struct in_addr *
get_host_address(const char * name,int af,struct in_addr * addr,char ** error_msg)2013 get_host_address(const char *name, int af, struct in_addr *addr,
2014 char **error_msg) {
2015 static char err[MAXLINE];
2016 static struct in_addr ipa;
2017
2018 struct addrinfo *res;
2019 struct addrinfo hints;
2020 struct sockaddr_in sa_in;
2021 int result;
2022
2023 if (addr == NULL) /* Use static storage if no buffer specified */
2024 addr = &ipa;
2025
2026 memset(&hints, '\0', sizeof(hints));
2027 if (af == AF_INET) {
2028 hints.ai_family = AF_INET;
2029 } else {
2030 err_msg("get_host_address: unknown address family: %d", af);
2031 }
2032
2033 result = getaddrinfo(name, NULL, &hints, &res);
2034 if (result != 0) { /* Error occurred */
2035 snprintf(err, MAXLINE, "%s", gai_strerror(result));
2036 *error_msg = err;
2037 return NULL;
2038 }
2039
2040 memcpy(&sa_in, res->ai_addr, sizeof(sa_in));
2041 memcpy(addr, &sa_in.sin_addr, sizeof(struct in_addr));
2042
2043 freeaddrinfo(res);
2044
2045 *error_msg = NULL;
2046 return addr;
2047 }
2048
2049 /*
2050 * my_ntoa -- IPv6 compatible inet_ntoa replacement
2051 *
2052 * Inputs:
2053 *
2054 * addr The IP address
2055 *
2056 * Returns:
2057 *
2058 * Pointer to the string representation of the IP address.
2059 *
2060 * This currently only supports IPv4.
2061 */
2062 const char *
my_ntoa(struct in_addr addr)2063 my_ntoa(struct in_addr addr) {
2064 static char ip_str[MAXLINE];
2065 const char *cp;
2066
2067 cp = inet_ntop(AF_INET, &addr, ip_str, MAXLINE);
2068
2069 return cp;
2070 }
2071
2072 /*
2073 * marshal_arp_pkt -- Marshal ARP packet from struct to buffer
2074 *
2075 * Inputs:
2076 *
2077 * buffer Pointer to the output buffer
2078 * frame_hdr The Ethernet frame header
2079 * arp_pkt The ARP packet
2080 * buf_siz The size of the output buffer
2081 * frame_padding Any padding to add after the ARP payload.
2082 * frame_padding_len The length of the padding.
2083 *
2084 * Returns:
2085 *
2086 * None
2087 */
2088 void
marshal_arp_pkt(unsigned char * buffer,ether_hdr * frame_hdr,arp_ether_ipv4 * arp_pkt,size_t * buf_siz,const unsigned char * frame_padding,size_t frame_padding_len)2089 marshal_arp_pkt(unsigned char *buffer, ether_hdr *frame_hdr,
2090 arp_ether_ipv4 *arp_pkt, size_t *buf_siz,
2091 const unsigned char *frame_padding, size_t frame_padding_len) {
2092 unsigned char llc_snap[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
2093 unsigned char vlan_tag[] = {0x81, 0x00, 0x00, 0x00};
2094 unsigned char *cp;
2095 size_t packet_size;
2096
2097 cp = buffer;
2098 /*
2099 * Set initial packet length to the size of an Ethernet frame using
2100 * Ethernet-II format plus the size of the ARP data. This may be
2101 * increased later by LLC/SNAP frame format or padding after the
2102 * ARP data.
2103 */
2104 packet_size = sizeof(frame_hdr->dest_addr) + sizeof(frame_hdr->src_addr) +
2105 sizeof(frame_hdr->frame_type) +
2106 sizeof(arp_pkt->ar_hrd) + sizeof(arp_pkt->ar_pro) +
2107 sizeof(arp_pkt->ar_hln) + sizeof(arp_pkt->ar_pln) +
2108 sizeof(arp_pkt->ar_op) + sizeof(arp_pkt->ar_sha) +
2109 sizeof(arp_pkt->ar_sip) + sizeof(arp_pkt->ar_tha) +
2110 sizeof(arp_pkt->ar_tip);
2111 /*
2112 * Copy the Ethernet frame header to the buffer.
2113 */
2114 memcpy(cp, &(frame_hdr->dest_addr), sizeof(frame_hdr->dest_addr));
2115 cp += sizeof(frame_hdr->dest_addr);
2116 memcpy(cp, &(frame_hdr->src_addr), sizeof(frame_hdr->src_addr));
2117 cp += sizeof(frame_hdr->src_addr);
2118 /*
2119 * Add 802.1Q tag if we are using VLAN tagging
2120 */
2121 if (ieee_8021q_vlan != -1) {
2122 uint16_t tci;
2123
2124 tci = htons(ieee_8021q_vlan);
2125 memcpy(cp, vlan_tag, sizeof(vlan_tag));
2126 memcpy(cp+2, &tci, sizeof(tci));
2127 cp += sizeof(vlan_tag);
2128 packet_size += sizeof(vlan_tag);
2129 }
2130 if (llc_flag) { /* With 802.2 LLC framing, type field is frame size */
2131 uint16_t frame_size;
2132
2133 frame_size=htons(packet_size + sizeof(llc_snap));
2134 memcpy(cp, &(frame_size), sizeof(frame_size));
2135 } else { /* Normal Ethernet-II framing */
2136 memcpy(cp, &(frame_hdr->frame_type), sizeof(frame_hdr->frame_type));
2137 }
2138 cp += sizeof(frame_hdr->frame_type);
2139 /*
2140 * Add IEEE 802.2 LLC and SNAP fields if we are using LLC frame format.
2141 */
2142 if (llc_flag) {
2143 memcpy(cp, llc_snap, sizeof(llc_snap));
2144 memcpy(cp+6, &(frame_hdr->frame_type), sizeof(frame_hdr->frame_type));
2145 cp += sizeof(llc_snap);
2146 packet_size += sizeof(llc_snap);
2147 }
2148 /*
2149 * Add the ARP data.
2150 */
2151 memcpy(cp, &(arp_pkt->ar_hrd), sizeof(arp_pkt->ar_hrd));
2152 cp += sizeof(arp_pkt->ar_hrd);
2153 memcpy(cp, &(arp_pkt->ar_pro), sizeof(arp_pkt->ar_pro));
2154 cp += sizeof(arp_pkt->ar_pro);
2155 memcpy(cp, &(arp_pkt->ar_hln), sizeof(arp_pkt->ar_hln));
2156 cp += sizeof(arp_pkt->ar_hln);
2157 memcpy(cp, &(arp_pkt->ar_pln), sizeof(arp_pkt->ar_pln));
2158 cp += sizeof(arp_pkt->ar_pln);
2159 memcpy(cp, &(arp_pkt->ar_op), sizeof(arp_pkt->ar_op));
2160 cp += sizeof(arp_pkt->ar_op);
2161 memcpy(cp, &(arp_pkt->ar_sha), sizeof(arp_pkt->ar_sha));
2162 cp += sizeof(arp_pkt->ar_sha);
2163 memcpy(cp, &(arp_pkt->ar_sip), sizeof(arp_pkt->ar_sip));
2164 cp += sizeof(arp_pkt->ar_sip);
2165 memcpy(cp, &(arp_pkt->ar_tha), sizeof(arp_pkt->ar_tha));
2166 cp += sizeof(arp_pkt->ar_tha);
2167 memcpy(cp, &(arp_pkt->ar_tip), sizeof(arp_pkt->ar_tip));
2168 cp += sizeof(arp_pkt->ar_tip);
2169 /*
2170 * Add padding if specified
2171 */
2172 if (frame_padding != NULL) {
2173 size_t safe_padding_len;
2174
2175 safe_padding_len = frame_padding_len;
2176 if (packet_size + frame_padding_len > MAX_FRAME) {
2177 safe_padding_len = MAX_FRAME - packet_size;
2178 }
2179 memcpy(cp, frame_padding, safe_padding_len);
2180 cp += safe_padding_len;
2181 packet_size += safe_padding_len;
2182 }
2183 *buf_siz = packet_size;
2184 }
2185
2186 /*
2187 * unmarshal_arp_pkt -- Un Marshal ARP packet from buffer to struct
2188 *
2189 * Inputs:
2190 *
2191 * buffer Pointer to the input buffer
2192 * buf_len Length of input buffer
2193 * frame_hdr The ethernet frame header
2194 * arp_pkt The arp packet data
2195 * extra_data Any extra data after the ARP data (typically padding)
2196 * extra_data_len Length of extra data
2197 * vlan_id 802.1Q VLAN identifier
2198 *
2199 * Returns:
2200 *
2201 * An integer representing the data link framing:
2202 * 0 = Ethernet-II
2203 * 1 = 802.3 with LLC/SNAP
2204 *
2205 * extra_data and extra_data_len are only calculated and returned if
2206 * extra_data is not NULL.
2207 *
2208 * vlan_id is set to -1 if the packet does not use 802.1Q tagging.
2209 */
2210 int
unmarshal_arp_pkt(const unsigned char * buffer,size_t buf_len,ether_hdr * frame_hdr,arp_ether_ipv4 * arp_pkt,unsigned char * extra_data,size_t * extra_data_len,int * vlan_id)2211 unmarshal_arp_pkt(const unsigned char *buffer, size_t buf_len,
2212 ether_hdr *frame_hdr, arp_ether_ipv4 *arp_pkt,
2213 unsigned char *extra_data, size_t *extra_data_len,
2214 int *vlan_id) {
2215 const unsigned char *cp;
2216 int framing=FRAMING_ETHERNET_II;
2217
2218 cp = buffer;
2219 /*
2220 * Extract the Ethernet frame header data
2221 */
2222 memcpy(&(frame_hdr->dest_addr), cp, sizeof(frame_hdr->dest_addr));
2223 cp += sizeof(frame_hdr->dest_addr);
2224 memcpy(&(frame_hdr->src_addr), cp, sizeof(frame_hdr->src_addr));
2225 cp += sizeof(frame_hdr->src_addr);
2226 /*
2227 * Check for 802.1Q VLAN tagging, indicated by a type code of
2228 * 0x8100 (TPID).
2229 */
2230 if (*cp == 0x81 && *(cp+1) == 0x00) {
2231 uint16_t tci;
2232 cp += 2; /* Skip TPID */
2233 memcpy(&tci, cp, sizeof(tci));
2234 cp += 2; /* Skip TCI */
2235 *vlan_id = ntohs(tci);
2236 *vlan_id &= 0x0fff; /* Mask off PRI and CFI */
2237 } else {
2238 *vlan_id = -1;
2239 }
2240 memcpy(&(frame_hdr->frame_type), cp, sizeof(frame_hdr->frame_type));
2241 cp += sizeof(frame_hdr->frame_type);
2242 /*
2243 * Check for an LLC header with SNAP. If this is present, the 802.2 LLC
2244 * header will contain DSAP=0xAA, SSAP=0xAA, Control=0x03.
2245 * If this 802.2 LLC header is present, skip it and the SNAP header
2246 */
2247 if (*cp == 0xAA && *(cp+1) == 0xAA && *(cp+2) == 0x03) {
2248 cp += 8; /* Skip eight bytes */
2249 framing = FRAMING_LLC_SNAP;
2250 }
2251 /*
2252 * Extract the ARP packet data
2253 */
2254 memcpy(&(arp_pkt->ar_hrd), cp, sizeof(arp_pkt->ar_hrd));
2255 cp += sizeof(arp_pkt->ar_hrd);
2256 memcpy(&(arp_pkt->ar_pro), cp, sizeof(arp_pkt->ar_pro));
2257 cp += sizeof(arp_pkt->ar_pro);
2258 memcpy(&(arp_pkt->ar_hln), cp, sizeof(arp_pkt->ar_hln));
2259 cp += sizeof(arp_pkt->ar_hln);
2260 memcpy(&(arp_pkt->ar_pln), cp, sizeof(arp_pkt->ar_pln));
2261 cp += sizeof(arp_pkt->ar_pln);
2262 memcpy(&(arp_pkt->ar_op), cp, sizeof(arp_pkt->ar_op));
2263 cp += sizeof(arp_pkt->ar_op);
2264 memcpy(&(arp_pkt->ar_sha), cp, sizeof(arp_pkt->ar_sha));
2265 cp += sizeof(arp_pkt->ar_sha);
2266 memcpy(&(arp_pkt->ar_sip), cp, sizeof(arp_pkt->ar_sip));
2267 cp += sizeof(arp_pkt->ar_sip);
2268 memcpy(&(arp_pkt->ar_tha), cp, sizeof(arp_pkt->ar_tha));
2269 cp += sizeof(arp_pkt->ar_tha);
2270 memcpy(&(arp_pkt->ar_tip), cp, sizeof(arp_pkt->ar_tip));
2271 cp += sizeof(arp_pkt->ar_tip);
2272
2273 if (extra_data != NULL) {
2274 int length;
2275
2276 length = buf_len - (cp - buffer);
2277 if (length > 0) { /* Extra data after ARP packet */
2278 memcpy(extra_data, cp, length);
2279 }
2280 *extra_data_len = length;
2281 }
2282
2283 return framing;
2284 }
2285
2286 /*
2287 * add_mac_vendor -- Add MAC/Vendor mappings to the hash table
2288 *
2289 * Inputs:
2290 *
2291 * map_filename The name of the file containing the mappings
2292 *
2293 * Returns:
2294 *
2295 * The number of entries added to the hash table.
2296 */
2297 int
add_mac_vendor(const char * map_filename)2298 add_mac_vendor(const char *map_filename) {
2299 static int first_call=1;
2300 FILE *fp; /* MAC/Vendor file handle */
2301 static const char *oui_pat_str = "([^\t]+)\t[\t ]*([^\t\r\n]+)";
2302 static regex_t oui_pat;
2303 regmatch_t pmatch[3];
2304 size_t key_len;
2305 size_t data_len;
2306 char *key;
2307 char *data;
2308 char line[MAXLINE];
2309 int line_count;
2310 int result;
2311 ENTRY hash_entry;
2312 /*
2313 * Compile the regex pattern if this is the first time we
2314 * have been called.
2315 */
2316 if (first_call) {
2317 first_call=0;
2318 if ((result=regcomp(&oui_pat, oui_pat_str, REG_EXTENDED))) {
2319 char reg_errbuf[MAXLINE];
2320 regerror(result, &oui_pat, reg_errbuf, MAXLINE);
2321 err_msg("ERROR: cannot compile regex pattern \"%s\": %s",
2322 oui_pat_str, reg_errbuf);
2323 }
2324 }
2325 /*
2326 * Open the file.
2327 */
2328 if ((fp = fopen(map_filename, "r")) == NULL) {
2329 warn_sys("WARNING: Cannot open MAC/Vendor file %s", map_filename);
2330 return 0;
2331 }
2332 line_count=0;
2333 /*
2334 *
2335 */
2336 while (fgets(line, MAXLINE, fp)) {
2337 if (line[0] == '#' || line[0] == '\n' || line[0] == '\r')
2338 continue; /* Skip blank lines and comments */
2339 result = regexec(&oui_pat, line, 3, pmatch, 0);
2340 if (result == REG_NOMATCH || pmatch[1].rm_so < 0 || pmatch[2].rm_so < 0) {
2341 warn_msg("WARNING: Could not parse oui: %s", line);
2342 } else if (result != 0) {
2343 char reg_errbuf[MAXLINE];
2344 regerror(result, &oui_pat, reg_errbuf, MAXLINE);
2345 err_msg("ERROR: oui regexec failed: %s", reg_errbuf);
2346 } else {
2347 key_len = pmatch[1].rm_eo - pmatch[1].rm_so;
2348 data_len = pmatch[2].rm_eo - pmatch[2].rm_so;
2349 key=Malloc(key_len+1);
2350 data=Malloc(data_len+1);
2351 /*
2352 * We cannot use strlcpy because the source is not guaranteed to be null
2353 * terminated. Therefore we use strncpy, specifying one less that the total
2354 * length, and manually null terminate the destination.
2355 */
2356 strncpy(key, line+pmatch[1].rm_so, key_len);
2357 key[key_len] = '\0';
2358 strncpy(data, line+pmatch[2].rm_so, data_len);
2359 data[data_len] = '\0';
2360 hash_entry.key = key;
2361 hash_entry.data = data;
2362 if ((hsearch(hash_entry, ENTER)) == NULL) {
2363 warn_msg("hsearch([%s, %s], ENTER)", key, data);
2364 } else {
2365 line_count++;
2366 }
2367 }
2368 }
2369 fclose(fp);
2370 return line_count;
2371 }
2372
2373 /*
2374 * get_mac_vendor_filename -- Determine MAC/Vendor mapping filename
2375 *
2376 * Inputs:
2377 *
2378 * specified_filename The filename specified on the command line
2379 * default_datadir The default data directory
2380 * default_filename The default filename
2381 *
2382 * Returns:
2383 *
2384 * The MAC/Vendor mapping filename.
2385 *
2386 * If a filename was specified as an option on the command line, then
2387 * that filename is used. Otherwise we look for the default filename
2388 * in the current directory, and use that if it's present. Otherwise
2389 * we use the default filename in the default directory.
2390 *
2391 */
2392 char *
get_mac_vendor_filename(const char * specified_filename,const char * default_datadir,const char * default_filename)2393 get_mac_vendor_filename(const char *specified_filename,
2394 const char *default_datadir,
2395 const char *default_filename) {
2396 struct stat statbuf;
2397 int status;
2398 char *file_name;
2399
2400 if (*specified_filename == '\0') { /* No filename specified */
2401 file_name = make_message("%s", default_filename);
2402 status = stat(file_name, &statbuf);
2403 if (status == -1 && errno == ENOENT) {
2404 free(file_name);
2405 file_name = make_message("%s/%s", default_datadir, default_filename);
2406 }
2407 } else { /* Filename specified */
2408 file_name = make_message("%s", specified_filename);
2409 }
2410 return file_name;
2411 }
2412
2413 /*
2414 * get_source_ip -- Get IP address associated with given interface
2415 *
2416 * Inputs:
2417 *
2418 * interface_name The name of the network interface
2419 * ip_addr (output) The IP Address associated with the device
2420 *
2421 * Returns:
2422 *
2423 * Zero on success, or -1 on failure.
2424 */
2425 int
get_source_ip(const char * interface_name,struct in_addr * ip_addr)2426 get_source_ip(const char *interface_name, struct in_addr *ip_addr) {
2427 char errbuf[PCAP_ERRBUF_SIZE];
2428 pcap_if_t *alldevsp;
2429 pcap_if_t *device;
2430 pcap_addr_t *addr;
2431 struct sockaddr *sa;
2432 struct sockaddr_in *sin = NULL;
2433
2434 if ((pcap_findalldevs(&alldevsp, errbuf)) != 0) {
2435 printf("pcap_findalldevs: %s\n", errbuf);
2436 }
2437
2438 device=alldevsp;
2439 while (device != NULL && (strcmp(device->name,interface_name) != 0)) {
2440 device=device->next;
2441 }
2442 if (device == NULL) {
2443 warn_msg("ERROR: Could not find interface: %s", interface_name);
2444 err_msg("ERROR: Check that the interface exists and is up");
2445 }
2446
2447 for (addr=device->addresses; addr != NULL; addr=addr->next) {
2448 sa = addr->addr;
2449 if (sa->sa_family == AF_INET) {
2450 sin = (struct sockaddr_in *) sa;
2451 break;
2452 }
2453 }
2454 if (sin == NULL) {
2455 memset(&(ip_addr->s_addr), '\0', sizeof(ip_addr->s_addr));
2456 pcap_freealldevs(alldevsp);
2457 return -1;
2458 }
2459
2460 memcpy(ip_addr, &(sin->sin_addr), sizeof(*ip_addr));
2461
2462 pcap_freealldevs(alldevsp);
2463
2464 return 0;
2465 }
2466