Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

arp-scan: Add network discovery mode (--discover) #66

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 44 additions & 6 deletions arp-scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static unsigned char source_mac[6];
static int source_mac_flag = 0;
static unsigned char *padding=NULL;
static size_t padding_len=0;
static int discover_flag=0; /* Discover local networks */
static int localnet_flag=0; /* Scan local network */
static int llc_flag=0; /* Use 802.2 LLC with SNAP */
static int ieee_8021q_vlan=-1; /* Use 802.1Q VLAN tagging if >= 0 */
Expand Down Expand Up @@ -109,6 +110,7 @@ main(int argc, char *argv[]) {
int pass_no = 0;
int first_timeout=1;
unsigned i;
unsigned j;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program filter;
char *filter_string;
Expand Down Expand Up @@ -323,17 +325,25 @@ main(int argc, char *argv[]) {
*/
if (interval && bandwidth != DEFAULT_BANDWIDTH)
err_msg("ERROR: You cannot specify both --bandwidth and --interval.");
if (discover_flag && localnet_flag)
err_msg("ERROR: You cannot specify both --localnet and --discover.");
if (localnet_flag) {
if ((argc - optind) > 0)
err_msg("ERROR: You can not specify targets with the --localnet option");
if (filename_flag)
err_msg("ERROR: You can not specify both --file and --localnet options");
}
if (discover_flag) {
if ((argc - optind) > 0)
err_msg("ERROR: You can not specify targets with the --discover option");
if (filename_flag)
err_msg("ERROR: You can not specify both --file and --discover options");
}
/*
* If we're not reading from a file, and --localnet was not specified, then
* we must have some hosts given as command line arguments.
*/
if (!filename_flag && !localnet_flag)
if (!filename_flag && !localnet_flag && !discover_flag)
if ((argc - optind) < 1)
usage(EXIT_FAILURE, 0);
/*
Expand Down Expand Up @@ -369,8 +379,10 @@ main(int argc, char *argv[]) {
}
/*
* Populate the list from the specified file if --file was specified, or
* from the interface address and mask if --localnet was specified, or
* otherwise from the remaining command line arguments.
* from the interface address and mask if --localnet was specified, or
* from the first IP address within each /24 subnet within the RFC1918
* local address space if --discover was specified, or otherwise from
* the remaining command line arguments.
*/
if (filename_flag) { /* Populate list from file */
FILE *fp;
Expand Down Expand Up @@ -416,6 +428,25 @@ main(int argc, char *argv[]) {
warn_msg("Using %s for localnet", localnet_descr);
}
add_host_pattern(localnet_descr, timeout);
} else if (discover_flag) { /* Populate list from common local addresses */
char ip[16];

for (i=0; i<=254; ++i) {
for (j=0; j<255; ++j) {
snprintf(ip, 16, "10.%d.%d.1", i, j);
add_host_pattern(ip, timeout);
}
}
for (i=16; i<=32; ++i) {
for (j=0; j<255; ++j) {
snprintf(ip, 16, "172.%d.%d.1", i, j);
add_host_pattern(ip, timeout);
}
}
for (i=0; i<255; ++i) {
snprintf(ip, 16, "192.168.%d.1", i);
add_host_pattern(ip, timeout);
}
} else { /* Populate list from command line arguments */
argv=&argv[optind];
while (*argv) {
Expand Down Expand Up @@ -987,7 +1018,9 @@ usage(int status, int detailed) {
fprintf(stdout, "Target hosts must be specified on the command line unless the --file option is\n");
fprintf(stdout, "given, in which case the targets are read from the specified file instead, or\n");
fprintf(stdout, "the --localnet option is used, in which case the targets are generated from\n");
fprintf(stdout, "the network interface IP address and netmask.\n");
fprintf(stdout, "the network interface IP address and netmask, or the --discover option is used,\n");
fprintf(stdout, "in which case the first IP address within each /24 subnet within the RFC1918\n");
fprintf(stdout, "local address space is used.\n");
fprintf(stdout, "\n");
fprintf(stdout, "You will need to be root, or arp-scan must be SUID root, in order to run\n");
fprintf(stdout, "arp-scan, because the functions that it uses to read and write packets\n");
Expand Down Expand Up @@ -1031,6 +1064,7 @@ usage(int status, int detailed) {
fprintf(stdout, "\n--file=<s> or -f <s>\tRead hostnames or addresses from the specified file\n");
fprintf(stdout, "\t\t\tinstead of from the command line. One name or IP\n");
fprintf(stdout, "\t\t\taddress per line. Use \"-\" for standard input.\n");
fprintf(stdout, "\n--discover or -d\tDiscover networks using common RF1918 local addresses.\n");
fprintf(stdout, "\n--localnet or -l\tGenerate addresses from network interface configuration.\n");
fprintf(stdout, "\t\t\tUse the network interface IP address and network mask\n");
fprintf(stdout, "\t\t\tto generate the list of target host addresses.\n");
Expand Down Expand Up @@ -1830,6 +1864,7 @@ process_options(int argc, char *argv[]) {
{"arpsha", required_argument, 0, 'u'},
{"arptha", required_argument, 0, 'w'},
{"srcaddr", required_argument, 0, 'S'},
{"discover", no_argument, 0, 'd'},
{"localnet", no_argument, 0, 'l'},
{"llc", no_argument, 0, 'L'},
{"vlan", required_argument, 0, 'Q'},
Expand All @@ -1844,12 +1879,12 @@ process_options(int argc, char *argv[]) {
/*
* available short option characters:
*
* lower: --cde----jk--------------z
* lower: --c-e----jk--------------z
* UPPER: --C---G--JK-M-------U--X-Z
* Digits: 0123456789
*/
const char *short_options =
"f:hr:Y:E:t:i:b:vVn:I:qgRNB:O:s:o:H:p:T:P:a:A:y:u:w:S:F:m:lLQ:W:Dx";
"f:hr:Y:E:t:i:b:vVn:I:qgRNB:O:s:o:H:p:T:P:a:A:y:u:w:S:F:m:dlLQ:W:Dx";
int arg;
int options_index=0;

Expand Down Expand Up @@ -1975,6 +2010,9 @@ process_options(int argc, char *argv[]) {
err_msg("Invalid target MAC address: %s", optarg);
source_mac_flag = 1;
break;
case 'd': /* --discover */
discover_flag = 1;
break;
case 'l': /* --localnet */
localnet_flag = 1;
break;
Expand Down