diff options
author | Ron Yorston <rmy@pobox.com> | 2014-12-14 14:20:56 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-12-14 14:20:56 +0000 |
commit | 6d6d18d45c145899fce3a39553771cf0af671f30 (patch) | |
tree | 1936d18cbf61b9e0989464aad0a11c52cbeff7b7 /networking | |
parent | 0c204dc07b718244c360e0b84df66ce0a012e14f (diff) | |
parent | acb8be721768b54075a51d1859d390904a0f1f6c (diff) | |
download | busybox-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.src | 8 | ||||
-rw-r--r-- | networking/httpd.c | 6 | ||||
-rw-r--r-- | networking/libiproute/iproute.c | 18 | ||||
-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/files.c | 14 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 11 | ||||
-rw-r--r-- | networking/zcip.c | 35 |
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 | ||
184 | config 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 | |||
192 | config FEATURE_HTTPD_SETUID | 184 | config 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 */ |
317 | int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; | 318 | 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 = | |||
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) | |||
148 | static NOINLINE void send_offer(struct dhcp_packet *oldpacket, | 149 | static 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( | |||
100 | int is_expired_lease(struct dyn_lease *lease) FAST_FUNC; | 100 | int is_expired_lease(struct dyn_lease *lease) FAST_FUNC; |
101 | struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; | 101 | struct dyn_lease *find_lease_by_mac(const uint8_t *mac) FAST_FUNC; |
102 | struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; | 102 | struct dyn_lease *find_lease_by_nip(uint32_t nip) FAST_FUNC; |
103 | uint32_t find_free_or_expired_nip(const uint8_t *safe_mac) FAST_FUNC; | 103 | uint32_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 */ |
115 | static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac) | 115 | static 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 */ |
135 | uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac) | 136 | uint32_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 { | |||
87 | struct globals { | 91 | struct 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 | */ |
101 | static uint32_t pick(void) | 106 | static 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; |