aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-12-14 14:20:56 +0000
committerRon Yorston <rmy@pobox.com>2014-12-14 14:20:56 +0000
commit6d6d18d45c145899fce3a39553771cf0af671f30 (patch)
tree1936d18cbf61b9e0989464aad0a11c52cbeff7b7 /networking
parent0c204dc07b718244c360e0b84df66ce0a012e14f (diff)
parentacb8be721768b54075a51d1859d390904a0f1f6c (diff)
downloadbusybox-w32-6d6d18d45c145899fce3a39553771cf0af671f30.tar.gz
busybox-w32-6d6d18d45c145899fce3a39553771cf0af671f30.tar.bz2
busybox-w32-6d6d18d45c145899fce3a39553771cf0af671f30.zip
Merge branch 'busybox' into merge
Conflicts: archival/libarchive/open_transformer.c libbb/lineedit.c miscutils/man.c
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src8
-rw-r--r--networking/httpd.c6
-rw-r--r--networking/libiproute/iproute.c18
-rw-r--r--networking/udhcp/arpping.c10
-rw-r--r--networking/udhcp/common.h3
-rw-r--r--networking/udhcp/dhcpc.c17
-rw-r--r--networking/udhcp/dhcpd.c17
-rw-r--r--networking/udhcp/dhcpd.h2
-rw-r--r--networking/udhcp/files.c14
-rw-r--r--networking/udhcp/leases.c11
-rw-r--r--networking/zcip.c35
11 files changed, 98 insertions, 43 deletions
diff --git a/networking/Config.src b/networking/Config.src
index e56646917..15a696876 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -181,14 +181,6 @@ config FEATURE_HTTPD_RANGES
181 "Range: bytes=NNN-[MMM]" header. Allows for resuming interrupted 181 "Range: bytes=NNN-[MMM]" header. Allows for resuming interrupted
182 downloads, seeking in multimedia players etc. 182 downloads, seeking in multimedia players etc.
183 183
184config FEATURE_HTTPD_USE_SENDFILE
185 bool "Use sendfile system call"
186 default y
187 depends on HTTPD
188 help
189 When enabled, httpd will use the kernel sendfile() function
190 instead of read/write loop.
191
192config FEATURE_HTTPD_SETUID 184config FEATURE_HTTPD_SETUID
193 bool "Enable -u <user> option" 185 bool "Enable -u <user> option"
194 default y 186 default y
diff --git a/networking/httpd.c b/networking/httpd.c
index 621d9cddc..9cf080401 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -133,7 +133,7 @@
133# include <security/pam_appl.h> 133# include <security/pam_appl.h>
134# include <security/pam_misc.h> 134# include <security/pam_misc.h>
135#endif 135#endif
136#if ENABLE_FEATURE_HTTPD_USE_SENDFILE 136#if ENABLE_FEATURE_USE_SENDFILE
137# include <sys/sendfile.h> 137# include <sys/sendfile.h>
138#endif 138#endif
139/* amount of buffering in a pipe */ 139/* amount of buffering in a pipe */
@@ -1624,7 +1624,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1624#endif 1624#endif
1625 if (what & SEND_HEADERS) 1625 if (what & SEND_HEADERS)
1626 send_headers(HTTP_OK); 1626 send_headers(HTTP_OK);
1627#if ENABLE_FEATURE_HTTPD_USE_SENDFILE 1627#if ENABLE_FEATURE_USE_SENDFILE
1628 { 1628 {
1629 off_t offset = range_start; 1629 off_t offset = range_start;
1630 while (1) { 1630 while (1) {
@@ -1654,7 +1654,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1654 break; 1654 break;
1655 } 1655 }
1656 if (count < 0) { 1656 if (count < 0) {
1657 IF_FEATURE_HTTPD_USE_SENDFILE(fin:) 1657 IF_FEATURE_USE_SENDFILE(fin:)
1658 if (verbose > 1) 1658 if (verbose > 1)
1659 bb_perror_msg("error"); 1659 bb_perror_msg("error");
1660 } 1660 }
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index ec4d8ba03..170c67b30 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -298,6 +298,19 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
298 if (tb[RTA_PRIORITY]) { 298 if (tb[RTA_PRIORITY]) {
299 printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); 299 printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
300 } 300 }
301 if (r->rtm_flags & RTNH_F_DEAD) {
302 printf("dead ");
303 }
304 if (r->rtm_flags & RTNH_F_ONLINK) {
305 printf("onlink ");
306 }
307 if (r->rtm_flags & RTNH_F_PERVASIVE) {
308 printf("pervasive ");
309 }
310 if (r->rtm_flags & RTM_F_NOTIFY) {
311 printf("notify ");
312 }
313
301 if (r->rtm_family == AF_INET6) { 314 if (r->rtm_family == AF_INET6) {
302 struct rta_cacheinfo *ci = NULL; 315 struct rta_cacheinfo *ci = NULL;
303 if (tb[RTA_CACHEINFO]) { 316 if (tb[RTA_CACHEINFO]) {
@@ -330,7 +343,7 @@ static int iproute_modify(int cmd, unsigned flags, char **argv)
330{ 343{
331 static const char keywords[] ALIGN1 = 344 static const char keywords[] ALIGN1 =
332 "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0") 345 "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0")
333 "dev\0""oif\0""to\0""metric\0"; 346 "dev\0""oif\0""to\0""metric\0""onlink\0";
334 enum { 347 enum {
335 ARG_src, 348 ARG_src,
336 ARG_via, 349 ARG_via,
@@ -341,6 +354,7 @@ IF_FEATURE_IP_RULE(ARG_table,)
341 ARG_oif, 354 ARG_oif,
342 ARG_to, 355 ARG_to,
343 ARG_metric, 356 ARG_metric,
357 ARG_onlink,
344 }; 358 };
345 enum { 359 enum {
346 gw_ok = 1 << 0, 360 gw_ok = 1 << 0,
@@ -431,6 +445,8 @@ IF_FEATURE_IP_RULE(ARG_table,)
431 NEXT_ARG(); 445 NEXT_ARG();
432 metric = get_u32(*argv, "metric"); 446 metric = get_u32(*argv, "metric");
433 addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric); 447 addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric);
448 } else if (arg == ARG_onlink) {
449 req.r.rtm_flags |= RTNH_F_ONLINK;
434 } else { 450 } else {
435 int type; 451 int type;
436 inet_prefix dst; 452 inet_prefix dst;
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,
39 const uint8_t *safe_mac, 39 const uint8_t *safe_mac,
40 uint32_t from_ip, 40 uint32_t from_ip,
41 uint8_t *from_mac, 41 uint8_t *from_mac,
42 const char *interface) 42 const char *interface,
43 unsigned timeo)
43{ 44{
44 int timeout_ms; 45 int timeout_ms;
45 struct pollfd pfd[1]; 46 struct pollfd pfd[1];
@@ -48,6 +49,9 @@ int FAST_FUNC arpping(uint32_t test_nip,
48 struct sockaddr addr; /* for interface name */ 49 struct sockaddr addr; /* for interface name */
49 struct arpMsg arp; 50 struct arpMsg arp;
50 51
52 if (!timeo)
53 return 1;
54
51 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)); 55 s = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP));
52 if (s == -1) { 56 if (s == -1) {
53 bb_perror_msg(bb_msg_can_not_create_raw_socket); 57 bb_perror_msg(bb_msg_can_not_create_raw_socket);
@@ -83,7 +87,7 @@ int FAST_FUNC arpping(uint32_t test_nip,
83 } 87 }
84 88
85 /* wait for arp reply, and check it */ 89 /* wait for arp reply, and check it */
86 timeout_ms = 2000; 90 timeout_ms = (int)timeo;
87 do { 91 do {
88 typedef uint32_t aliased_uint32_t FIX_ALIASING; 92 typedef uint32_t aliased_uint32_t FIX_ALIASING;
89 int r; 93 int r;
@@ -124,7 +128,7 @@ int FAST_FUNC arpping(uint32_t test_nip,
124 * this is more under/overflow-resistant 128 * this is more under/overflow-resistant
125 * (people did see overflows here when system time jumps): 129 * (people did see overflows here when system time jumps):
126 */ 130 */
127 } while ((unsigned)timeout_ms <= 2000); 131 } while ((unsigned)timeout_ms <= timeo);
128 132
129 ret: 133 ret:
130 close(s); 134 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,
311 const uint8_t *safe_mac, 311 const uint8_t *safe_mac,
312 uint32_t from_ip, 312 uint32_t from_ip,
313 uint8_t *from_mac, 313 uint8_t *from_mac,
314 const char *interface) FAST_FUNC; 314 const char *interface,
315 unsigned timeo) FAST_FUNC;
315 316
316/* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ 317/* note: ip is a pointer to an IPv6 in network order, possibly misaliged */
317int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; 318int 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 =
54 "foreground\0" No_argument "f" 54 "foreground\0" No_argument "f"
55 "background\0" No_argument "b" 55 "background\0" No_argument "b"
56 "broadcast\0" No_argument "B" 56 "broadcast\0" No_argument "B"
57 IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") 57 IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a")
58 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") 58 IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P")
59 ; 59 ;
60#endif 60#endif
@@ -1150,7 +1150,7 @@ static void client_background(void)
1150//usage:# define IF_UDHCP_VERBOSE(...) 1150//usage:# define IF_UDHCP_VERBOSE(...)
1151//usage:#endif 1151//usage:#endif
1152//usage:#define udhcpc_trivial_usage 1152//usage:#define udhcpc_trivial_usage
1153//usage: "[-fbq"IF_UDHCP_VERBOSE("v")IF_FEATURE_UDHCPC_ARPING("a")"RB] [-t N] [-T SEC] [-A SEC/-n]\n" 1153//usage: "[-fbq"IF_UDHCP_VERBOSE("v")"RB]"IF_FEATURE_UDHCPC_ARPING(" [-a[MSEC]]")" [-t N] [-T SEC] [-A SEC/-n]\n"
1154//usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n" 1154//usage: " [-i IFACE]"IF_FEATURE_UDHCP_PORT(" [-P PORT]")" [-s PROG] [-p PIDFILE]\n"
1155//usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..." 1155//usage: " [-oC] [-r IP] [-V VENDOR] [-F NAME] [-x OPT:VAL]... [-O OPT]..."
1156//usage:#define udhcpc_full_usage "\n" 1156//usage:#define udhcpc_full_usage "\n"
@@ -1174,7 +1174,7 @@ static void client_background(void)
1174//usage: ) 1174//usage: )
1175//usage: "\n -S,--syslog Log to syslog too" 1175//usage: "\n -S,--syslog Log to syslog too"
1176//usage: IF_FEATURE_UDHCPC_ARPING( 1176//usage: IF_FEATURE_UDHCPC_ARPING(
1177//usage: "\n -a,--arping Use arping to validate offered address" 1177//usage: "\n -a[MSEC],--arping[=MSEC] Validate offered address with ARP ping"
1178//usage: ) 1178//usage: )
1179//usage: "\n -r,--request IP Request this IP address" 1179//usage: "\n -r,--request IP Request this IP address"
1180//usage: "\n -o,--no-default-options Don't request any options (unless -O is given)" 1180//usage: "\n -o,--no-default-options Don't request any options (unless -O is given)"
@@ -1211,7 +1211,7 @@ static void client_background(void)
1211//usage: ) 1211//usage: )
1212//usage: "\n -S Log to syslog too" 1212//usage: "\n -S Log to syslog too"
1213//usage: IF_FEATURE_UDHCPC_ARPING( 1213//usage: IF_FEATURE_UDHCPC_ARPING(
1214//usage: "\n -a Use arping to validate offered address" 1214//usage: "\n -a[MSEC] Validate offered address with ARP ping"
1215//usage: ) 1215//usage: )
1216//usage: "\n -r IP Request this IP address" 1216//usage: "\n -r IP Request this IP address"
1217//usage: "\n -o Don't request any options (unless -O is given)" 1217//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)
1238{ 1238{
1239 uint8_t *message; 1239 uint8_t *message;
1240 const char *str_V, *str_h, *str_F, *str_r; 1240 const char *str_V, *str_h, *str_F, *str_r;
1241 IF_FEATURE_UDHCPC_ARPING(const char *str_a = "2000";)
1241 IF_FEATURE_UDHCP_PORT(char *str_P;) 1242 IF_FEATURE_UDHCP_PORT(char *str_P;)
1242 void *clientid_mac_ptr; 1243 void *clientid_mac_ptr;
1243 llist_t *list_O = NULL; 1244 llist_t *list_O = NULL;
@@ -1252,6 +1253,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1252 int timeout; /* must be signed */ 1253 int timeout; /* must be signed */
1253 unsigned already_waited_sec; 1254 unsigned already_waited_sec;
1254 unsigned opt; 1255 unsigned opt;
1256 IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;)
1255 int max_fd; 1257 int max_fd;
1256 int retval; 1258 int retval;
1257 fd_set rfds; 1259 fd_set rfds;
@@ -1269,7 +1271,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1269 IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) 1271 IF_LONG_OPTS(applet_long_options = udhcpc_longopts;)
1270 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" 1272 opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB"
1271 USE_FOR_MMU("b") 1273 USE_FOR_MMU("b")
1272 IF_FEATURE_UDHCPC_ARPING("a") 1274 IF_FEATURE_UDHCPC_ARPING("a::")
1273 IF_FEATURE_UDHCP_PORT("P:") 1275 IF_FEATURE_UDHCP_PORT("P:")
1274 "v" 1276 "v"
1275 , &str_V, &str_h, &str_h, &str_F 1277 , &str_V, &str_h, &str_h, &str_F
@@ -1278,6 +1280,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1278 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */ 1280 , &discover_timeout, &discover_retries, &tryagain_timeout /* T,t,A */
1279 , &list_O 1281 , &list_O
1280 , &list_x 1282 , &list_x
1283 IF_FEATURE_UDHCPC_ARPING(, &str_a)
1281 IF_FEATURE_UDHCP_PORT(, &str_P) 1284 IF_FEATURE_UDHCP_PORT(, &str_P)
1282 IF_UDHCP_VERBOSE(, &dhcp_verbose) 1285 IF_UDHCP_VERBOSE(, &dhcp_verbose)
1283 ); 1286 );
@@ -1309,6 +1312,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1309 SERVER_PORT = CLIENT_PORT - 1; 1312 SERVER_PORT = CLIENT_PORT - 1;
1310 } 1313 }
1311#endif 1314#endif
1315 IF_FEATURE_UDHCPC_ARPING(arpping_ms = xatou(str_a);)
1312 while (list_O) { 1316 while (list_O) {
1313 char *optstr = llist_pop(&list_O); 1317 char *optstr = llist_pop(&list_O);
1314 unsigned n = bb_strtou(optstr, NULL, 0); 1318 unsigned n = bb_strtou(optstr, NULL, 0);
@@ -1726,7 +1730,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1726 NULL, 1730 NULL,
1727 (uint32_t) 0, 1731 (uint32_t) 0,
1728 client_config.client_mac, 1732 client_config.client_mac,
1729 client_config.interface) 1733 client_config.interface,
1734 arpping_ms)
1730 ) { 1735 ) {
1731 bb_info_msg("Offered address is in use " 1736 bb_info_msg("Offered address is in use "
1732 "(got ARP reply), declining"); 1737 "(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 @@
28//usage: "\n -f Run in foreground" 28//usage: "\n -f Run in foreground"
29//usage: "\n -S Log to syslog too" 29//usage: "\n -S Log to syslog too"
30//usage: "\n -I ADDR Local address" 30//usage: "\n -I ADDR Local address"
31//usage: "\n -a MSEC Timeout for ARP ping (default 2000)"
31//usage: IF_FEATURE_UDHCP_PORT( 32//usage: IF_FEATURE_UDHCP_PORT(
32//usage: "\n -P N Use port N (default 67)" 33//usage: "\n -P N Use port N (default 67)"
33//usage: ) 34//usage: )
@@ -148,7 +149,8 @@ static uint32_t select_lease_time(struct dhcp_packet *packet)
148static NOINLINE void send_offer(struct dhcp_packet *oldpacket, 149static NOINLINE void send_offer(struct dhcp_packet *oldpacket,
149 uint32_t static_lease_nip, 150 uint32_t static_lease_nip,
150 struct dyn_lease *lease, 151 struct dyn_lease *lease,
151 uint8_t *requested_ip_opt) 152 uint8_t *requested_ip_opt,
153 unsigned arpping_ms)
152{ 154{
153 struct dhcp_packet packet; 155 struct dhcp_packet packet;
154 uint32_t lease_time_sec; 156 uint32_t lease_time_sec;
@@ -187,7 +189,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket,
187 } 189 }
188 else { 190 else {
189 /* Otherwise, find a free IP */ 191 /* Otherwise, find a free IP */
190 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr); 192 packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms);
191 } 193 }
192 194
193 if (!packet.yiaddr) { 195 if (!packet.yiaddr) {
@@ -304,6 +306,8 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
304 unsigned opt; 306 unsigned opt;
305 struct option_set *option; 307 struct option_set *option;
306 char *str_I = str_I; 308 char *str_I = str_I;
309 const char *str_a = "2000";
310 unsigned arpping_ms;
307 IF_FEATURE_UDHCP_PORT(char *str_P;) 311 IF_FEATURE_UDHCP_PORT(char *str_P;)
308 312
309#if ENABLE_FEATURE_UDHCP_PORT 313#if ENABLE_FEATURE_UDHCP_PORT
@@ -314,9 +318,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
314#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 318#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1
315 opt_complementary = "vv"; 319 opt_complementary = "vv";
316#endif 320#endif
317 opt = getopt32(argv, "fSI:v" 321 opt = getopt32(argv, "fSI:va:"
318 IF_FEATURE_UDHCP_PORT("P:") 322 IF_FEATURE_UDHCP_PORT("P:")
319 , &str_I 323 , &str_I
324 , &str_a
320 IF_FEATURE_UDHCP_PORT(, &str_P) 325 IF_FEATURE_UDHCP_PORT(, &str_P)
321 IF_UDHCP_VERBOSE(, &dhcp_verbose) 326 IF_UDHCP_VERBOSE(, &dhcp_verbose)
322 ); 327 );
@@ -336,11 +341,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
336 free(lsa); 341 free(lsa);
337 } 342 }
338#if ENABLE_FEATURE_UDHCP_PORT 343#if ENABLE_FEATURE_UDHCP_PORT
339 if (opt & 16) { /* -P */ 344 if (opt & 32) { /* -P */
340 SERVER_PORT = xatou16(str_P); 345 SERVER_PORT = xatou16(str_P);
341 CLIENT_PORT = SERVER_PORT + 1; 346 CLIENT_PORT = SERVER_PORT + 1;
342 } 347 }
343#endif 348#endif
349 arpping_ms = xatou(str_a);
350
344 /* Would rather not do read_config before daemonization - 351 /* Would rather not do read_config before daemonization -
345 * otherwise NOMMU machines will parse config twice */ 352 * otherwise NOMMU machines will parse config twice */
346 read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); 353 read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE);
@@ -498,7 +505,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
498 case DHCPDISCOVER: 505 case DHCPDISCOVER:
499 log1("Received DISCOVER"); 506 log1("Received DISCOVER");
500 507
501 send_offer(&packet, static_lease_nip, lease, requested_ip_opt); 508 send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms);
502 break; 509 break;
503 510
504 case DHCPREQUEST: 511 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(
100int is_expired_lease(struct dyn_lease *lease) FAST_FUNC; 100int is_expired_lease(struct dyn_lease *lease) FAST_FUNC;
101struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; 101struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC;
102struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; 102struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC;
103uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC; 103uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) FAST_FUNC;
104 104
105 105
106/* Config file parser will pass static lease info to this function 106/* Config file parser will pass static lease info to this function
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c
index 6840f3c25..1c8808c0f 100644
--- a/networking/udhcp/files.c
+++ b/networking/udhcp/files.c
@@ -189,12 +189,24 @@ void FAST_FUNC read_leases(const char *file)
189 goto ret; 189 goto ret;
190 190
191 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { 191 while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) {
192//FIXME: what if it matches some static lease?
193 uint32_t y = ntohl(lease.lease_nip); 192 uint32_t y = ntohl(lease.lease_nip);
194 if (y >= server_config.start_ip && y <= server_config.end_ip) { 193 if (y >= server_config.start_ip && y <= server_config.end_ip) {
195 signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; 194 signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed;
195 uint32_t static_nip;
196
196 if (expires <= 0) 197 if (expires <= 0)
197 continue; 198 continue;
199
200 /* Check if there is a different static lease for this IP or MAC */
201 static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac);
202 if (static_nip) {
203 /* NB: we do not add lease even if static_nip == lease.lease_nip.
204 */
205 continue;
206 }
207 if (is_nip_reserved(server_config.static_leases, lease.lease_nip))
208 continue;
209
198 /* NB: add_lease takes "relative time", IOW, 210 /* NB: add_lease takes "relative time", IOW,
199 * lease duration, not lease deadline. */ 211 * lease duration, not lease deadline. */
200 if (add_lease(lease.lease_mac, lease.lease_nip, 212 if (add_lease(lease.lease_mac, lease.lease_nip,
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)
112} 112}
113 113
114/* Check if the IP is taken; if it is, add it to the lease table */ 114/* Check if the IP is taken; if it is, add it to the lease table */
115static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) 115static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms)
116{ 116{
117 struct in_addr temp; 117 struct in_addr temp;
118 int r; 118 int r;
@@ -120,7 +120,8 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
120 r = arpping(nip, safe_mac, 120 r = arpping(nip, safe_mac,
121 server_config.server_nip, 121 server_config.server_nip,
122 server_config.server_mac, 122 server_config.server_mac,
123 server_config.interface); 123 server_config.interface,
124 arpping_ms);
124 if (r) 125 if (r)
125 return r; 126 return r;
126 127
@@ -132,7 +133,7 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac)
132} 133}
133 134
134/* Find a new usable (we think) address */ 135/* Find a new usable (we think) address */
135uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) 136uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms)
136{ 137{
137 uint32_t addr; 138 uint32_t addr;
138 struct dyn_lease *oldest_lease = NULL; 139 struct dyn_lease *oldest_lease = NULL;
@@ -177,7 +178,7 @@ uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac)
177 lease = find_lease_by_nip(nip); 178 lease = find_lease_by_nip(nip);
178 if (!lease) { 179 if (!lease) {
179//TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! 180//TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping!
180 if (nobody_responds_to_arp(nip, safe_mac)) 181 if (nobody_responds_to_arp(nip, safe_mac, arpping_ms))
181 return nip; 182 return nip;
182 } else { 183 } else {
183 if (!oldest_lease || lease->expires < oldest_lease->expires) 184 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)
194 195
195 if (oldest_lease 196 if (oldest_lease
196 && is_expired_lease(oldest_lease) 197 && is_expired_lease(oldest_lease)
197 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac) 198 && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms)
198 ) { 199 ) {
199 return oldest_lease->lease_nip; 200 return oldest_lease->lease_nip;
200 } 201 }
diff --git a/networking/zcip.c b/networking/zcip.c
index 45d1f7c1c..a3307c5c9 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -30,8 +30,12 @@
30//usage: "\n -f Run in foreground" 30//usage: "\n -f Run in foreground"
31//usage: "\n -q Quit after obtaining address" 31//usage: "\n -q Quit after obtaining address"
32//usage: "\n -r 169.254.x.x Request this address first" 32//usage: "\n -r 169.254.x.x Request this address first"
33//usage: "\n -l x.x.0.0 Use this range instead of 169.254"
33//usage: "\n -v Verbose" 34//usage: "\n -v Verbose"
34//usage: "\n" 35//usage: "\n"
36//usage: "\n$LOGGING=none Suppress logging"
37//usage: "\n$LOGGING=syslog Log to syslog"
38//usage: "\n"
35//usage: "\nWith no -q, runs continuously monitoring for ARP conflicts," 39//usage: "\nWith no -q, runs continuously monitoring for ARP conflicts,"
36//usage: "\nexits only on I/O errors (link down etc)" 40//usage: "\nexits only on I/O errors (link down etc)"
37 41
@@ -87,6 +91,7 @@ enum {
87struct globals { 91struct globals {
88 struct sockaddr saddr; 92 struct sockaddr saddr;
89 struct ether_addr eth_addr; 93 struct ether_addr eth_addr;
94 uint32_t localnet_ip;
90} FIX_ALIASING; 95} FIX_ALIASING;
91#define G (*(struct globals*)&bb_common_bufsiz1) 96#define G (*(struct globals*)&bb_common_bufsiz1)
92#define saddr (G.saddr ) 97#define saddr (G.saddr )
@@ -98,14 +103,14 @@ struct globals {
98 * Pick a random link local IP address on 169.254/16, except that 103 * Pick a random link local IP address on 169.254/16, except that
99 * the first and last 256 addresses are reserved. 104 * the first and last 256 addresses are reserved.
100 */ 105 */
101static uint32_t pick(void) 106static uint32_t pick_nip(void)
102{ 107{
103 unsigned tmp; 108 unsigned tmp;
104 109
105 do { 110 do {
106 tmp = rand() & IN_CLASSB_HOST; 111 tmp = rand() & IN_CLASSB_HOST;
107 } while (tmp > (IN_CLASSB_HOST - 0x0200)); 112 } while (tmp > (IN_CLASSB_HOST - 0x0200));
108 return htonl((LINKLOCAL_ADDR + 0x0100) + tmp); 113 return htonl((G.localnet_ip + 0x0100) + tmp);
109} 114}
110 115
111/** 116/**
@@ -197,6 +202,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
197{ 202{
198 int state; 203 int state;
199 char *r_opt; 204 char *r_opt;
205 const char *l_opt = "169.254.0.0";
200 unsigned opts; 206 unsigned opts;
201 207
202 // ugly trick, but I want these zeroed in one go 208 // ugly trick, but I want these zeroed in one go
@@ -231,7 +237,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
231 // parse commandline: prog [options] ifname script 237 // parse commandline: prog [options] ifname script
232 // exactly 2 args; -v accumulates and implies -f 238 // exactly 2 args; -v accumulates and implies -f
233 opt_complementary = "=2:vv:vf"; 239 opt_complementary = "=2:vv:vf";
234 opts = getopt32(argv, "fqr:v", &r_opt, &verbose); 240 opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose);
235#if !BB_MMU 241#if !BB_MMU
236 // on NOMMU reexec early (or else we will rerun things twice) 242 // on NOMMU reexec early (or else we will rerun things twice)
237 if (!FOREGROUND) 243 if (!FOREGROUND)
@@ -246,9 +252,20 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
246 openlog(applet_name, 0, LOG_DAEMON); 252 openlog(applet_name, 0, LOG_DAEMON);
247 logmode |= LOGMODE_SYSLOG; 253 logmode |= LOGMODE_SYSLOG;
248 } 254 }
255 bb_logenv_override();
256
257 { // -l n.n.n.n
258 struct in_addr net;
259 if (inet_aton(l_opt, &net) == 0
260 || (net.s_addr & htonl(IN_CLASSB_NET)) != net.s_addr
261 ) {
262 bb_error_msg_and_die("invalid network address");
263 }
264 G.localnet_ip = ntohl(net.s_addr);
265 }
249 if (opts & 4) { // -r n.n.n.n 266 if (opts & 4) { // -r n.n.n.n
250 if (inet_aton(r_opt, &ip) == 0 267 if (inet_aton(r_opt, &ip) == 0
251 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR 268 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip
252 ) { 269 ) {
253 bb_error_msg_and_die("invalid link address"); 270 bb_error_msg_and_die("invalid link address");
254 } 271 }
@@ -295,7 +312,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
295 srand(t); 312 srand(t);
296 } 313 }
297 if (ip.s_addr == 0) 314 if (ip.s_addr == 0)
298 ip.s_addr = pick(); 315 ip.s_addr = pick_nip();
299 316
300 // FIXME cases to handle: 317 // FIXME cases to handle:
301 // - zcip already running! 318 // - zcip already running!
@@ -433,7 +450,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
433 default: 450 default:
434 // Invalid, should never happen. Restart the whole protocol. 451 // Invalid, should never happen. Restart the whole protocol.
435 state = PROBE; 452 state = PROBE;
436 ip.s_addr = pick(); 453 ip.s_addr = pick_nip();
437 timeout_ms = 0; 454 timeout_ms = 0;
438 nprobes = 0; 455 nprobes = 0;
439 nclaims = 0; 456 nclaims = 0;
@@ -535,7 +552,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
535 } 552 }
536 553
537 // restart the whole protocol 554 // restart the whole protocol
538 ip.s_addr = pick(); 555 ip.s_addr = pick_nip();
539 timeout_ms = 0; 556 timeout_ms = 0;
540 nprobes = 0; 557 nprobes = 0;
541 nclaims = 0; 558 nclaims = 0;
@@ -561,7 +578,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
561 run(argv, "deconfig", &ip); 578 run(argv, "deconfig", &ip);
562 579
563 // restart the whole protocol 580 // restart the whole protocol
564 ip.s_addr = pick(); 581 ip.s_addr = pick_nip();
565 timeout_ms = 0; 582 timeout_ms = 0;
566 nprobes = 0; 583 nprobes = 0;
567 nclaims = 0; 584 nclaims = 0;
@@ -571,7 +588,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
571 // Invalid, should never happen. Restart the whole protocol. 588 // Invalid, should never happen. Restart the whole protocol.
572 VDBG("invalid state -- starting over\n"); 589 VDBG("invalid state -- starting over\n");
573 state = PROBE; 590 state = PROBE;
574 ip.s_addr = pick(); 591 ip.s_addr = pick_nip();
575 timeout_ms = 0; 592 timeout_ms = 0;
576 nprobes = 0; 593 nprobes = 0;
577 nclaims = 0; 594 nclaims = 0;