diff --git a/networking/zcip.c b/networking/zcip.c index 45d1f7c1c..635d660b3 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -30,6 +30,7 @@ //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," @@ -87,6 +88,7 @@ enum { 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 ) @@ -98,14 +100,14 @@ struct globals { * 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); } /** @@ -197,6 +199,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) { 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 @@ -231,7 +234,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // 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) @@ -246,9 +249,18 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) 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"); } @@ -295,7 +307,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) srand(t); } if (ip.s_addr == 0) - ip.s_addr = pick(); + ip.s_addr = pick_nip(); // FIXME cases to handle: // - zcip already running! @@ -433,7 +445,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) 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; @@ -535,7 +547,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) } // restart the whole protocol - ip.s_addr = pick(); + ip.s_addr = pick_nip(); timeout_ms = 0; nprobes = 0; nclaims = 0; @@ -561,7 +573,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) run(argv, "deconfig", &ip); // restart the whole protocol - ip.s_addr = pick(); + ip.s_addr = pick_nip(); timeout_ms = 0; nprobes = 0; nclaims = 0; @@ -571,7 +583,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // 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;