diff options
-rw-r--r-- | networking/udhcp/arpping.c | 10 | ||||
-rw-r--r-- | networking/udhcp/common.h | 3 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 17 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 17 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.h | 2 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 11 |
6 files changed, 39 insertions, 21 deletions
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c index b43e52e96..fad2283c3 100644 --- a/networking/udhcp/arpping.c +++ b/networking/udhcp/arpping.c @@ -39,7 +39,8 @@ int FAST_FUNC arpping(uint32_t test_nip, const uint8_t *safe_mac, uint32_t from_ip, uint8_t *from_mac, - const char *interface) + const char *interface, + unsigned timeo) { int timeout_ms; struct pollfd pfd[1]; @@ -48,6 +49,9 @@ int FAST_FUNC arpping(uint32_t test_nip, struct sockaddr addr; /* for interface name */ struct arpMsg arp; + if (!timeo) + return 1; + s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); if (s == -1) { bb_perror_msg(bb_msg_can_not_create_raw_socket); @@ -83,7 +87,7 @@ int FAST_FUNC arpping(uint32_t test_nip, } /* wait for arp reply, and check it */ - timeout_ms = 2000; + timeout_ms = (int)timeo; do { typedef uint32_t aliased_uint32_t FIX_ALIASING; int r; @@ -124,7 +128,7 @@ int FAST_FUNC arpping(uint32_t test_nip, * this is more under/overflow-resistant * (people did see overflows here when system time jumps): */ - } while ((unsigned)timeout_ms <= 2000); + } while ((unsigned)timeout_ms <= timeo); ret: close(s); diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index e5e0f2599..d20659e2f 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -311,7 +311,8 @@ int arpping(uint32_t test_nip, const uint8_t *safe_mac, uint32_t from_ip, uint8_t *from_mac, - const char *interface) FAST_FUNC; + const char *interface, + unsigned timeo) FAST_FUNC; /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index e468b7bbb..35e7c2070 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -54,7 +54,7 @@ static const char udhcpc_longopts[] ALIGN1 = "foreground\0" No_argument "f" "background\0" No_argument "b" "broadcast\0" No_argument "B" - IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") + IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a") IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") ; #endif @@ -1150,7 +1150,7 @@ static void client_background(void) //usage:# define IF_UDHCP_VERBOSE(...) //usage:#endif //usage:#define udhcpc_trivial_usage -//usage: "[-fbq"IF_UDHCP_VERBOSE("v")IF_FEATURE_UDHCPC_ARPING("a")"RB] [-t N] [-T SEC] [-A SEC/-n]\n" +//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n" //usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n" //usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..." //usage:#define udhcpc_full_usage "\n" @@ -1174,7 +1174,7 @@ static void client_background(void) //usage: ) //usage: "\n -S,--syslog Log to syslog too" //usage: IF_FEATURE_UDHCPC_ARPING( -//usage: "\n -a,--arping Use arping to validate offered address" +//usage: "\n -a[MSEC],--arping[=MSEC] Validate offered address with ARP ping" //usage: ) //usage: "\n -r,--request IP Request this IP address" //usage: "\n -o,--no-default-options Don't request any options (unless -O is given)" @@ -1211,7 +1211,7 @@ static void client_background(void) //usage: ) //usage: "\n -S Log to syslog too" //usage: IF_FEATURE_UDHCPC_ARPING( -//usage: "\n -a Use arping to validate offered address" +//usage: "\n -a[MSEC] Validate offered address with ARP ping" //usage: ) //usage: "\n -r IP Request this IP address" //usage: "\n -o Don't request any options (unless -O is given)" @@ -1238,6 +1238,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) { uint8_t *message; const char *str_V, *str_h, *str_F, *str_r; + IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";) IF_FEATURE_UDHCP_PORT(char *str_P;) void *clientid_mac_ptr; llist_t *list_O = NULL; @@ -1252,6 +1253,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) int timeout; /* must be signed */ unsigned already_waited_sec; unsigned opt; + IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) int max_fd; int retval; fd_set rfds; @@ -1269,7 +1271,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" USE_FOR_MMU("b") - IF_FEATURE_UDHCPC_ARPING("a") + IF_FEATURE_UDHCPC_ARPING("a::") IF_FEATURE_UDHCP_PORT("P:") "v" , &str_V, &str_h, &str_h, &str_F @@ -1278,6 +1280,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ , &list_O , &list_x + IF_FEATURE_UDHCPC_ARPING(, &str_a) IF_FEATURE_UDHCP_PORT(, &str_P) IF_UDHCP_VERBOSE(, &dhcp_verbose) ); @@ -1309,6 +1312,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) SERVER_PORT = CLIENT_PORT - 1; } #endif + IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);) while (list_O) { char *optstr = llist_pop(&list_O); unsigned n = bb_strtou(optstr, NULL, 0); @@ -1726,7 +1730,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) NULL, (uint32_t) 0, client_config.client_mac, - client_config.interface) + client_config.interface, + arpping_ms) ) { bb_info_msg("Offered address is in use " "(got ARP reply), declining"); diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index a1a7f6b57..4b3ed240c 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -28,6 +28,7 @@ //usage: "\n -f Run in foreground" //usage: "\n -S Log to syslog too" //usage: "\n -I ADDR Local address" +//usage: "\n -a MSEC Timeout for ARP ping (default 2000)" //usage: IF_FEATURE_UDHCP_PORT( //usage: "\n -P N Use port N (default 67)" //usage: ) @@ -148,7 +149,8 @@ static uint32_t select_lease_time(struct dhcp_packet *packet) static NOINLINE void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease, - uint8_t *requested_ip_opt) + uint8_t *requested_ip_opt, + unsigned arpping_ms) { struct dhcp_packet packet; uint32_t lease_time_sec; @@ -187,7 +189,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, } else { /* Otherwise, find a free IP */ - packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr); + packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms); } if (!packet.yiaddr) { @@ -304,6 +306,8 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) unsigned opt; struct option_set *option; char *str_I = str_I; + const char *str_a = "2000"; + unsigned arpping_ms; IF_FEATURE_UDHCP_PORT(char *str_P;) #if ENABLE_FEATURE_UDHCP_PORT @@ -314,9 +318,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 opt_complementary = "vv"; #endif - opt = getopt32(argv, "fSI:v" + opt = getopt32(argv, "fSI:va:" IF_FEATURE_UDHCP_PORT("P:") , &str_I + , &str_a IF_FEATURE_UDHCP_PORT(, &str_P) IF_UDHCP_VERBOSE(, &dhcp_verbose) ); @@ -336,11 +341,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) free(lsa); } #if ENABLE_FEATURE_UDHCP_PORT - if (opt & 16) { /* -P */ + if (opt & 32) { /* -P */ SERVER_PORT = xatou16(str_P); CLIENT_PORT = SERVER_PORT + 1; } #endif + arpping_ms = xatou(str_a); + /* Would rather not do read_config before daemonization - * otherwise NOMMU machines will parse config twice */ read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); @@ -498,7 +505,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) case DHCPDISCOVER: log1("Received DISCOVER"); - send_offer(&packet, static_lease_nip, lease, requested_ip_opt); + send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); break; case DHCPREQUEST: diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index a77724f20..183e7e24c 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -100,7 +100,7 @@ struct dyn_lease *add_lease( int is_expired_lease(struct dyn_lease *lease) FAST_FUNC; struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; -uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC; +uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) FAST_FUNC; /* Config file parser will pass static lease info to this function diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index c5b60b108..745340ad3 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c @@ -112,7 +112,7 @@ struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip) } /* Check if the IP is taken; if it is, add it to the lease table */ -static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) +static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms) { struct in_addr temp; int r; @@ -120,7 +120,8 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) r = arpping(nip, safe_mac, server_config.server_nip, server_config.server_mac, - server_config.interface); + server_config.interface, + arpping_ms); if (r) return r; @@ -132,7 +133,7 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) } /* Find a new usable (we think) address */ -uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) +uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) { uint32_t addr; struct dyn_lease *oldest_lease = NULL; @@ -177,7 +178,7 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) lease = find_lease_by_nip(nip); if (!lease) { //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! - if (nobody_responds_to_arp(nip, safe_mac)) + if (nobody_responds_to_arp(nip, safe_mac, arpping_ms)) return nip; } else { if (!oldest_lease || lease->expires < oldest_lease->expires) @@ -194,7 +195,7 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) if (oldest_lease && is_expired_lease(oldest_lease) - && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac) + && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms) ) { return oldest_lease->lease_nip; } |