Loading src/logger.c +18 −2 Original line number Diff line number Diff line /* log messages to console, depending on verbose level Use -v (or -d) to get more verbose output. The more -v you add, the more verbose the output becomes. Details about the running of the program go to <stderr>. Details about scan results go to <stdout>, so that they can easily be redirected to a file. */ #include "logger.h" Loading @@ -8,7 +15,11 @@ int verbosity = 0; /* yea! a global variable!! */ void vLOG(int level, const char *fmt, va_list marker) /*************************************************************************** ***************************************************************************/ void vLOG(int level, const char *fmt, va_list marker) { if (level <= verbosity) { vfprintf(stderr, fmt, marker); Loading @@ -16,7 +27,12 @@ void vLOG(int level, const char *fmt, va_list marker) } } void LOG(int level, const char *fmt, ...) /*************************************************************************** * Prints the message if the global "verbosity" flag exceeds this level. ***************************************************************************/ void LOG(int level, const char *fmt, ...) { va_list marker; Loading src/logger.h +1 −1 Original line number Diff line number Diff line #ifndef LOGGER_H #define LOGGER_H extern int verbosity; /* defined in logger.c */ void LOG(int level, const char *fmt, ...); #endif src/main-conf.c +87 −7 Original line number Diff line number Diff line Loading @@ -14,12 +14,11 @@ #include "masscan.h" #include "ranges.h" #include "string_s.h" #include "logger.h" #include <ctype.h> extern int verbosity; /* logger.c */ /*************************************************************************** ***************************************************************************/ void masscan_usage(void) Loading Loading @@ -101,7 +100,7 @@ masscan_echo(struct Masscan *masscan, FILE *fp) fprintf(fp, "randomize-hosts = true\n"); fprintf(fp, "\n# adapter settings\n"); fprintf(fp, "# ADAPTER SETTINGS\n"); fprintf(fp, "adapter = %s\n", masscan->ifname); fprintf(fp, "adapter-ip = %u.%u.%u.%u\n", (masscan->adapter_ip>>24)&0xFF, Loading @@ -127,7 +126,7 @@ masscan_echo(struct Masscan *masscan, FILE *fp) /* * Output information */ fprintf(fp, "# output\n"); fprintf(fp, "# OUTPUT/REPORTING SETTINGS\n"); switch (masscan->nmap.format) { case Output_Interactive: fprintf(fp, "output-format = interactive\n"); Loading @@ -142,12 +141,15 @@ masscan_echo(struct Masscan *masscan, FILE *fp) fprintf(fp, "output-filename = %s\n", masscan->nmap.filename); if (masscan->nmap.append) fprintf(fp, "output-append = true\n"); fprintf(fp, "rotate = %u\n", masscan->rotate_output); fprintf(fp, "rotate-dir = %s\n", masscan->rotate_directory); fprintf(fp, "rotate-offset = %u\n", masscan->rotate_offset); /* * Targets */ fprintf(fp, "\n# targets\n"); fprintf(fp, "# TARGET SELECTION (IP, PORTS, EXCLUDES)\n"); fprintf(fp, "ports = "); for (i=0; i<masscan->ports.count; i++) { struct Range range = masscan->ports.list[i]; Loading Loading @@ -658,6 +660,86 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val } else { masscan->retries = x; } } else if (EQUALS("rotate-output", name) || EQUALS("rotate", name) || EQUALS("ouput-rotate", name)) { switch (tolower(value[0])) { case 's': masscan->rotate_output = 1; return; case 'm': masscan->rotate_output = 60; return; case 'h': masscan->rotate_output = 60*60; return; case 'd': masscan->rotate_output = 24*60*60; return; case 'w': masscan->rotate_output = 24*60*60*7; return; default: if (isdigit(value[0]&0xFF)) { masscan->rotate_output = strtoul(value, 0, 0); return; } } fprintf(stderr, "--rotate: unknown value (epected 'minute', 'hour', 'day', 'week')\n"); exit(1); } else if (EQUALS("rotate-offset", name) || EQUALS("ouput-rotate-offset", name)) { uint64_t num = 0; unsigned is_negative = 0; while (*value == '-') { is_negative = 1; value++; } while (isdigit(value[0]&0xFF)) { num = num*10 + (value[0] - '0'); value++; } while (ispunct(value[0]) || isspace(value[0])) value++; if (isalpha(value[0]) && num == 0) num = 1; switch (tolower(value[0])) { case 's': num *= 1; break; case 'm': num *= 60; break; case 'h': num *= 60*60; break; case 'd': num *= 24*60*60; break; case 'w': num *= 24*60*60*7; break; default: fprintf(stderr, "--rotate-offset: unknown character\n"); exit(1); } if (num >= 24*60*60) { fprintf(stderr, "--rotate-offset: value is greater than 1 day\n"); exit(1); } if (is_negative) num = 24*60*60 - num; masscan->rotate_offset = (unsigned)num; } else if (EQUALS("rotate-dir", name) || EQUALS("rotate-directory", name) || EQUALS("ouput-rotate-dir", name)) { char *p; strcpy_s( masscan->rotate_directory, sizeof(masscan->rotate_directory), value); /* strip trailing slashes */ p = masscan->rotate_directory; while (*p && (p[strlen(p)-1] == '/' || p[strlen(p)-1] == '/')) p[strlen(p)-1] = '\0'; } else if (EQUALS("script", name)) { fprintf(stderr, "nmap(%s): unsupported, it's too complex for this simple scanner\n", name); exit(1); Loading Loading @@ -893,8 +975,6 @@ masscan_command_line(struct Masscan *masscan, int argc, char *argv[]) break; case 'X': masscan->nmap.format = Output_XML; fprintf(stderr, "nmap(%s): unsupported output format\n", argv[i]); exit(1); break; case 'S': masscan->nmap.format = Output_ScriptKiddie; Loading src/main-dedup.c +16 −4 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ #include <stdlib.h> #include <string.h> #define DEDUP_ENTRIES 1024 #define DEDUP_ENTRIES 4096 struct DedupEntry { Loading Loading @@ -55,8 +55,8 @@ dedup_is_duplicate(struct DedupTable *dedup, unsigned ip, unsigned port) struct DedupEntry *bucket; unsigned i; /* THREAT: We've already validated resonses via SYN-cookies, so * therefore we don't need a robust hash for duplicate detection */ /* THREAT: probably need to secure this hash, though the syn-cookies * provides some protection */ hash = (ip + port) ^ ((ip>>8) + (ip>>16)) ^ (ip>>24); hash &= DEDUP_ENTRIES-1; Loading @@ -64,9 +64,21 @@ dedup_is_duplicate(struct DedupTable *dedup, unsigned ip, unsigned port) bucket = dedup->entries[hash]; for (i = 0; i < 4; i++) { if (bucket[i].ip == ip && bucket[i].port == port) if (bucket[i].ip == ip && bucket[i].port == port) { /* move to end of list so constant repeats get ignored */ if (i > 0) { bucket[i].ip ^= bucket[0].ip; bucket[i].port ^= bucket[0].port; bucket[0].ip ^= bucket[i].ip; bucket[0].port ^= bucket[i].port; bucket[i].ip ^= bucket[0].ip; bucket[i].port ^= bucket[0].port; } return 1; } } /* We didn't find it, so add it to our list. This will push * older entries at this bucket off the list */ Loading src/main-initadapter.c 0 → 100644 +167 −0 Original line number Diff line number Diff line #include "masscan.h" #include "logger.h" #include "rawsock.h" /*************************************************************************** * Initialize the network adapter. * * This requires finding things like our IP address, MAC address, and router * MAC address. The user could configure these things manually instead. * * Note that we don't update the "static" configuration with the discovered * values, but instead return them as the "running" configuration. That's * so if we pause and resume a scan, autodiscovered values don't get saved * in the configuration file. ***************************************************************************/ int masscan_initialize_adapter(struct Masscan *masscan, unsigned *r_adapter_ip, unsigned char *adapter_mac, unsigned char *router_mac) { char *ifname; char ifname2[256]; LOG(1, "initializing adapter\n"); /* * ADAPTER/NETWORK-INTERFACE * * If no network interface was configured, we need to go hunt down * the best Interface to use. We do this by choosing the first * interface with a "default route" (aka. "gateway") defined */ if (masscan->ifname && masscan->ifname[0]) ifname = masscan->ifname; else { /* no adapter specified, so find a default one */ int err; err = rawsock_get_default_interface(ifname2, sizeof(ifname2)); if (err) { fprintf(stderr, "FAIL: could not determine default interface\n"); fprintf(stderr, "FAIL:... try \"--interface ethX\"\n"); return -1; } else { LOG(2, "auto-detected: interface=%s\n", ifname2); } ifname = ifname2; } /* * IP ADDRESS * * We need to figure out that IP address to send packets from. This * is done by queryin the adapter (or configured by user). If the * adapter doesn't have one, then the user must configure one. */ *r_adapter_ip = masscan->adapter_ip; if (*r_adapter_ip == 0) { *r_adapter_ip = rawsock_get_adapter_ip(ifname); LOG(2, "auto-detected: adapter-ip=%u.%u.%u.%u\n", (*r_adapter_ip>>24)&0xFF, (*r_adapter_ip>>16)&0xFF, (*r_adapter_ip>> 8)&0xFF, (*r_adapter_ip>> 0)&0xFF ); } if (*r_adapter_ip == 0) { fprintf(stderr, "FAIL: failed to detect IP of interface: \"%s\"\n", ifname); fprintf(stderr, "FAIL:... try something like \"--adapter-ip 192.168.100.5\"\n"); return -1; } /* * MAC ADDRESS * * This is the address we send packets from. It actually doesn't really * matter what this address is, but to be a "responsible" citizen we * try to use the hardware address in the network card. */ memcpy(adapter_mac, masscan->adapter_mac, 6); if (memcmp(adapter_mac, "\0\0\0\0\0\0", 6) == 0) { rawsock_get_adapter_mac(ifname, adapter_mac); LOG(2, "auto-detected: adapter-mac=%02x-%02x-%02x-%02x-%02x-%02x\n", adapter_mac[0], adapter_mac[1], adapter_mac[2], adapter_mac[3], adapter_mac[4], adapter_mac[5] ); } if (memcmp(adapter_mac, "\0\0\0\0\0\0", 6) == 0) { fprintf(stderr, "FAIL: failed to detect MAC address of interface: \"%s\"\n", ifname); fprintf(stderr, "FAIL:... try something like \"--adapter-mac 00-11-22-33-44\"\n"); return -1; } /* * START ADAPTER * * Once we've figured out which adapter to use, we now need to * turn it on. */ masscan->adapter = rawsock_init_adapter(ifname, masscan->is_pfring, masscan->is_sendq); if (masscan->adapter == 0) { fprintf(stderr, "adapter[%s].init: failed\n", ifname); return -1; } LOG(3, "rawsock: ignoring transmits\n"); rawsock_ignore_transmits(masscan->adapter, adapter_mac); LOG(3, "rawsock: initialization done\n"); /* * ROUTER MAC ADDRESS * * NOTE: this is one of the least understood aspects of the code. We must * send packets to the local router, which means the MAC address (not * IP address) of the router. * * Note: in order to ARP the router, we need to first enable the libpcap * code above. */ memcpy(router_mac, masscan->router_mac, 6); if (memcmp(router_mac, "\0\0\0\0\0\0", 6) == 0) { unsigned router_ipv4; int err; LOG(1, "rawsock: looking for default gateway\n"); err = rawsock_get_default_gateway(ifname, &router_ipv4); if (err == 0) { LOG(2, "auto-detected: router-ip=%u.%u.%u.%u\n", (router_ipv4>>24)&0xFF, (router_ipv4>>16)&0xFF, (router_ipv4>> 8)&0xFF, (router_ipv4>> 0)&0xFF ); arp_resolve_sync( masscan->adapter, *r_adapter_ip, adapter_mac, router_ipv4, router_mac); if (memcmp(router_mac, "\0\0\0\0\0\0", 6) != 0) { LOG(2, "auto-detected: router-mac=%02x-%02x-%02x-%02x-%02x-%02x\n", router_mac[0], router_mac[1], router_mac[2], router_mac[3], router_mac[4], router_mac[5] ); } } } if (memcmp(router_mac, "\0\0\0\0\0\0", 6) == 0) { fprintf(stderr, "FAIL: failed to detect router for interface: \"%s\"\n", ifname); fprintf(stderr, "FAIL:... try something like \"--router-mac 66-55-44-33-22-11\"\n"); return -1; } LOG(1, "adapter initialization done.\n"); return 0; } Loading
src/logger.c +18 −2 Original line number Diff line number Diff line /* log messages to console, depending on verbose level Use -v (or -d) to get more verbose output. The more -v you add, the more verbose the output becomes. Details about the running of the program go to <stderr>. Details about scan results go to <stdout>, so that they can easily be redirected to a file. */ #include "logger.h" Loading @@ -8,7 +15,11 @@ int verbosity = 0; /* yea! a global variable!! */ void vLOG(int level, const char *fmt, va_list marker) /*************************************************************************** ***************************************************************************/ void vLOG(int level, const char *fmt, va_list marker) { if (level <= verbosity) { vfprintf(stderr, fmt, marker); Loading @@ -16,7 +27,12 @@ void vLOG(int level, const char *fmt, va_list marker) } } void LOG(int level, const char *fmt, ...) /*************************************************************************** * Prints the message if the global "verbosity" flag exceeds this level. ***************************************************************************/ void LOG(int level, const char *fmt, ...) { va_list marker; Loading
src/logger.h +1 −1 Original line number Diff line number Diff line #ifndef LOGGER_H #define LOGGER_H extern int verbosity; /* defined in logger.c */ void LOG(int level, const char *fmt, ...); #endif
src/main-conf.c +87 −7 Original line number Diff line number Diff line Loading @@ -14,12 +14,11 @@ #include "masscan.h" #include "ranges.h" #include "string_s.h" #include "logger.h" #include <ctype.h> extern int verbosity; /* logger.c */ /*************************************************************************** ***************************************************************************/ void masscan_usage(void) Loading Loading @@ -101,7 +100,7 @@ masscan_echo(struct Masscan *masscan, FILE *fp) fprintf(fp, "randomize-hosts = true\n"); fprintf(fp, "\n# adapter settings\n"); fprintf(fp, "# ADAPTER SETTINGS\n"); fprintf(fp, "adapter = %s\n", masscan->ifname); fprintf(fp, "adapter-ip = %u.%u.%u.%u\n", (masscan->adapter_ip>>24)&0xFF, Loading @@ -127,7 +126,7 @@ masscan_echo(struct Masscan *masscan, FILE *fp) /* * Output information */ fprintf(fp, "# output\n"); fprintf(fp, "# OUTPUT/REPORTING SETTINGS\n"); switch (masscan->nmap.format) { case Output_Interactive: fprintf(fp, "output-format = interactive\n"); Loading @@ -142,12 +141,15 @@ masscan_echo(struct Masscan *masscan, FILE *fp) fprintf(fp, "output-filename = %s\n", masscan->nmap.filename); if (masscan->nmap.append) fprintf(fp, "output-append = true\n"); fprintf(fp, "rotate = %u\n", masscan->rotate_output); fprintf(fp, "rotate-dir = %s\n", masscan->rotate_directory); fprintf(fp, "rotate-offset = %u\n", masscan->rotate_offset); /* * Targets */ fprintf(fp, "\n# targets\n"); fprintf(fp, "# TARGET SELECTION (IP, PORTS, EXCLUDES)\n"); fprintf(fp, "ports = "); for (i=0; i<masscan->ports.count; i++) { struct Range range = masscan->ports.list[i]; Loading Loading @@ -658,6 +660,86 @@ masscan_set_parameter(struct Masscan *masscan, const char *name, const char *val } else { masscan->retries = x; } } else if (EQUALS("rotate-output", name) || EQUALS("rotate", name) || EQUALS("ouput-rotate", name)) { switch (tolower(value[0])) { case 's': masscan->rotate_output = 1; return; case 'm': masscan->rotate_output = 60; return; case 'h': masscan->rotate_output = 60*60; return; case 'd': masscan->rotate_output = 24*60*60; return; case 'w': masscan->rotate_output = 24*60*60*7; return; default: if (isdigit(value[0]&0xFF)) { masscan->rotate_output = strtoul(value, 0, 0); return; } } fprintf(stderr, "--rotate: unknown value (epected 'minute', 'hour', 'day', 'week')\n"); exit(1); } else if (EQUALS("rotate-offset", name) || EQUALS("ouput-rotate-offset", name)) { uint64_t num = 0; unsigned is_negative = 0; while (*value == '-') { is_negative = 1; value++; } while (isdigit(value[0]&0xFF)) { num = num*10 + (value[0] - '0'); value++; } while (ispunct(value[0]) || isspace(value[0])) value++; if (isalpha(value[0]) && num == 0) num = 1; switch (tolower(value[0])) { case 's': num *= 1; break; case 'm': num *= 60; break; case 'h': num *= 60*60; break; case 'd': num *= 24*60*60; break; case 'w': num *= 24*60*60*7; break; default: fprintf(stderr, "--rotate-offset: unknown character\n"); exit(1); } if (num >= 24*60*60) { fprintf(stderr, "--rotate-offset: value is greater than 1 day\n"); exit(1); } if (is_negative) num = 24*60*60 - num; masscan->rotate_offset = (unsigned)num; } else if (EQUALS("rotate-dir", name) || EQUALS("rotate-directory", name) || EQUALS("ouput-rotate-dir", name)) { char *p; strcpy_s( masscan->rotate_directory, sizeof(masscan->rotate_directory), value); /* strip trailing slashes */ p = masscan->rotate_directory; while (*p && (p[strlen(p)-1] == '/' || p[strlen(p)-1] == '/')) p[strlen(p)-1] = '\0'; } else if (EQUALS("script", name)) { fprintf(stderr, "nmap(%s): unsupported, it's too complex for this simple scanner\n", name); exit(1); Loading Loading @@ -893,8 +975,6 @@ masscan_command_line(struct Masscan *masscan, int argc, char *argv[]) break; case 'X': masscan->nmap.format = Output_XML; fprintf(stderr, "nmap(%s): unsupported output format\n", argv[i]); exit(1); break; case 'S': masscan->nmap.format = Output_ScriptKiddie; Loading
src/main-dedup.c +16 −4 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ #include <stdlib.h> #include <string.h> #define DEDUP_ENTRIES 1024 #define DEDUP_ENTRIES 4096 struct DedupEntry { Loading Loading @@ -55,8 +55,8 @@ dedup_is_duplicate(struct DedupTable *dedup, unsigned ip, unsigned port) struct DedupEntry *bucket; unsigned i; /* THREAT: We've already validated resonses via SYN-cookies, so * therefore we don't need a robust hash for duplicate detection */ /* THREAT: probably need to secure this hash, though the syn-cookies * provides some protection */ hash = (ip + port) ^ ((ip>>8) + (ip>>16)) ^ (ip>>24); hash &= DEDUP_ENTRIES-1; Loading @@ -64,9 +64,21 @@ dedup_is_duplicate(struct DedupTable *dedup, unsigned ip, unsigned port) bucket = dedup->entries[hash]; for (i = 0; i < 4; i++) { if (bucket[i].ip == ip && bucket[i].port == port) if (bucket[i].ip == ip && bucket[i].port == port) { /* move to end of list so constant repeats get ignored */ if (i > 0) { bucket[i].ip ^= bucket[0].ip; bucket[i].port ^= bucket[0].port; bucket[0].ip ^= bucket[i].ip; bucket[0].port ^= bucket[i].port; bucket[i].ip ^= bucket[0].ip; bucket[i].port ^= bucket[0].port; } return 1; } } /* We didn't find it, so add it to our list. This will push * older entries at this bucket off the list */ Loading
src/main-initadapter.c 0 → 100644 +167 −0 Original line number Diff line number Diff line #include "masscan.h" #include "logger.h" #include "rawsock.h" /*************************************************************************** * Initialize the network adapter. * * This requires finding things like our IP address, MAC address, and router * MAC address. The user could configure these things manually instead. * * Note that we don't update the "static" configuration with the discovered * values, but instead return them as the "running" configuration. That's * so if we pause and resume a scan, autodiscovered values don't get saved * in the configuration file. ***************************************************************************/ int masscan_initialize_adapter(struct Masscan *masscan, unsigned *r_adapter_ip, unsigned char *adapter_mac, unsigned char *router_mac) { char *ifname; char ifname2[256]; LOG(1, "initializing adapter\n"); /* * ADAPTER/NETWORK-INTERFACE * * If no network interface was configured, we need to go hunt down * the best Interface to use. We do this by choosing the first * interface with a "default route" (aka. "gateway") defined */ if (masscan->ifname && masscan->ifname[0]) ifname = masscan->ifname; else { /* no adapter specified, so find a default one */ int err; err = rawsock_get_default_interface(ifname2, sizeof(ifname2)); if (err) { fprintf(stderr, "FAIL: could not determine default interface\n"); fprintf(stderr, "FAIL:... try \"--interface ethX\"\n"); return -1; } else { LOG(2, "auto-detected: interface=%s\n", ifname2); } ifname = ifname2; } /* * IP ADDRESS * * We need to figure out that IP address to send packets from. This * is done by queryin the adapter (or configured by user). If the * adapter doesn't have one, then the user must configure one. */ *r_adapter_ip = masscan->adapter_ip; if (*r_adapter_ip == 0) { *r_adapter_ip = rawsock_get_adapter_ip(ifname); LOG(2, "auto-detected: adapter-ip=%u.%u.%u.%u\n", (*r_adapter_ip>>24)&0xFF, (*r_adapter_ip>>16)&0xFF, (*r_adapter_ip>> 8)&0xFF, (*r_adapter_ip>> 0)&0xFF ); } if (*r_adapter_ip == 0) { fprintf(stderr, "FAIL: failed to detect IP of interface: \"%s\"\n", ifname); fprintf(stderr, "FAIL:... try something like \"--adapter-ip 192.168.100.5\"\n"); return -1; } /* * MAC ADDRESS * * This is the address we send packets from. It actually doesn't really * matter what this address is, but to be a "responsible" citizen we * try to use the hardware address in the network card. */ memcpy(adapter_mac, masscan->adapter_mac, 6); if (memcmp(adapter_mac, "\0\0\0\0\0\0", 6) == 0) { rawsock_get_adapter_mac(ifname, adapter_mac); LOG(2, "auto-detected: adapter-mac=%02x-%02x-%02x-%02x-%02x-%02x\n", adapter_mac[0], adapter_mac[1], adapter_mac[2], adapter_mac[3], adapter_mac[4], adapter_mac[5] ); } if (memcmp(adapter_mac, "\0\0\0\0\0\0", 6) == 0) { fprintf(stderr, "FAIL: failed to detect MAC address of interface: \"%s\"\n", ifname); fprintf(stderr, "FAIL:... try something like \"--adapter-mac 00-11-22-33-44\"\n"); return -1; } /* * START ADAPTER * * Once we've figured out which adapter to use, we now need to * turn it on. */ masscan->adapter = rawsock_init_adapter(ifname, masscan->is_pfring, masscan->is_sendq); if (masscan->adapter == 0) { fprintf(stderr, "adapter[%s].init: failed\n", ifname); return -1; } LOG(3, "rawsock: ignoring transmits\n"); rawsock_ignore_transmits(masscan->adapter, adapter_mac); LOG(3, "rawsock: initialization done\n"); /* * ROUTER MAC ADDRESS * * NOTE: this is one of the least understood aspects of the code. We must * send packets to the local router, which means the MAC address (not * IP address) of the router. * * Note: in order to ARP the router, we need to first enable the libpcap * code above. */ memcpy(router_mac, masscan->router_mac, 6); if (memcmp(router_mac, "\0\0\0\0\0\0", 6) == 0) { unsigned router_ipv4; int err; LOG(1, "rawsock: looking for default gateway\n"); err = rawsock_get_default_gateway(ifname, &router_ipv4); if (err == 0) { LOG(2, "auto-detected: router-ip=%u.%u.%u.%u\n", (router_ipv4>>24)&0xFF, (router_ipv4>>16)&0xFF, (router_ipv4>> 8)&0xFF, (router_ipv4>> 0)&0xFF ); arp_resolve_sync( masscan->adapter, *r_adapter_ip, adapter_mac, router_ipv4, router_mac); if (memcmp(router_mac, "\0\0\0\0\0\0", 6) != 0) { LOG(2, "auto-detected: router-mac=%02x-%02x-%02x-%02x-%02x-%02x\n", router_mac[0], router_mac[1], router_mac[2], router_mac[3], router_mac[4], router_mac[5] ); } } } if (memcmp(router_mac, "\0\0\0\0\0\0", 6) == 0) { fprintf(stderr, "FAIL: failed to detect router for interface: \"%s\"\n", ifname); fprintf(stderr, "FAIL:... try something like \"--router-mac 66-55-44-33-22-11\"\n"); return -1; } LOG(1, "adapter initialization done.\n"); return 0; }