//usage: "\n -f Run in foreground"
//usage: "\n -q Quit after obtaining address"
//usage: "\n -r 169.254.x.x Request this address first"
+//usage: "\n -l x.x.0.0 Use this range instead of 169.254"
//usage: "\n -v Verbose"
//usage: "\n"
//usage: "\nWith no -q, runs continuously monitoring for ARP conflicts,"
struct globals {
struct sockaddr saddr;
struct ether_addr eth_addr;
+ uint32_t localnet_ip;
} FIX_ALIASING;
#define G (*(struct globals*)&bb_common_bufsiz1)
#define saddr (G.saddr )
* Pick a random link local IP address on 169.254/16, except that
* the first and last 256 addresses are reserved.
*/
-static uint32_t pick(void)
+static uint32_t pick_nip(void)
{
unsigned tmp;
do {
tmp = rand() & IN_CLASSB_HOST;
} while (tmp > (IN_CLASSB_HOST - 0x0200));
- return htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
+ return htonl((G.localnet_ip + 0x0100) + tmp);
}
/**
{
int state;
char *r_opt;
+ const char *l_opt = "169.254.0.0";
unsigned opts;
// ugly trick, but I want these zeroed in one go
// parse commandline: prog [options] ifname script
// exactly 2 args; -v accumulates and implies -f
opt_complementary = "=2:vv:vf";
- opts = getopt32(argv, "fqr:v", &r_opt, &verbose);
+ opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose);
#if !BB_MMU
// on NOMMU reexec early (or else we will rerun things twice)
if (!FOREGROUND)
openlog(applet_name, 0, LOG_DAEMON);
logmode |= LOGMODE_SYSLOG;
}
+ { // -l n.n.n.n
+ struct in_addr net;
+ if (inet_aton(l_opt, &net) == 0
+ || (net.s_addr & htonl(IN_CLASSB_NET)) != net.s_addr
+ ) {
+ bb_error_msg_and_die("invalid network address");
+ }
+ G.localnet_ip = ntohl(net.s_addr);
+ }
if (opts & 4) { // -r n.n.n.n
if (inet_aton(r_opt, &ip) == 0
- || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR
+ || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip
) {
bb_error_msg_and_die("invalid link address");
}
srand(t);
}
if (ip.s_addr == 0)
- ip.s_addr = pick();
+ ip.s_addr = pick_nip();
// FIXME cases to handle:
// - zcip already running!
default:
// Invalid, should never happen. Restart the whole protocol.
state = PROBE;
- ip.s_addr = pick();
+ ip.s_addr = pick_nip();
timeout_ms = 0;
nprobes = 0;
nclaims = 0;
}
// restart the whole protocol
- ip.s_addr = pick();
+ ip.s_addr = pick_nip();
timeout_ms = 0;
nprobes = 0;
nclaims = 0;
run(argv, "deconfig", &ip);
// restart the whole protocol
- ip.s_addr = pick();
+ ip.s_addr = pick_nip();
timeout_ms = 0;
nprobes = 0;
nclaims = 0;
// Invalid, should never happen. Restart the whole protocol.
VDBG("invalid state -- starting over\n");
state = PROBE;
- ip.s_addr = pick();
+ ip.s_addr = pick_nip();
timeout_ms = 0;
nprobes = 0;
nclaims = 0;