diff options
author | Ron Yorston <rmy@pobox.com> | 2016-10-19 17:01:55 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-10-19 17:01:55 +0100 |
commit | 075814c60a316cfd088c88f26f75ab21b5850b98 (patch) | |
tree | f6e33ac693630827deb309faa5fa4931588db57d /networking | |
parent | 977d65c1bbc57f5cdd0c8bfd67c8b5bb1cd390dd (diff) | |
parent | f37e1155aabde6bd95d267a8aec347cedccb8bc3 (diff) | |
download | busybox-w32-075814c60a316cfd088c88f26f75ab21b5850b98.tar.gz busybox-w32-075814c60a316cfd088c88f26f75ab21b5850b98.tar.bz2 busybox-w32-075814c60a316cfd088c88f26f75ab21b5850b98.zip |
Merge branch busybox (up to "ash: comment out free(p) just before...")
Diffstat (limited to 'networking')
-rw-r--r-- | networking/Config.src | 12 | ||||
-rw-r--r-- | networking/ifplugd.c | 8 | ||||
-rw-r--r-- | networking/ifupdown.c | 14 | ||||
-rw-r--r-- | networking/libiproute/iproute.c | 3 | ||||
-rw-r--r-- | networking/libiproute/iprule.c | 8 | ||||
-rw-r--r-- | networking/libiproute/libnetlink.c | 66 | ||||
-rw-r--r-- | networking/ntpd.c | 7 | ||||
-rw-r--r-- | networking/route.c | 4 | ||||
-rwxr-xr-x | networking/ssl_helper-wolfssl/00cfg-wolfssl-3.9.8 | 39 | ||||
-rw-r--r-- | networking/ssl_helper-wolfssl/README | 7 | ||||
-rwxr-xr-x | networking/ssl_helper-wolfssl/ssl_helper.sh | 2 | ||||
-rw-r--r-- | networking/traceroute.c | 124 | ||||
-rw-r--r-- | networking/udhcp/Kbuild.src | 2 | ||||
-rw-r--r-- | networking/udhcp/arpping.c | 1 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 9 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 13 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 502 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.h | 33 | ||||
-rw-r--r-- | networking/udhcp/files.c | 234 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 211 | ||||
-rw-r--r-- | networking/udhcp/static_leases.c | 77 | ||||
-rw-r--r-- | networking/wget.c | 130 |
22 files changed, 766 insertions, 740 deletions
diff --git a/networking/Config.src b/networking/Config.src index 27c604a31..eb0536a7c 100644 --- a/networking/Config.src +++ b/networking/Config.src | |||
@@ -912,17 +912,9 @@ config FEATURE_TRACEROUTE_VERBOSE | |||
912 | Add some verbosity to traceroute. This includes among other things | 912 | Add some verbosity to traceroute. This includes among other things |
913 | hostnames and ICMP response types. | 913 | hostnames and ICMP response types. |
914 | 914 | ||
915 | config FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
916 | bool "Enable loose source route" | ||
917 | default n | ||
918 | depends on TRACEROUTE | ||
919 | help | ||
920 | Add option to specify a loose source route gateway | ||
921 | (8 maximum). | ||
922 | |||
923 | config FEATURE_TRACEROUTE_USE_ICMP | 915 | config FEATURE_TRACEROUTE_USE_ICMP |
924 | bool "Use ICMP instead of UDP" | 916 | bool "Enable -I option (use ICMP instead of UDP)" |
925 | default n | 917 | default y |
926 | depends on TRACEROUTE | 918 | depends on TRACEROUTE |
927 | help | 919 | help |
928 | Add option -I to use ICMP ECHO instead of UDP datagrams. | 920 | Add option -I to use ICMP ECHO instead of UDP datagrams. |
diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 28c49e218..029cba147 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c | |||
@@ -358,8 +358,12 @@ static void up_iface(void) | |||
358 | ifrequest.ifr_flags |= IFF_UP; | 358 | ifrequest.ifr_flags |= IFF_UP; |
359 | /* Let user know we mess up with interface */ | 359 | /* Let user know we mess up with interface */ |
360 | bb_error_msg("upping interface"); | 360 | bb_error_msg("upping interface"); |
361 | if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) | 361 | if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) { |
362 | xfunc_die(); | 362 | if (errno != ENODEV) |
363 | xfunc_die(); | ||
364 | G.iface_exists = 0; | ||
365 | return; | ||
366 | } | ||
363 | } | 367 | } |
364 | 368 | ||
365 | #if 0 /* why do we mess with IP addr? It's not our business */ | 369 | #if 0 /* why do we mess with IP addr? It's not our business */ |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 25b04c9d7..b0bc0d70f 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -21,7 +21,7 @@ | |||
21 | //usage: "[-an"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] [-i FILE] IFACE..." | 21 | //usage: "[-an"IF_FEATURE_IFUPDOWN_MAPPING("m")"vf] [-i FILE] IFACE..." |
22 | //usage:#define ifup_full_usage "\n\n" | 22 | //usage:#define ifup_full_usage "\n\n" |
23 | //usage: " -a De/configure all interfaces automatically" | 23 | //usage: " -a De/configure all interfaces automatically" |
24 | //usage: "\n -i FILE Use FILE for interface definitions" | 24 | //usage: "\n -i FILE Use FILE instead of /etc/network/interfaces" |
25 | //usage: "\n -n Print out what would happen, but don't do it" | 25 | //usage: "\n -n Print out what would happen, but don't do it" |
26 | //usage: IF_FEATURE_IFUPDOWN_MAPPING( | 26 | //usage: IF_FEATURE_IFUPDOWN_MAPPING( |
27 | //usage: "\n (note: doesn't disable mappings)" | 27 | //usage: "\n (note: doesn't disable mappings)" |
@@ -492,7 +492,7 @@ static int FAST_FUNC static_up(struct interface_defn_t *ifd, execfn *exec) | |||
492 | result = execute("ifconfig %iface%[[ hw %hwaddress%]][[ media %media%]][[ mtu %mtu%]] up", | 492 | result = execute("ifconfig %iface%[[ hw %hwaddress%]][[ media %media%]][[ mtu %mtu%]] up", |
493 | ifd, exec); | 493 | ifd, exec); |
494 | result += execute("ifconfig %iface% %address% netmask %netmask%" | 494 | result += execute("ifconfig %iface% %address% netmask %netmask%" |
495 | "[[ broadcast %broadcast%]][[ pointopoint %pointopoint%]] ", | 495 | "[[ broadcast %broadcast%]][[ pointopoint %pointopoint%]]", |
496 | ifd, exec); | 496 | ifd, exec); |
497 | result += execute("[[route add default gw %gateway%[[ metric %metric%]] %iface%]]", ifd, exec); | 497 | result += execute("[[route add default gw %gateway%[[ metric %metric%]] %iface%]]", ifd, exec); |
498 | return ((result == 3) ? 3 : 0); | 498 | return ((result == 3) ? 3 : 0); |
@@ -503,7 +503,10 @@ static int FAST_FUNC static_down(struct interface_defn_t *ifd, execfn *exec) | |||
503 | { | 503 | { |
504 | int result; | 504 | int result; |
505 | # if ENABLE_FEATURE_IFUPDOWN_IP | 505 | # if ENABLE_FEATURE_IFUPDOWN_IP |
506 | result = execute("ip addr flush dev %iface%", ifd, exec); | 506 | /* Optional "label LBL" is necessary if interface is an alias (eth0:0), |
507 | * otherwise "ip addr flush dev eth0:0" flushes all addresses on eth0. | ||
508 | */ | ||
509 | result = execute("ip addr flush dev %iface%[[ label %label%]]", ifd, exec); | ||
507 | result += execute("ip link set %iface% down", ifd, exec); | 510 | result += execute("ip link set %iface% down", ifd, exec); |
508 | # else | 511 | # else |
509 | /* result = execute("[[route del default gw %gateway% %iface%]]", ifd, exec); */ | 512 | /* result = execute("[[route del default gw %gateway% %iface%]]", ifd, exec); */ |
@@ -1066,6 +1069,11 @@ static int execute_all(struct interface_defn_t *ifd, const char *opt) | |||
1066 | } | 1069 | } |
1067 | } | 1070 | } |
1068 | 1071 | ||
1072 | /* Tested on Debian Squeeze: "standard" ifup runs this without | ||
1073 | * checking that directory exists. If it doesn't, run-parts | ||
1074 | * complains, and this message _is_ annoyingly visible. | ||
1075 | * Don't "fix" this (unless newer Debian does). | ||
1076 | */ | ||
1069 | buf = xasprintf("run-parts /etc/network/if-%s.d", opt); | 1077 | buf = xasprintf("run-parts /etc/network/if-%s.d", opt); |
1070 | /* heh, we don't bother free'ing it */ | 1078 | /* heh, we don't bother free'ing it */ |
1071 | return doit(buf); | 1079 | return doit(buf); |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index e674e9a0d..48dc6e3d9 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -362,10 +362,9 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
362 | req.r.rtm_scope = RT_SCOPE_NOWHERE; | 362 | req.r.rtm_scope = RT_SCOPE_NOWHERE; |
363 | 363 | ||
364 | if (cmd != RTM_DELROUTE) { | 364 | if (cmd != RTM_DELROUTE) { |
365 | req.r.rtm_scope = RT_SCOPE_UNIVERSE; | ||
365 | if (RTPROT_BOOT != 0) | 366 | if (RTPROT_BOOT != 0) |
366 | req.r.rtm_protocol = RTPROT_BOOT; | 367 | req.r.rtm_protocol = RTPROT_BOOT; |
367 | if (RT_SCOPE_UNIVERSE != 0) | ||
368 | req.r.rtm_scope = RT_SCOPE_UNIVERSE; | ||
369 | if (RTN_UNICAST != 0) | 368 | if (RTN_UNICAST != 0) |
370 | req.r.rtm_type = RTN_UNICAST; | 369 | req.r.rtm_type = RTN_UNICAST; |
371 | } | 370 | } |
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index dba64346f..c486834b0 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c | |||
@@ -197,9 +197,11 @@ static int iprule_modify(int cmd, char **argv) | |||
197 | req.n.nlmsg_flags = NLM_F_REQUEST; | 197 | req.n.nlmsg_flags = NLM_F_REQUEST; |
198 | req.r.rtm_family = preferred_family; | 198 | req.r.rtm_family = preferred_family; |
199 | req.r.rtm_protocol = RTPROT_BOOT; | 199 | req.r.rtm_protocol = RTPROT_BOOT; |
200 | req.r.rtm_scope = RT_SCOPE_UNIVERSE; | 200 | if (RT_SCOPE_UNIVERSE != 0) |
201 | req.r.rtm_table = 0; | 201 | req.r.rtm_scope = RT_SCOPE_UNIVERSE; |
202 | req.r.rtm_type = RTN_UNSPEC; | 202 | /*req.r.rtm_table = 0; - already is */ |
203 | if (RTN_UNSPEC != 0) | ||
204 | req.r.rtm_type = RTN_UNSPEC; | ||
203 | 205 | ||
204 | if (cmd == RTM_NEWRULE) { | 206 | if (cmd == RTM_NEWRULE) { |
205 | req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL; | 207 | req.n.nlmsg_flags |= NLM_F_CREATE|NLM_F_EXCL; |
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c index cbb5daf95..7e0ff1b6c 100644 --- a/networking/libiproute/libnetlink.c +++ b/networking/libiproute/libnetlink.c | |||
@@ -68,30 +68,32 @@ int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len) | |||
68 | 68 | ||
69 | int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) | 69 | int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) |
70 | { | 70 | { |
71 | struct nlmsghdr nlh; | 71 | struct { |
72 | struct sockaddr_nl nladdr; | 72 | struct nlmsghdr nlh; |
73 | struct iovec iov[2] = { { &nlh, sizeof(nlh) }, { req, len } }; | 73 | struct msghdr msg; |
74 | /* Use designated initializers, struct layout is non-portable */ | 74 | struct sockaddr_nl nladdr; |
75 | struct msghdr msg = { | 75 | } s; |
76 | .msg_name = (void*)&nladdr, | 76 | struct iovec iov[2] = { { &s.nlh, sizeof(s.nlh) }, { req, len } }; |
77 | .msg_namelen = sizeof(nladdr), | 77 | |
78 | .msg_iov = iov, | 78 | memset(&s, 0, sizeof(s)); |
79 | .msg_iovlen = 2, | 79 | |
80 | .msg_control = NULL, | 80 | s.msg.msg_name = (void*)&s.nladdr; |
81 | .msg_controllen = 0, | 81 | s.msg.msg_namelen = sizeof(s.nladdr); |
82 | .msg_flags = 0 | 82 | s.msg.msg_iov = iov; |
83 | }; | 83 | s.msg.msg_iovlen = 2; |
84 | 84 | /*s.msg.msg_control = NULL; - already is */ | |
85 | memset(&nladdr, 0, sizeof(nladdr)); | 85 | /*s.msg.msg_controllen = 0; - already is */ |
86 | nladdr.nl_family = AF_NETLINK; | 86 | /*s.msg.msg_flags = 0; - already is */ |
87 | 87 | ||
88 | nlh.nlmsg_len = NLMSG_LENGTH(len); | 88 | s.nladdr.nl_family = AF_NETLINK; |
89 | nlh.nlmsg_type = type; | 89 | |
90 | nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; | 90 | s.nlh.nlmsg_len = NLMSG_LENGTH(len); |
91 | nlh.nlmsg_pid = 0; | 91 | s.nlh.nlmsg_type = type; |
92 | nlh.nlmsg_seq = rth->dump = ++rth->seq; | 92 | s.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; |
93 | 93 | /*s.nlh.nlmsg_pid = 0; - already is */ | |
94 | return sendmsg(rth->fd, &msg, 0); | 94 | s.nlh.nlmsg_seq = rth->dump = ++rth->seq; |
95 | |||
96 | return sendmsg(rth->fd, &s.msg, 0); | ||
95 | } | 97 | } |
96 | 98 | ||
97 | static int rtnl_dump_filter(struct rtnl_handle *rth, | 99 | static int rtnl_dump_filter(struct rtnl_handle *rth, |
@@ -338,14 +340,14 @@ int FAST_FUNC addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data) | |||
338 | int len = RTA_LENGTH(4); | 340 | int len = RTA_LENGTH(4); |
339 | struct rtattr *rta; | 341 | struct rtattr *rta; |
340 | 342 | ||
341 | if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { | 343 | if ((int)(NLMSG_ALIGN(n->nlmsg_len + len)) > maxlen) { |
342 | return -1; | 344 | return -1; |
343 | } | 345 | } |
344 | rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); | 346 | rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); |
345 | rta->rta_type = type; | 347 | rta->rta_type = type; |
346 | rta->rta_len = len; | 348 | rta->rta_len = len; |
347 | move_to_unaligned32(RTA_DATA(rta), data); | 349 | move_to_unaligned32(RTA_DATA(rta), data); |
348 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; | 350 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len + len); |
349 | return 0; | 351 | return 0; |
350 | } | 352 | } |
351 | 353 | ||
@@ -354,14 +356,14 @@ int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, in | |||
354 | int len = RTA_LENGTH(alen); | 356 | int len = RTA_LENGTH(alen); |
355 | struct rtattr *rta; | 357 | struct rtattr *rta; |
356 | 358 | ||
357 | if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { | 359 | if ((int)(NLMSG_ALIGN(n->nlmsg_len + len)) > maxlen) { |
358 | return -1; | 360 | return -1; |
359 | } | 361 | } |
360 | rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); | 362 | rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); |
361 | rta->rta_type = type; | 363 | rta->rta_type = type; |
362 | rta->rta_len = len; | 364 | rta->rta_len = len; |
363 | memcpy(RTA_DATA(rta), data, alen); | 365 | memcpy(RTA_DATA(rta), data, alen); |
364 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + len; | 366 | n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len + len); |
365 | return 0; | 367 | return 0; |
366 | } | 368 | } |
367 | 369 | ||
@@ -370,14 +372,14 @@ int FAST_FUNC rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t d | |||
370 | int len = RTA_LENGTH(4); | 372 | int len = RTA_LENGTH(4); |
371 | struct rtattr *subrta; | 373 | struct rtattr *subrta; |
372 | 374 | ||
373 | if (RTA_ALIGN(rta->rta_len) + len > maxlen) { | 375 | if (RTA_ALIGN(rta->rta_len + len) > maxlen) { |
374 | return -1; | 376 | return -1; |
375 | } | 377 | } |
376 | subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); | 378 | subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); |
377 | subrta->rta_type = type; | 379 | subrta->rta_type = type; |
378 | subrta->rta_len = len; | 380 | subrta->rta_len = len; |
379 | move_to_unaligned32(RTA_DATA(subrta), data); | 381 | move_to_unaligned32(RTA_DATA(subrta), data); |
380 | rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; | 382 | rta->rta_len = NLMSG_ALIGN(rta->rta_len + len); |
381 | return 0; | 383 | return 0; |
382 | } | 384 | } |
383 | 385 | ||
@@ -386,14 +388,14 @@ int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data | |||
386 | struct rtattr *subrta; | 388 | struct rtattr *subrta; |
387 | int len = RTA_LENGTH(alen); | 389 | int len = RTA_LENGTH(alen); |
388 | 390 | ||
389 | if (RTA_ALIGN(rta->rta_len) + len > maxlen) { | 391 | if (RTA_ALIGN(rta->rta_len + len) > maxlen) { |
390 | return -1; | 392 | return -1; |
391 | } | 393 | } |
392 | subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); | 394 | subrta = (struct rtattr*)(((char*)rta) + RTA_ALIGN(rta->rta_len)); |
393 | subrta->rta_type = type; | 395 | subrta->rta_type = type; |
394 | subrta->rta_len = len; | 396 | subrta->rta_len = len; |
395 | memcpy(RTA_DATA(subrta), data, alen); | 397 | memcpy(RTA_DATA(subrta), data, alen); |
396 | rta->rta_len = NLMSG_ALIGN(rta->rta_len) + len; | 398 | rta->rta_len = NLMSG_ALIGN(rta->rta_len + len); |
397 | return 0; | 399 | return 0; |
398 | } | 400 | } |
399 | 401 | ||
diff --git a/networking/ntpd.c b/networking/ntpd.c index 130cef0af..8ca62cf1b 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -2051,6 +2051,13 @@ recv_and_process_client_pkt(void /*int fd*/) | |||
2051 | goto bail; | 2051 | goto bail; |
2052 | } | 2052 | } |
2053 | 2053 | ||
2054 | /* Respond only to client and symmetric active packets */ | ||
2055 | if ((msg.m_status & MODE_MASK) != MODE_CLIENT | ||
2056 | && (msg.m_status & MODE_MASK) != MODE_SYM_ACT | ||
2057 | ) { | ||
2058 | goto bail; | ||
2059 | } | ||
2060 | |||
2054 | query_status = msg.m_status; | 2061 | query_status = msg.m_status; |
2055 | query_xmttime = msg.m_xmttime; | 2062 | query_xmttime = msg.m_xmttime; |
2056 | 2063 | ||
diff --git a/networking/route.c b/networking/route.c index 65c2fb7c8..102a6ec67 100644 --- a/networking/route.c +++ b/networking/route.c | |||
@@ -295,7 +295,7 @@ static NOINLINE void INET_setroute(int action, char **args) | |||
295 | #endif | 295 | #endif |
296 | 296 | ||
297 | /* Device is special in that it can be the last arg specified | 297 | /* Device is special in that it can be the last arg specified |
298 | * and doesn't requre the dev/device keyword in that case. */ | 298 | * and doesn't require the dev/device keyword in that case. */ |
299 | if (!rt->rt_dev && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { | 299 | if (!rt->rt_dev && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { |
300 | /* Don't use args_m1 here since args may have changed! */ | 300 | /* Don't use args_m1 here since args may have changed! */ |
301 | rt->rt_dev = args[-1]; | 301 | rt->rt_dev = args[-1]; |
@@ -416,7 +416,7 @@ static NOINLINE void INET6_setroute(int action, char **args) | |||
416 | } | 416 | } |
417 | 417 | ||
418 | /* Device is special in that it can be the last arg specified | 418 | /* Device is special in that it can be the last arg specified |
419 | * and doesn't requre the dev/device keyword in that case. */ | 419 | * and doesn't require the dev/device keyword in that case. */ |
420 | if (!devname && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { | 420 | if (!devname && ((k == KW_IPVx_DEVICE) || (!k && !*++args))) { |
421 | /* Don't use args_m1 here since args may have changed! */ | 421 | /* Don't use args_m1 here since args may have changed! */ |
422 | devname = args[-1]; | 422 | devname = args[-1]; |
diff --git a/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.9.8 b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.9.8 new file mode 100755 index 000000000..208a7087d --- /dev/null +++ b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.9.8 | |||
@@ -0,0 +1,39 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # How to configure & build a static wolfssl library | ||
4 | # suitable for static build of ssl_helper. | ||
5 | |||
6 | export CC="i686-gcc" | ||
7 | export CFLAGS="\ | ||
8 | -Os \ | ||
9 | -static \ | ||
10 | -fomit-frame-pointer \ | ||
11 | -falign-functions=1 -falign-labels=1 -falign-loops=1 -falign-jumps=1 \ | ||
12 | -ffunction-sections -fdata-sections \ | ||
13 | " | ||
14 | |||
15 | { | ||
16 | |||
17 | ./configure \ | ||
18 | --host="i686" \ | ||
19 | --enable-static \ | ||
20 | --enable-singlethreaded \ | ||
21 | --disable-shared \ | ||
22 | \ | ||
23 | C_EXTRA_FLAGS="-DWOLFSSL_STATIC_RSA" \ | ||
24 | || exit $? | ||
25 | |||
26 | # The second group of options was added when "vanilla" config did not work. | ||
27 | # A good tool to debug problems is to try wolfssl's client tool, e.g.: | ||
28 | # examples/client/client -h www.google.com -p 443 -d -x | ||
29 | # | ||
30 | # configure has many other options, see ./configure --help | ||
31 | # --enable-ecc \ | ||
32 | # --enable-sni \ | ||
33 | # | ||
34 | # Also consult "wolfSSL - Embedded SSL Library Product Support Forums" | ||
35 | # for recent report of users having problems connecting. | ||
36 | |||
37 | make | ||
38 | |||
39 | } 2>&1 | tee "$0.log" | ||
diff --git a/networking/ssl_helper-wolfssl/README b/networking/ssl_helper-wolfssl/README index 58a381c20..ff46f4bdf 100644 --- a/networking/ssl_helper-wolfssl/README +++ b/networking/ssl_helper-wolfssl/README | |||
@@ -11,6 +11,13 @@ Build instructions: | |||
11 | * Drop this directory into wolfssl-3.6.8/ssl_helper | 11 | * Drop this directory into wolfssl-3.6.8/ssl_helper |
12 | * Run ssl_helper.sh to compile and link the helper | 12 | * Run ssl_helper.sh to compile and link the helper |
13 | 13 | ||
14 | * Unpack wolfssl-3.9.8.tar.gz from https://github.com/wolfSSL/wolfssl/releases | ||
15 | * Create configure: | ||
16 | ./autogen.sh | ||
17 | * Build it: see 00cfg-wolfssl-3.9.8 shell script | ||
18 | * Drop this directory into wolfssl-x.y.z/ssl_helper | ||
19 | * Run ssl_helper.sh to compile and link the helper | ||
20 | |||
14 | Usage: "ssl_helper -d FILE_DESCRIPTOR" where FILE_DESCRIPTOR is open to the peer. | 21 | Usage: "ssl_helper -d FILE_DESCRIPTOR" where FILE_DESCRIPTOR is open to the peer. |
15 | 22 | ||
16 | In bash, you can do it this way: | 23 | In bash, you can do it this way: |
diff --git a/networking/ssl_helper-wolfssl/ssl_helper.sh b/networking/ssl_helper-wolfssl/ssl_helper.sh index 184ffe67e..c6cbf353f 100755 --- a/networking/ssl_helper-wolfssl/ssl_helper.sh +++ b/networking/ssl_helper-wolfssl/ssl_helper.sh | |||
@@ -9,4 +9,4 @@ STATIC="-static" | |||
9 | 9 | ||
10 | ${PREFIX}gcc -Os -Wall -I.. -c ssl_helper.c -o ssl_helper.o | 10 | ${PREFIX}gcc -Os -Wall -I.. -c ssl_helper.c -o ssl_helper.o |
11 | ${PREFIX}gcc $STATIC --start-group ssl_helper.o -lm ../src/.libs/libwolfssl.a --end-group -o ssl_helper | 11 | ${PREFIX}gcc $STATIC --start-group ssl_helper.o -lm ../src/.libs/libwolfssl.a --end-group -o ssl_helper |
12 | ${PREFIX}-strip ssl_helper | 12 | ${PREFIX}strip ssl_helper |
diff --git a/networking/traceroute.c b/networking/traceroute.c index e43a36dc7..b9a9ca4bb 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -212,8 +212,7 @@ | |||
212 | 212 | ||
213 | //usage:#define traceroute_trivial_usage | 213 | //usage:#define traceroute_trivial_usage |
214 | //usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" | 214 | //usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" |
215 | //usage: " [-t TOS] [-w WAIT_SEC]" | 215 | //usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n" |
216 | //usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n" | ||
217 | //usage: " [-z PAUSE_MSEC] HOST [BYTES]" | 216 | //usage: " [-z PAUSE_MSEC] HOST [BYTES]" |
218 | //usage:#define traceroute_full_usage "\n\n" | 217 | //usage:#define traceroute_full_usage "\n\n" |
219 | //usage: "Trace the route to HOST\n" | 218 | //usage: "Trace the route to HOST\n" |
@@ -294,7 +293,6 @@ | |||
294 | 293 | ||
295 | #define OPT_STRING \ | 294 | #define OPT_STRING \ |
296 | "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ | 295 | "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ |
297 | IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:*") \ | ||
298 | "4" IF_TRACEROUTE6("6") | 296 | "4" IF_TRACEROUTE6("6") |
299 | enum { | 297 | enum { |
300 | OPT_DONT_FRAGMNT = (1 << 0), /* F */ | 298 | OPT_DONT_FRAGMNT = (1 << 0), /* F */ |
@@ -314,9 +312,8 @@ enum { | |||
314 | OPT_WAITTIME = (1 << 14), /* w */ | 312 | OPT_WAITTIME = (1 << 14), /* w */ |
315 | OPT_PAUSE_MS = (1 << 15), /* z */ | 313 | OPT_PAUSE_MS = (1 << 15), /* z */ |
316 | OPT_FIRST_TTL = (1 << 16), /* f */ | 314 | OPT_FIRST_TTL = (1 << 16), /* f */ |
317 | OPT_SOURCE_ROUTE = (1 << 17) * ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE, /* g */ | 315 | OPT_IPV4 = (1 << 17), /* 4 */ |
318 | OPT_IPV4 = (1 << (17+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)), /* 4 */ | 316 | OPT_IPV6 = (1 << 18) * ENABLE_TRACEROUTE6, /* 6 */ |
319 | OPT_IPV6 = (1 << (18+ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE)) * ENABLE_TRACEROUTE6, /* 6 */ | ||
320 | }; | 317 | }; |
321 | #define verbose (option_mask32 & OPT_VERBOSE) | 318 | #define verbose (option_mask32 & OPT_VERBOSE) |
322 | 319 | ||
@@ -343,26 +340,18 @@ struct outdata6_t { | |||
343 | #endif | 340 | #endif |
344 | 341 | ||
345 | struct globals { | 342 | struct globals { |
343 | /* Pointer to entire malloced IP packet, "packlen" bytes long: */ | ||
346 | struct ip *outip; | 344 | struct ip *outip; |
345 | /* Pointer to ICMP or UDP payload (not header): */ | ||
347 | struct outdata_t *outdata; | 346 | struct outdata_t *outdata; |
347 | |||
348 | len_and_sockaddr *dest_lsa; | 348 | len_and_sockaddr *dest_lsa; |
349 | int packlen; /* total length of packet */ | 349 | int packlen; /* total length of packet */ |
350 | int pmtu; /* Path MTU Discovery (RFC1191) */ | 350 | int pmtu; /* Path MTU Discovery (RFC1191) */ |
351 | uint32_t ident; | 351 | uint32_t ident; |
352 | uint16_t port; // 32768 + 666; /* start udp dest port # for probe packets */ | 352 | uint16_t port; // 33434; /* start udp dest port # for probe packets */ |
353 | int waittime; // 5; /* time to wait for response (in seconds) */ | 353 | int waittime; // 5; /* time to wait for response (in seconds) */ |
354 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
355 | int optlen; /* length of ip options */ | ||
356 | #else | ||
357 | #define optlen 0 | ||
358 | #endif | ||
359 | unsigned char recv_pkt[512]; /* last inbound (icmp) packet */ | 354 | unsigned char recv_pkt[512]; /* last inbound (icmp) packet */ |
360 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
361 | /* Maximum number of gateways (include room for one noop) */ | ||
362 | #define NGATEWAYS ((int)((MAX_IPOPTLEN - IPOPT_MINOFF - 1) / sizeof(uint32_t))) | ||
363 | /* loose source route gateway list (including room for final destination) */ | ||
364 | uint32_t gwlist[NGATEWAYS + 1]; | ||
365 | #endif | ||
366 | }; | 355 | }; |
367 | 356 | ||
368 | #define G (*ptr_to_globals) | 357 | #define G (*ptr_to_globals) |
@@ -374,14 +363,11 @@ struct globals { | |||
374 | #define ident (G.ident ) | 363 | #define ident (G.ident ) |
375 | #define port (G.port ) | 364 | #define port (G.port ) |
376 | #define waittime (G.waittime ) | 365 | #define waittime (G.waittime ) |
377 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
378 | # define optlen (G.optlen ) | ||
379 | #endif | ||
380 | #define recv_pkt (G.recv_pkt ) | 366 | #define recv_pkt (G.recv_pkt ) |
381 | #define gwlist (G.gwlist ) | 367 | #define gwlist (G.gwlist ) |
382 | #define INIT_G() do { \ | 368 | #define INIT_G() do { \ |
383 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 369 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
384 | port = 32768 + 666; \ | 370 | port = 33434; \ |
385 | waittime = 5; \ | 371 | waittime = 5; \ |
386 | } while (0) | 372 | } while (0) |
387 | 373 | ||
@@ -421,7 +407,7 @@ send_probe(int seq, int ttl) | |||
421 | /* Payload */ | 407 | /* Payload */ |
422 | #if ENABLE_TRACEROUTE6 | 408 | #if ENABLE_TRACEROUTE6 |
423 | if (dest_lsa->u.sa.sa_family == AF_INET6) { | 409 | if (dest_lsa->u.sa.sa_family == AF_INET6) { |
424 | struct outdata6_t *pkt = (struct outdata6_t *) outip; | 410 | struct outdata6_t *pkt = (struct outdata6_t *) outdata; |
425 | pkt->ident6 = htonl(ident); | 411 | pkt->ident6 = htonl(ident); |
426 | pkt->seq6 = htonl(seq); | 412 | pkt->seq6 = htonl(seq); |
427 | /*gettimeofday(&pkt->tv, &tz);*/ | 413 | /*gettimeofday(&pkt->tv, &tz);*/ |
@@ -438,8 +424,10 @@ send_probe(int seq, int ttl) | |||
438 | 424 | ||
439 | /* Always calculate checksum for icmp packets */ | 425 | /* Always calculate checksum for icmp packets */ |
440 | outicmp->icmp_cksum = 0; | 426 | outicmp->icmp_cksum = 0; |
441 | outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp, | 427 | outicmp->icmp_cksum = inet_cksum( |
442 | packlen - (sizeof(*outip) + optlen)); | 428 | (uint16_t *)outicmp, |
429 | ((char*)outip + packlen) - (char*)outicmp | ||
430 | ); | ||
443 | if (outicmp->icmp_cksum == 0) | 431 | if (outicmp->icmp_cksum == 0) |
444 | outicmp->icmp_cksum = 0xffff; | 432 | outicmp->icmp_cksum = 0xffff; |
445 | } | 433 | } |
@@ -471,13 +459,12 @@ send_probe(int seq, int ttl) | |||
471 | } | 459 | } |
472 | #endif | 460 | #endif |
473 | 461 | ||
462 | out = outdata; | ||
474 | #if ENABLE_TRACEROUTE6 | 463 | #if ENABLE_TRACEROUTE6 |
475 | if (dest_lsa->u.sa.sa_family == AF_INET6) { | 464 | if (dest_lsa->u.sa.sa_family == AF_INET6) { |
476 | res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); | 465 | res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); |
477 | if (res != 0) | 466 | if (res != 0) |
478 | bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); | 467 | bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); |
479 | out = outip; | ||
480 | len = packlen; | ||
481 | } else | 468 | } else |
482 | #endif | 469 | #endif |
483 | { | 470 | { |
@@ -486,15 +473,14 @@ send_probe(int seq, int ttl) | |||
486 | if (res != 0) | 473 | if (res != 0) |
487 | bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); | 474 | bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); |
488 | #endif | 475 | #endif |
489 | out = outicmp; | 476 | if (option_mask32 & OPT_USE_ICMP) |
490 | len = packlen - sizeof(*outip); | 477 | out = outicmp; |
491 | if (!(option_mask32 & OPT_USE_ICMP)) { | ||
492 | out = outdata; | ||
493 | len -= sizeof(*outudp); | ||
494 | set_nport(&dest_lsa->u.sa, htons(port + seq)); | ||
495 | } | ||
496 | } | 478 | } |
497 | 479 | ||
480 | if (!(option_mask32 & OPT_USE_ICMP)) { | ||
481 | set_nport(&dest_lsa->u.sa, htons(port + seq)); | ||
482 | } | ||
483 | len = ((char*)outip + packlen) - (char*)out; | ||
498 | res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); | 484 | res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); |
499 | if (res != len) | 485 | if (res != len) |
500 | bb_error_msg("sent %d octets, ret=%d", len, res); | 486 | bb_error_msg("sent %d octets, ret=%d", len, res); |
@@ -801,10 +787,6 @@ common_traceroute_main(int op, char **argv) | |||
801 | char *pausemsecs_str; | 787 | char *pausemsecs_str; |
802 | char *first_ttl_str; | 788 | char *first_ttl_str; |
803 | char *dest_str; | 789 | char *dest_str; |
804 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
805 | llist_t *source_route_list = NULL; | ||
806 | int lsrr = 0; | ||
807 | #endif | ||
808 | #if ENABLE_TRACEROUTE6 | 790 | #if ENABLE_TRACEROUTE6 |
809 | sa_family_t af; | 791 | sa_family_t af; |
810 | #else | 792 | #else |
@@ -823,9 +805,6 @@ common_traceroute_main(int op, char **argv) | |||
823 | op |= getopt32(argv, OPT_STRING | 805 | op |= getopt32(argv, OPT_STRING |
824 | , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str | 806 | , &tos_str, &device, &max_ttl_str, &port_str, &nprobes_str |
825 | , &source, &waittime_str, &pausemsecs_str, &first_ttl_str | 807 | , &source, &waittime_str, &pausemsecs_str, &first_ttl_str |
826 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
827 | , &source_route_list | ||
828 | #endif | ||
829 | ); | 808 | ); |
830 | argv += optind; | 809 | argv += optind; |
831 | 810 | ||
@@ -858,26 +837,14 @@ common_traceroute_main(int op, char **argv) | |||
858 | if (op & OPT_FIRST_TTL) | 837 | if (op & OPT_FIRST_TTL) |
859 | first_ttl = xatou_range(first_ttl_str, 1, max_ttl); | 838 | first_ttl = xatou_range(first_ttl_str, 1, max_ttl); |
860 | 839 | ||
861 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE | ||
862 | if (source_route_list) { | ||
863 | while (source_route_list) { | ||
864 | len_and_sockaddr *lsa; | ||
865 | |||
866 | if (lsrr >= NGATEWAYS) | ||
867 | bb_error_msg_and_die("no more than %d gateways", NGATEWAYS); | ||
868 | lsa = xhost_and_af2sockaddr(llist_pop(&source_route_list), 0, AF_INET); | ||
869 | gwlist[lsrr] = lsa->u.sin.sin_addr.s_addr; | ||
870 | free(lsa); | ||
871 | ++lsrr; | ||
872 | } | ||
873 | optlen = (lsrr + 1) * sizeof(gwlist[0]); | ||
874 | } | ||
875 | #endif | ||
876 | |||
877 | /* Process destination and optional packet size */ | 840 | /* Process destination and optional packet size */ |
878 | minpacket = sizeof(*outip) + SIZEOF_ICMP_HDR + sizeof(*outdata) + optlen; | 841 | minpacket = sizeof(struct ip) |
842 | + SIZEOF_ICMP_HDR | ||
843 | + sizeof(struct outdata_t); | ||
879 | if (!(op & OPT_USE_ICMP)) | 844 | if (!(op & OPT_USE_ICMP)) |
880 | minpacket += sizeof(*outudp) - SIZEOF_ICMP_HDR; | 845 | minpacket = sizeof(struct ip) |
846 | + sizeof(struct udphdr) | ||
847 | + sizeof(struct outdata_t); | ||
881 | #if ENABLE_TRACEROUTE6 | 848 | #if ENABLE_TRACEROUTE6 |
882 | af = AF_UNSPEC; | 849 | af = AF_UNSPEC; |
883 | if (op & OPT_IPV4) | 850 | if (op & OPT_IPV4) |
@@ -887,7 +854,9 @@ common_traceroute_main(int op, char **argv) | |||
887 | dest_lsa = xhost_and_af2sockaddr(argv[0], port, af); | 854 | dest_lsa = xhost_and_af2sockaddr(argv[0], port, af); |
888 | af = dest_lsa->u.sa.sa_family; | 855 | af = dest_lsa->u.sa.sa_family; |
889 | if (af == AF_INET6) | 856 | if (af == AF_INET6) |
890 | minpacket = sizeof(struct outdata6_t); | 857 | minpacket = sizeof(struct ip6_hdr) |
858 | + sizeof(struct udphdr) | ||
859 | + sizeof(struct outdata6_t); | ||
891 | #else | 860 | #else |
892 | dest_lsa = xhost2sockaddr(argv[0], port); | 861 | dest_lsa = xhost2sockaddr(argv[0], port); |
893 | #endif | 862 | #endif |
@@ -932,31 +901,6 @@ common_traceroute_main(int op, char **argv) | |||
932 | xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock); | 901 | xmove_fd(xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP), sndsock); |
933 | else | 902 | else |
934 | xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock); | 903 | xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), sndsock); |
935 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS | ||
936 | if (lsrr > 0) { | ||
937 | unsigned char optlist[MAX_IPOPTLEN]; | ||
938 | unsigned size; | ||
939 | |||
940 | /* final hop */ | ||
941 | gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr; | ||
942 | ++lsrr; | ||
943 | |||
944 | /* force 4 byte alignment */ | ||
945 | optlist[0] = IPOPT_NOP; | ||
946 | /* loose source route option */ | ||
947 | optlist[1] = IPOPT_LSRR; | ||
948 | size = lsrr * sizeof(gwlist[0]); | ||
949 | optlist[2] = size + 3; | ||
950 | /* pointer to LSRR addresses */ | ||
951 | optlist[3] = IPOPT_MINOFF; | ||
952 | memcpy(optlist + 4, gwlist, size); | ||
953 | |||
954 | if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, | ||
955 | (char *)optlist, size + sizeof(gwlist[0])) < 0) { | ||
956 | bb_perror_msg_and_die("IP_OPTIONS"); | ||
957 | } | ||
958 | } | ||
959 | #endif | ||
960 | } | 904 | } |
961 | 905 | ||
962 | #ifdef SO_SNDBUF | 906 | #ifdef SO_SNDBUF |
@@ -984,7 +928,7 @@ common_traceroute_main(int op, char **argv) | |||
984 | 928 | ||
985 | ident = getpid(); | 929 | ident = getpid(); |
986 | 930 | ||
987 | if (af == AF_INET) { | 931 | if (!ENABLE_TRACEROUTE6 || af == AF_INET) { |
988 | if (op & OPT_USE_ICMP) { | 932 | if (op & OPT_USE_ICMP) { |
989 | ident |= 0x8000; | 933 | ident |= 0x8000; |
990 | outicmp->icmp_type = ICMP_ECHO; | 934 | outicmp->icmp_type = ICMP_ECHO; |
@@ -994,6 +938,14 @@ common_traceroute_main(int op, char **argv) | |||
994 | outdata = (struct outdata_t *)(outudp + 1); | 938 | outdata = (struct outdata_t *)(outudp + 1); |
995 | } | 939 | } |
996 | } | 940 | } |
941 | #if ENABLE_TRACEROUTE6 | ||
942 | if (af == AF_INET6) { | ||
943 | outdata = (void*)((char*)outip | ||
944 | + sizeof(struct ip6_hdr) | ||
945 | + sizeof(struct udphdr) | ||
946 | ); | ||
947 | } | ||
948 | #endif | ||
997 | 949 | ||
998 | if (op & OPT_DEVICE) /* hmm, do we need error check? */ | 950 | if (op & OPT_DEVICE) /* hmm, do we need error check? */ |
999 | setsockopt_bindtodevice(sndsock, device); | 951 | setsockopt_bindtodevice(sndsock, device); |
diff --git a/networking/udhcp/Kbuild.src b/networking/udhcp/Kbuild.src index b8767baea..5ea77df06 100644 --- a/networking/udhcp/Kbuild.src +++ b/networking/udhcp/Kbuild.src | |||
@@ -13,7 +13,7 @@ lib-$(CONFIG_UDHCPC) += common.o packet.o signalpipe.o socket.o | |||
13 | lib-$(CONFIG_UDHCPD) += common.o packet.o signalpipe.o socket.o | 13 | lib-$(CONFIG_UDHCPD) += common.o packet.o signalpipe.o socket.o |
14 | 14 | ||
15 | lib-$(CONFIG_UDHCPC) += dhcpc.o | 15 | lib-$(CONFIG_UDHCPC) += dhcpc.o |
16 | lib-$(CONFIG_UDHCPD) += dhcpd.o arpping.o files.o leases.o static_leases.o | 16 | lib-$(CONFIG_UDHCPD) += dhcpd.o arpping.o |
17 | lib-$(CONFIG_DUMPLEASES) += dumpleases.o | 17 | lib-$(CONFIG_DUMPLEASES) += dumpleases.o |
18 | lib-$(CONFIG_DHCPRELAY) += dhcprelay.o | 18 | lib-$(CONFIG_DHCPRELAY) += dhcprelay.o |
19 | 19 | ||
diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c index c98027316..215d023ce 100644 --- a/networking/udhcp/arpping.c +++ b/networking/udhcp/arpping.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <net/if_arp.h> | 9 | #include <net/if_arp.h> |
10 | 10 | ||
11 | #include "common.h" | 11 | #include "common.h" |
12 | #include "dhcpd.h" | ||
13 | 12 | ||
14 | struct arpMsg { | 13 | struct arpMsg { |
15 | /* Ethernet header */ | 14 | /* Ethernet header */ |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 6ff040d9e..ddf3412a0 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -800,10 +800,15 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou | |||
800 | ) { | 800 | ) { |
801 | bb_error_msg("unicasting a release"); | 801 | bb_error_msg("unicasting a release"); |
802 | send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ | 802 | send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ |
803 | d6_run_script(NULL, "deconfig"); | ||
804 | } | 803 | } |
805 | bb_error_msg("entering released state"); | 804 | bb_error_msg("entering released state"); |
806 | 805 | /* | |
806 | * We can be here on: SIGUSR2, | ||
807 | * or on exit (SIGTERM) and -R "release on quit" is specified. | ||
808 | * Users requested to be notified in all cases, even if not in one | ||
809 | * of the states above. | ||
810 | */ | ||
811 | d6_run_script(NULL, "deconfig"); | ||
807 | change_listen_mode(LISTEN_NONE); | 812 | change_listen_mode(LISTEN_NONE); |
808 | state = RELEASED; | 813 | state = RELEASED; |
809 | } | 814 | } |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 8a16e987d..bef73277a 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -1129,9 +1129,15 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) | |||
1129 | bb_error_msg("unicasting a release of %s to %s", | 1129 | bb_error_msg("unicasting a release of %s to %s", |
1130 | inet_ntoa(temp_addr), buffer); | 1130 | inet_ntoa(temp_addr), buffer); |
1131 | send_release(server_addr, requested_ip); /* unicast */ | 1131 | send_release(server_addr, requested_ip); /* unicast */ |
1132 | udhcp_run_script(NULL, "deconfig"); | ||
1133 | } | 1132 | } |
1134 | bb_error_msg("entering released state"); | 1133 | bb_error_msg("entering released state"); |
1134 | /* | ||
1135 | * We can be here on: SIGUSR2, | ||
1136 | * or on exit (SIGTERM) and -R "release on quit" is specified. | ||
1137 | * Users requested to be notified in all cases, even if not in one | ||
1138 | * of the states above. | ||
1139 | */ | ||
1140 | udhcp_run_script(NULL, "deconfig"); | ||
1135 | 1141 | ||
1136 | change_listen_mode(LISTEN_NONE); | 1142 | change_listen_mode(LISTEN_NONE); |
1137 | state = RELEASED; | 1143 | state = RELEASED; |
@@ -1813,9 +1819,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1813 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); | 1819 | temp = udhcp_get_option(&packet, DHCP_SERVER_ID); |
1814 | if (!temp) { | 1820 | if (!temp) { |
1815 | non_matching_svid: | 1821 | non_matching_svid: |
1816 | log1("%s with wrong server ID, ignoring packet", | 1822 | log1("received DHCP NAK with wrong" |
1817 | "Received DHCP NAK" | 1823 | " server ID, ignoring packet"); |
1818 | ); | ||
1819 | continue; | 1824 | continue; |
1820 | } | 1825 | } |
1821 | move_from_unaligned32(svid, temp); | 1826 | move_from_unaligned32(svid, temp); |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index e93a9f1da..56116d01f 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -33,11 +33,507 @@ | |||
33 | //usage: "\n -P N Use port N (default 67)" | 33 | //usage: "\n -P N Use port N (default 67)" |
34 | //usage: ) | 34 | //usage: ) |
35 | 35 | ||
36 | #include <netinet/ether.h> | ||
36 | #include <syslog.h> | 37 | #include <syslog.h> |
37 | #include "common.h" | 38 | #include "common.h" |
38 | #include "dhcpc.h" | 39 | #include "dhcpc.h" |
39 | #include "dhcpd.h" | 40 | #include "dhcpd.h" |
40 | 41 | ||
42 | /* globals */ | ||
43 | struct dyn_lease *g_leases; | ||
44 | /* struct server_config_t server_config is in bb_common_bufsiz1 */ | ||
45 | |||
46 | /* Takes the address of the pointer to the static_leases linked list, | ||
47 | * address to a 6 byte mac address, | ||
48 | * 4 byte IP address */ | ||
49 | static void add_static_lease(struct static_lease **st_lease_pp, | ||
50 | uint8_t *mac, | ||
51 | uint32_t nip) | ||
52 | { | ||
53 | struct static_lease *st_lease; | ||
54 | |||
55 | /* Find the tail of the list */ | ||
56 | while ((st_lease = *st_lease_pp) != NULL) { | ||
57 | st_lease_pp = &st_lease->next; | ||
58 | } | ||
59 | |||
60 | /* Add new node */ | ||
61 | *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease)); | ||
62 | memcpy(st_lease->mac, mac, 6); | ||
63 | st_lease->nip = nip; | ||
64 | /*st_lease->next = NULL;*/ | ||
65 | } | ||
66 | |||
67 | /* Find static lease IP by mac */ | ||
68 | static uint32_t get_static_nip_by_mac(struct static_lease *st_lease, void *mac) | ||
69 | { | ||
70 | while (st_lease) { | ||
71 | if (memcmp(st_lease->mac, mac, 6) == 0) | ||
72 | return st_lease->nip; | ||
73 | st_lease = st_lease->next; | ||
74 | } | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int is_nip_reserved(struct static_lease *st_lease, uint32_t nip) | ||
80 | { | ||
81 | while (st_lease) { | ||
82 | if (st_lease->nip == nip) | ||
83 | return 1; | ||
84 | st_lease = st_lease->next; | ||
85 | } | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | ||
91 | /* Print out static leases just to check what's going on */ | ||
92 | /* Takes the address of the pointer to the static_leases linked list */ | ||
93 | static void log_static_leases(struct static_lease **st_lease_pp) | ||
94 | { | ||
95 | struct static_lease *cur; | ||
96 | |||
97 | if (dhcp_verbose < 2) | ||
98 | return; | ||
99 | |||
100 | cur = *st_lease_pp; | ||
101 | while (cur) { | ||
102 | bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", | ||
103 | cur->mac[0], cur->mac[1], cur->mac[2], | ||
104 | cur->mac[3], cur->mac[4], cur->mac[5], | ||
105 | cur->nip | ||
106 | ); | ||
107 | cur = cur->next; | ||
108 | } | ||
109 | } | ||
110 | #else | ||
111 | # define log_static_leases(st_lease_pp) ((void)0) | ||
112 | #endif | ||
113 | |||
114 | /* Find the oldest expired lease, NULL if there are no expired leases */ | ||
115 | static struct dyn_lease *oldest_expired_lease(void) | ||
116 | { | ||
117 | struct dyn_lease *oldest_lease = NULL; | ||
118 | leasetime_t oldest_time = time(NULL); | ||
119 | unsigned i; | ||
120 | |||
121 | /* Unexpired leases have g_leases[i].expires >= current time | ||
122 | * and therefore can't ever match */ | ||
123 | for (i = 0; i < server_config.max_leases; i++) { | ||
124 | if (g_leases[i].expires == 0 /* empty entry */ | ||
125 | || g_leases[i].expires < oldest_time | ||
126 | ) { | ||
127 | oldest_time = g_leases[i].expires; | ||
128 | oldest_lease = &g_leases[i]; | ||
129 | } | ||
130 | } | ||
131 | return oldest_lease; | ||
132 | } | ||
133 | |||
134 | /* Clear out all leases with matching nonzero chaddr OR yiaddr. | ||
135 | * If chaddr == NULL, this is a conflict lease. | ||
136 | */ | ||
137 | static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr) | ||
138 | { | ||
139 | unsigned i; | ||
140 | |||
141 | for (i = 0; i < server_config.max_leases; i++) { | ||
142 | if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) | ||
143 | || (yiaddr && g_leases[i].lease_nip == yiaddr) | ||
144 | ) { | ||
145 | memset(&g_leases[i], 0, sizeof(g_leases[i])); | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | |||
150 | /* Add a lease into the table, clearing out any old ones. | ||
151 | * If chaddr == NULL, this is a conflict lease. | ||
152 | */ | ||
153 | static struct dyn_lease *add_lease( | ||
154 | const uint8_t *chaddr, uint32_t yiaddr, | ||
155 | leasetime_t leasetime, | ||
156 | const char *hostname, int hostname_len) | ||
157 | { | ||
158 | struct dyn_lease *oldest; | ||
159 | |||
160 | /* clean out any old ones */ | ||
161 | clear_leases(chaddr, yiaddr); | ||
162 | |||
163 | oldest = oldest_expired_lease(); | ||
164 | |||
165 | if (oldest) { | ||
166 | memset(oldest, 0, sizeof(*oldest)); | ||
167 | if (hostname) { | ||
168 | char *p; | ||
169 | |||
170 | hostname_len++; /* include NUL */ | ||
171 | if (hostname_len > sizeof(oldest->hostname)) | ||
172 | hostname_len = sizeof(oldest->hostname); | ||
173 | p = safe_strncpy(oldest->hostname, hostname, hostname_len); | ||
174 | /* | ||
175 | * Sanitization (s/bad_char/./g). | ||
176 | * The intent is not to allow only "DNS-valid" hostnames, | ||
177 | * but merely make dumpleases output safe for shells to use. | ||
178 | * We accept "0-9A-Za-z._-", all other chars turn to dots. | ||
179 | */ | ||
180 | while (*p) { | ||
181 | if (!isalnum(*p) && *p != '-' && *p != '_') | ||
182 | *p = '.'; | ||
183 | p++; | ||
184 | } | ||
185 | } | ||
186 | if (chaddr) | ||
187 | memcpy(oldest->lease_mac, chaddr, 6); | ||
188 | oldest->lease_nip = yiaddr; | ||
189 | oldest->expires = time(NULL) + leasetime; | ||
190 | } | ||
191 | |||
192 | return oldest; | ||
193 | } | ||
194 | |||
195 | /* True if a lease has expired */ | ||
196 | static int is_expired_lease(struct dyn_lease *lease) | ||
197 | { | ||
198 | return (lease->expires < (leasetime_t) time(NULL)); | ||
199 | } | ||
200 | |||
201 | /* Find the first lease that matches MAC, NULL if no match */ | ||
202 | static struct dyn_lease *find_lease_by_mac(const uint8_t *mac) | ||
203 | { | ||
204 | unsigned i; | ||
205 | |||
206 | for (i = 0; i < server_config.max_leases; i++) | ||
207 | if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) | ||
208 | return &g_leases[i]; | ||
209 | |||
210 | return NULL; | ||
211 | } | ||
212 | |||
213 | /* Find the first lease that matches IP, NULL is no match */ | ||
214 | static struct dyn_lease *find_lease_by_nip(uint32_t nip) | ||
215 | { | ||
216 | unsigned i; | ||
217 | |||
218 | for (i = 0; i < server_config.max_leases; i++) | ||
219 | if (g_leases[i].lease_nip == nip) | ||
220 | return &g_leases[i]; | ||
221 | |||
222 | return NULL; | ||
223 | } | ||
224 | |||
225 | /* Check if the IP is taken; if it is, add it to the lease table */ | ||
226 | static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms) | ||
227 | { | ||
228 | struct in_addr temp; | ||
229 | int r; | ||
230 | |||
231 | r = arpping(nip, safe_mac, | ||
232 | server_config.server_nip, | ||
233 | server_config.server_mac, | ||
234 | server_config.interface, | ||
235 | arpping_ms); | ||
236 | if (r) | ||
237 | return r; | ||
238 | |||
239 | temp.s_addr = nip; | ||
240 | bb_error_msg("%s belongs to someone, reserving it for %u seconds", | ||
241 | inet_ntoa(temp), (unsigned)server_config.conflict_time); | ||
242 | add_lease(NULL, nip, server_config.conflict_time, NULL, 0); | ||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | /* Find a new usable (we think) address */ | ||
247 | static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) | ||
248 | { | ||
249 | uint32_t addr; | ||
250 | struct dyn_lease *oldest_lease = NULL; | ||
251 | |||
252 | #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC | ||
253 | uint32_t stop; | ||
254 | unsigned i, hash; | ||
255 | |||
256 | /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good | ||
257 | * dispersal even with similarly-valued "strings". | ||
258 | */ | ||
259 | hash = 0; | ||
260 | for (i = 0; i < 6; i++) | ||
261 | hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; | ||
262 | |||
263 | /* pick a seed based on hwaddr then iterate until we find a free address. */ | ||
264 | addr = server_config.start_ip | ||
265 | + (hash % (1 + server_config.end_ip - server_config.start_ip)); | ||
266 | stop = addr; | ||
267 | #else | ||
268 | addr = server_config.start_ip; | ||
269 | #define stop (server_config.end_ip + 1) | ||
270 | #endif | ||
271 | do { | ||
272 | uint32_t nip; | ||
273 | struct dyn_lease *lease; | ||
274 | |||
275 | /* ie, 192.168.55.0 */ | ||
276 | if ((addr & 0xff) == 0) | ||
277 | goto next_addr; | ||
278 | /* ie, 192.168.55.255 */ | ||
279 | if ((addr & 0xff) == 0xff) | ||
280 | goto next_addr; | ||
281 | nip = htonl(addr); | ||
282 | /* skip our own address */ | ||
283 | if (nip == server_config.server_nip) | ||
284 | goto next_addr; | ||
285 | /* is this a static lease addr? */ | ||
286 | if (is_nip_reserved(server_config.static_leases, nip)) | ||
287 | goto next_addr; | ||
288 | |||
289 | lease = find_lease_by_nip(nip); | ||
290 | if (!lease) { | ||
291 | //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! | ||
292 | if (nobody_responds_to_arp(nip, safe_mac, arpping_ms)) | ||
293 | return nip; | ||
294 | } else { | ||
295 | if (!oldest_lease || lease->expires < oldest_lease->expires) | ||
296 | oldest_lease = lease; | ||
297 | } | ||
298 | |||
299 | next_addr: | ||
300 | addr++; | ||
301 | #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC | ||
302 | if (addr > server_config.end_ip) | ||
303 | addr = server_config.start_ip; | ||
304 | #endif | ||
305 | } while (addr != stop); | ||
306 | |||
307 | if (oldest_lease | ||
308 | && is_expired_lease(oldest_lease) | ||
309 | && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms) | ||
310 | ) { | ||
311 | return oldest_lease->lease_nip; | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | /* On these functions, make sure your datatype matches */ | ||
318 | static int FAST_FUNC read_str(const char *line, void *arg) | ||
319 | { | ||
320 | char **dest = arg; | ||
321 | |||
322 | free(*dest); | ||
323 | *dest = xstrdup(line); | ||
324 | return 1; | ||
325 | } | ||
326 | |||
327 | static int FAST_FUNC read_u32(const char *line, void *arg) | ||
328 | { | ||
329 | *(uint32_t*)arg = bb_strtou32(line, NULL, 10); | ||
330 | return errno == 0; | ||
331 | } | ||
332 | |||
333 | static int FAST_FUNC read_staticlease(const char *const_line, void *arg) | ||
334 | { | ||
335 | char *line; | ||
336 | char *mac_string; | ||
337 | char *ip_string; | ||
338 | struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */ | ||
339 | uint32_t nip; | ||
340 | |||
341 | /* Read mac */ | ||
342 | line = (char *) const_line; | ||
343 | mac_string = strtok_r(line, " \t", &line); | ||
344 | if (!mac_string || !ether_aton_r(mac_string, &mac_bytes)) | ||
345 | return 0; | ||
346 | |||
347 | /* Read ip */ | ||
348 | ip_string = strtok_r(NULL, " \t", &line); | ||
349 | if (!ip_string || !udhcp_str2nip(ip_string, &nip)) | ||
350 | return 0; | ||
351 | |||
352 | add_static_lease(arg, (uint8_t*) &mac_bytes, nip); | ||
353 | |||
354 | log_static_leases(arg); | ||
355 | |||
356 | return 1; | ||
357 | } | ||
358 | |||
359 | struct config_keyword { | ||
360 | const char *keyword; | ||
361 | int (*handler)(const char *line, void *var) FAST_FUNC; | ||
362 | unsigned ofs; | ||
363 | const char *def; | ||
364 | }; | ||
365 | |||
366 | #define OFS(field) offsetof(struct server_config_t, field) | ||
367 | |||
368 | static const struct config_keyword keywords[] = { | ||
369 | /* keyword handler variable address default */ | ||
370 | {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, | ||
371 | {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, | ||
372 | {"interface" , read_str , OFS(interface ), "eth0"}, | ||
373 | /* Avoid "max_leases value not sane" warning by setting default | ||
374 | * to default_end_ip - default_start_ip + 1: */ | ||
375 | {"max_leases" , read_u32 , OFS(max_leases ), "235"}, | ||
376 | {"auto_time" , read_u32 , OFS(auto_time ), "7200"}, | ||
377 | {"decline_time" , read_u32 , OFS(decline_time ), "3600"}, | ||
378 | {"conflict_time", read_u32 , OFS(conflict_time), "3600"}, | ||
379 | {"offer_time" , read_u32 , OFS(offer_time ), "60"}, | ||
380 | {"min_lease" , read_u32 , OFS(min_lease_sec), "60"}, | ||
381 | {"lease_file" , read_str , OFS(lease_file ), LEASES_FILE}, | ||
382 | {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, | ||
383 | {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, | ||
384 | /* keywords with no defaults must be last! */ | ||
385 | {"option" , udhcp_str2optset, OFS(options ), ""}, | ||
386 | {"opt" , udhcp_str2optset, OFS(options ), ""}, | ||
387 | {"notify_file" , read_str , OFS(notify_file ), NULL}, | ||
388 | {"sname" , read_str , OFS(sname ), NULL}, | ||
389 | {"boot_file" , read_str , OFS(boot_file ), NULL}, | ||
390 | {"static_lease" , read_staticlease, OFS(static_leases), ""}, | ||
391 | }; | ||
392 | enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; | ||
393 | |||
394 | static NOINLINE void read_config(const char *file) | ||
395 | { | ||
396 | parser_t *parser; | ||
397 | const struct config_keyword *k; | ||
398 | unsigned i; | ||
399 | char *token[2]; | ||
400 | |||
401 | for (i = 0; i < KWS_WITH_DEFAULTS; i++) | ||
402 | keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); | ||
403 | |||
404 | parser = config_open(file); | ||
405 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { | ||
406 | for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { | ||
407 | if (strcasecmp(token[0], k->keyword) == 0) { | ||
408 | if (!k->handler(token[1], (char*)&server_config + k->ofs)) { | ||
409 | bb_error_msg("can't parse line %u in %s", | ||
410 | parser->lineno, file); | ||
411 | /* reset back to the default value */ | ||
412 | k->handler(k->def, (char*)&server_config + k->ofs); | ||
413 | } | ||
414 | break; | ||
415 | } | ||
416 | } | ||
417 | } | ||
418 | config_close(parser); | ||
419 | |||
420 | server_config.start_ip = ntohl(server_config.start_ip); | ||
421 | server_config.end_ip = ntohl(server_config.end_ip); | ||
422 | } | ||
423 | |||
424 | static void write_leases(void) | ||
425 | { | ||
426 | int fd; | ||
427 | unsigned i; | ||
428 | leasetime_t curr; | ||
429 | int64_t written_at; | ||
430 | |||
431 | fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC); | ||
432 | if (fd < 0) | ||
433 | return; | ||
434 | |||
435 | curr = written_at = time(NULL); | ||
436 | |||
437 | written_at = SWAP_BE64(written_at); | ||
438 | full_write(fd, &written_at, sizeof(written_at)); | ||
439 | |||
440 | for (i = 0; i < server_config.max_leases; i++) { | ||
441 | leasetime_t tmp_time; | ||
442 | |||
443 | if (g_leases[i].lease_nip == 0) | ||
444 | continue; | ||
445 | |||
446 | /* Screw with the time in the struct, for easier writing */ | ||
447 | tmp_time = g_leases[i].expires; | ||
448 | |||
449 | g_leases[i].expires -= curr; | ||
450 | if ((signed_leasetime_t) g_leases[i].expires < 0) | ||
451 | g_leases[i].expires = 0; | ||
452 | g_leases[i].expires = htonl(g_leases[i].expires); | ||
453 | |||
454 | /* No error check. If the file gets truncated, | ||
455 | * we lose some leases on restart. Oh well. */ | ||
456 | full_write(fd, &g_leases[i], sizeof(g_leases[i])); | ||
457 | |||
458 | /* Then restore it when done */ | ||
459 | g_leases[i].expires = tmp_time; | ||
460 | } | ||
461 | close(fd); | ||
462 | |||
463 | if (server_config.notify_file) { | ||
464 | char *argv[3]; | ||
465 | argv[0] = server_config.notify_file; | ||
466 | argv[1] = server_config.lease_file; | ||
467 | argv[2] = NULL; | ||
468 | spawn_and_wait(argv); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | static NOINLINE void read_leases(const char *file) | ||
473 | { | ||
474 | struct dyn_lease lease; | ||
475 | int64_t written_at, time_passed; | ||
476 | int fd; | ||
477 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
478 | unsigned i = 0; | ||
479 | #endif | ||
480 | |||
481 | fd = open_or_warn(file, O_RDONLY); | ||
482 | if (fd < 0) | ||
483 | return; | ||
484 | |||
485 | if (full_read(fd, &written_at, sizeof(written_at)) != sizeof(written_at)) | ||
486 | goto ret; | ||
487 | written_at = SWAP_BE64(written_at); | ||
488 | |||
489 | time_passed = time(NULL) - written_at; | ||
490 | /* Strange written_at, or lease file from old version of udhcpd | ||
491 | * which had no "written_at" field? */ | ||
492 | if ((uint64_t)time_passed > 12 * 60 * 60) | ||
493 | goto ret; | ||
494 | |||
495 | while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { | ||
496 | uint32_t y = ntohl(lease.lease_nip); | ||
497 | if (y >= server_config.start_ip && y <= server_config.end_ip) { | ||
498 | signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; | ||
499 | uint32_t static_nip; | ||
500 | |||
501 | if (expires <= 0) | ||
502 | /* We keep expired leases: add_lease() will add | ||
503 | * a lease with 0 seconds remaining. | ||
504 | * Fewer IP address changes this way for mass reboot scenario. | ||
505 | */ | ||
506 | expires = 0; | ||
507 | |||
508 | /* Check if there is a different static lease for this IP or MAC */ | ||
509 | static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); | ||
510 | if (static_nip) { | ||
511 | /* NB: we do not add lease even if static_nip == lease.lease_nip. | ||
512 | */ | ||
513 | continue; | ||
514 | } | ||
515 | if (is_nip_reserved(server_config.static_leases, lease.lease_nip)) | ||
516 | continue; | ||
517 | |||
518 | /* NB: add_lease takes "relative time", IOW, | ||
519 | * lease duration, not lease deadline. */ | ||
520 | if (add_lease(lease.lease_mac, lease.lease_nip, | ||
521 | expires, | ||
522 | lease.hostname, sizeof(lease.hostname) | ||
523 | ) == 0 | ||
524 | ) { | ||
525 | bb_error_msg("too many leases while loading %s", file); | ||
526 | break; | ||
527 | } | ||
528 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
529 | i++; | ||
530 | #endif | ||
531 | } | ||
532 | } | ||
533 | log1("read %d leases", i); | ||
534 | ret: | ||
535 | close(fd); | ||
536 | } | ||
41 | 537 | ||
42 | /* Send a packet to a specific mac address and ip address by creating our own ip packet */ | 538 | /* Send a packet to a specific mac address and ip address by creating our own ip packet */ |
43 | static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadcast) | 539 | static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadcast) |
@@ -290,12 +786,6 @@ static NOINLINE void send_inform(struct dhcp_packet *oldpacket) | |||
290 | send_packet(&packet, /*force_bcast:*/ 0); | 786 | send_packet(&packet, /*force_bcast:*/ 0); |
291 | } | 787 | } |
292 | 788 | ||
293 | |||
294 | /* globals */ | ||
295 | struct dyn_lease *g_leases; | ||
296 | /* struct server_config_t server_config is in bb_common_bufsiz1 */ | ||
297 | |||
298 | |||
299 | int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 789 | int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
300 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) | 790 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) |
301 | { | 791 | { |
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index 9dd5bef9e..b8f96b029 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h | |||
@@ -90,39 +90,6 @@ struct dyn_lease { | |||
90 | /* total size is a multiply of 4 */ | 90 | /* total size is a multiply of 4 */ |
91 | } PACKED; | 91 | } PACKED; |
92 | 92 | ||
93 | extern struct dyn_lease *g_leases; | ||
94 | |||
95 | struct dyn_lease *add_lease( | ||
96 | const uint8_t *chaddr, uint32_t yiaddr, | ||
97 | leasetime_t leasetime, | ||
98 | const char *hostname, int hostname_len | ||
99 | ) 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; | ||
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, unsigned arpping_ms) FAST_FUNC; | ||
104 | |||
105 | |||
106 | /* Config file parser will pass static lease info to this function | ||
107 | * which will add it to a data structure that can be searched later */ | ||
108 | void add_static_lease(struct static_lease **st_lease_pp, uint8_t *mac, uint32_t nip) FAST_FUNC; | ||
109 | /* Find static lease IP by mac */ | ||
110 | uint32_t get_static_nip_by_mac(struct static_lease *st_lease, void *arg) FAST_FUNC; | ||
111 | /* Check to see if an IP is reserved as a static IP */ | ||
112 | int is_nip_reserved(struct static_lease *st_lease, uint32_t nip) FAST_FUNC; | ||
113 | /* Print out static leases just to check what's going on (debug code) */ | ||
114 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | ||
115 | void log_static_leases(struct static_lease **st_lease_pp) FAST_FUNC; | ||
116 | #else | ||
117 | # define log_static_leases(st_lease_pp) ((void)0) | ||
118 | #endif | ||
119 | |||
120 | |||
121 | void read_config(const char *file) FAST_FUNC; | ||
122 | void write_leases(void) FAST_FUNC; | ||
123 | void read_leases(const char *file) FAST_FUNC; | ||
124 | |||
125 | |||
126 | POP_SAVED_FUNCTION_VISIBILITY | 93 | POP_SAVED_FUNCTION_VISIBILITY |
127 | 94 | ||
128 | #endif | 95 | #endif |
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c deleted file mode 100644 index b22425352..000000000 --- a/networking/udhcp/files.c +++ /dev/null | |||
@@ -1,234 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * DHCP server config and lease file manipulation | ||
4 | * | ||
5 | * Rewrite by Russ Dill <Russ.Dill@asu.edu> July 2001 | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | #include <netinet/ether.h> | ||
10 | |||
11 | #include "common.h" | ||
12 | #include "dhcpd.h" | ||
13 | |||
14 | /* on these functions, make sure your datatype matches */ | ||
15 | static int FAST_FUNC read_str(const char *line, void *arg) | ||
16 | { | ||
17 | char **dest = arg; | ||
18 | |||
19 | free(*dest); | ||
20 | *dest = xstrdup(line); | ||
21 | return 1; | ||
22 | } | ||
23 | |||
24 | static int FAST_FUNC read_u32(const char *line, void *arg) | ||
25 | { | ||
26 | *(uint32_t*)arg = bb_strtou32(line, NULL, 10); | ||
27 | return errno == 0; | ||
28 | } | ||
29 | |||
30 | static int FAST_FUNC read_staticlease(const char *const_line, void *arg) | ||
31 | { | ||
32 | char *line; | ||
33 | char *mac_string; | ||
34 | char *ip_string; | ||
35 | struct ether_addr mac_bytes; /* it's "struct { uint8_t mac[6]; }" */ | ||
36 | uint32_t nip; | ||
37 | |||
38 | /* Read mac */ | ||
39 | line = (char *) const_line; | ||
40 | mac_string = strtok_r(line, " \t", &line); | ||
41 | if (!mac_string || !ether_aton_r(mac_string, &mac_bytes)) | ||
42 | return 0; | ||
43 | |||
44 | /* Read ip */ | ||
45 | ip_string = strtok_r(NULL, " \t", &line); | ||
46 | if (!ip_string || !udhcp_str2nip(ip_string, &nip)) | ||
47 | return 0; | ||
48 | |||
49 | add_static_lease(arg, (uint8_t*) &mac_bytes, nip); | ||
50 | |||
51 | log_static_leases(arg); | ||
52 | |||
53 | return 1; | ||
54 | } | ||
55 | |||
56 | |||
57 | struct config_keyword { | ||
58 | const char *keyword; | ||
59 | int (*handler)(const char *line, void *var) FAST_FUNC; | ||
60 | unsigned ofs; | ||
61 | const char *def; | ||
62 | }; | ||
63 | |||
64 | #define OFS(field) offsetof(struct server_config_t, field) | ||
65 | |||
66 | static const struct config_keyword keywords[] = { | ||
67 | /* keyword handler variable address default */ | ||
68 | {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, | ||
69 | {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, | ||
70 | {"interface" , read_str , OFS(interface ), "eth0"}, | ||
71 | /* Avoid "max_leases value not sane" warning by setting default | ||
72 | * to default_end_ip - default_start_ip + 1: */ | ||
73 | {"max_leases" , read_u32 , OFS(max_leases ), "235"}, | ||
74 | {"auto_time" , read_u32 , OFS(auto_time ), "7200"}, | ||
75 | {"decline_time" , read_u32 , OFS(decline_time ), "3600"}, | ||
76 | {"conflict_time", read_u32 , OFS(conflict_time), "3600"}, | ||
77 | {"offer_time" , read_u32 , OFS(offer_time ), "60"}, | ||
78 | {"min_lease" , read_u32 , OFS(min_lease_sec), "60"}, | ||
79 | {"lease_file" , read_str , OFS(lease_file ), LEASES_FILE}, | ||
80 | {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, | ||
81 | {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, | ||
82 | /* keywords with no defaults must be last! */ | ||
83 | {"option" , udhcp_str2optset, OFS(options ), ""}, | ||
84 | {"opt" , udhcp_str2optset, OFS(options ), ""}, | ||
85 | {"notify_file" , read_str , OFS(notify_file ), NULL}, | ||
86 | {"sname" , read_str , OFS(sname ), NULL}, | ||
87 | {"boot_file" , read_str , OFS(boot_file ), NULL}, | ||
88 | {"static_lease" , read_staticlease, OFS(static_leases), ""}, | ||
89 | }; | ||
90 | enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; | ||
91 | |||
92 | void FAST_FUNC read_config(const char *file) | ||
93 | { | ||
94 | parser_t *parser; | ||
95 | const struct config_keyword *k; | ||
96 | unsigned i; | ||
97 | char *token[2]; | ||
98 | |||
99 | for (i = 0; i < KWS_WITH_DEFAULTS; i++) | ||
100 | keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); | ||
101 | |||
102 | parser = config_open(file); | ||
103 | while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { | ||
104 | for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { | ||
105 | if (strcasecmp(token[0], k->keyword) == 0) { | ||
106 | if (!k->handler(token[1], (char*)&server_config + k->ofs)) { | ||
107 | bb_error_msg("can't parse line %u in %s", | ||
108 | parser->lineno, file); | ||
109 | /* reset back to the default value */ | ||
110 | k->handler(k->def, (char*)&server_config + k->ofs); | ||
111 | } | ||
112 | break; | ||
113 | } | ||
114 | } | ||
115 | } | ||
116 | config_close(parser); | ||
117 | |||
118 | server_config.start_ip = ntohl(server_config.start_ip); | ||
119 | server_config.end_ip = ntohl(server_config.end_ip); | ||
120 | } | ||
121 | |||
122 | void FAST_FUNC write_leases(void) | ||
123 | { | ||
124 | int fd; | ||
125 | unsigned i; | ||
126 | leasetime_t curr; | ||
127 | int64_t written_at; | ||
128 | |||
129 | fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC); | ||
130 | if (fd < 0) | ||
131 | return; | ||
132 | |||
133 | curr = written_at = time(NULL); | ||
134 | |||
135 | written_at = SWAP_BE64(written_at); | ||
136 | full_write(fd, &written_at, sizeof(written_at)); | ||
137 | |||
138 | for (i = 0; i < server_config.max_leases; i++) { | ||
139 | leasetime_t tmp_time; | ||
140 | |||
141 | if (g_leases[i].lease_nip == 0) | ||
142 | continue; | ||
143 | |||
144 | /* Screw with the time in the struct, for easier writing */ | ||
145 | tmp_time = g_leases[i].expires; | ||
146 | |||
147 | g_leases[i].expires -= curr; | ||
148 | if ((signed_leasetime_t) g_leases[i].expires < 0) | ||
149 | g_leases[i].expires = 0; | ||
150 | g_leases[i].expires = htonl(g_leases[i].expires); | ||
151 | |||
152 | /* No error check. If the file gets truncated, | ||
153 | * we lose some leases on restart. Oh well. */ | ||
154 | full_write(fd, &g_leases[i], sizeof(g_leases[i])); | ||
155 | |||
156 | /* Then restore it when done */ | ||
157 | g_leases[i].expires = tmp_time; | ||
158 | } | ||
159 | close(fd); | ||
160 | |||
161 | if (server_config.notify_file) { | ||
162 | char *argv[3]; | ||
163 | argv[0] = server_config.notify_file; | ||
164 | argv[1] = server_config.lease_file; | ||
165 | argv[2] = NULL; | ||
166 | spawn_and_wait(argv); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | void FAST_FUNC read_leases(const char *file) | ||
171 | { | ||
172 | struct dyn_lease lease; | ||
173 | int64_t written_at, time_passed; | ||
174 | int fd; | ||
175 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
176 | unsigned i = 0; | ||
177 | #endif | ||
178 | |||
179 | fd = open_or_warn(file, O_RDONLY); | ||
180 | if (fd < 0) | ||
181 | return; | ||
182 | |||
183 | if (full_read(fd, &written_at, sizeof(written_at)) != sizeof(written_at)) | ||
184 | goto ret; | ||
185 | written_at = SWAP_BE64(written_at); | ||
186 | |||
187 | time_passed = time(NULL) - written_at; | ||
188 | /* Strange written_at, or lease file from old version of udhcpd | ||
189 | * which had no "written_at" field? */ | ||
190 | if ((uint64_t)time_passed > 12 * 60 * 60) | ||
191 | goto ret; | ||
192 | |||
193 | while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { | ||
194 | uint32_t y = ntohl(lease.lease_nip); | ||
195 | if (y >= server_config.start_ip && y <= server_config.end_ip) { | ||
196 | signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; | ||
197 | uint32_t static_nip; | ||
198 | |||
199 | if (expires <= 0) | ||
200 | /* We keep expired leases: add_lease() will add | ||
201 | * a lease with 0 seconds remaining. | ||
202 | * Fewer IP address changes this way for mass reboot scenario. | ||
203 | */ | ||
204 | expires = 0; | ||
205 | |||
206 | /* Check if there is a different static lease for this IP or MAC */ | ||
207 | static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); | ||
208 | if (static_nip) { | ||
209 | /* NB: we do not add lease even if static_nip == lease.lease_nip. | ||
210 | */ | ||
211 | continue; | ||
212 | } | ||
213 | if (is_nip_reserved(server_config.static_leases, lease.lease_nip)) | ||
214 | continue; | ||
215 | |||
216 | /* NB: add_lease takes "relative time", IOW, | ||
217 | * lease duration, not lease deadline. */ | ||
218 | if (add_lease(lease.lease_mac, lease.lease_nip, | ||
219 | expires, | ||
220 | lease.hostname, sizeof(lease.hostname) | ||
221 | ) == 0 | ||
222 | ) { | ||
223 | bb_error_msg("too many leases while loading %s", file); | ||
224 | break; | ||
225 | } | ||
226 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 | ||
227 | i++; | ||
228 | #endif | ||
229 | } | ||
230 | } | ||
231 | log1("read %d leases", i); | ||
232 | ret: | ||
233 | close(fd); | ||
234 | } | ||
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c deleted file mode 100644 index 6642e396d..000000000 --- a/networking/udhcp/leases.c +++ /dev/null | |||
@@ -1,211 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Russ Dill <Russ.Dill@asu.edu> July 2001 | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | #include "common.h" | ||
8 | #include "dhcpd.h" | ||
9 | |||
10 | /* Find the oldest expired lease, NULL if there are no expired leases */ | ||
11 | static struct dyn_lease *oldest_expired_lease(void) | ||
12 | { | ||
13 | struct dyn_lease *oldest_lease = NULL; | ||
14 | leasetime_t oldest_time = time(NULL); | ||
15 | unsigned i; | ||
16 | |||
17 | /* Unexpired leases have g_leases[i].expires >= current time | ||
18 | * and therefore can't ever match */ | ||
19 | for (i = 0; i < server_config.max_leases; i++) { | ||
20 | if (g_leases[i].expires == 0 /* empty entry */ | ||
21 | || g_leases[i].expires < oldest_time | ||
22 | ) { | ||
23 | oldest_time = g_leases[i].expires; | ||
24 | oldest_lease = &g_leases[i]; | ||
25 | } | ||
26 | } | ||
27 | return oldest_lease; | ||
28 | } | ||
29 | |||
30 | /* Clear out all leases with matching nonzero chaddr OR yiaddr. | ||
31 | * If chaddr == NULL, this is a conflict lease. | ||
32 | */ | ||
33 | static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr) | ||
34 | { | ||
35 | unsigned i; | ||
36 | |||
37 | for (i = 0; i < server_config.max_leases; i++) { | ||
38 | if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) | ||
39 | || (yiaddr && g_leases[i].lease_nip == yiaddr) | ||
40 | ) { | ||
41 | memset(&g_leases[i], 0, sizeof(g_leases[i])); | ||
42 | } | ||
43 | } | ||
44 | } | ||
45 | |||
46 | /* Add a lease into the table, clearing out any old ones. | ||
47 | * If chaddr == NULL, this is a conflict lease. | ||
48 | */ | ||
49 | struct dyn_lease* FAST_FUNC add_lease( | ||
50 | const uint8_t *chaddr, uint32_t yiaddr, | ||
51 | leasetime_t leasetime, | ||
52 | const char *hostname, int hostname_len) | ||
53 | { | ||
54 | struct dyn_lease *oldest; | ||
55 | |||
56 | /* clean out any old ones */ | ||
57 | clear_leases(chaddr, yiaddr); | ||
58 | |||
59 | oldest = oldest_expired_lease(); | ||
60 | |||
61 | if (oldest) { | ||
62 | memset(oldest, 0, sizeof(*oldest)); | ||
63 | if (hostname) { | ||
64 | char *p; | ||
65 | |||
66 | hostname_len++; /* include NUL */ | ||
67 | if (hostname_len > sizeof(oldest->hostname)) | ||
68 | hostname_len = sizeof(oldest->hostname); | ||
69 | p = safe_strncpy(oldest->hostname, hostname, hostname_len); | ||
70 | /* | ||
71 | * Sanitization (s/bad_char/./g). | ||
72 | * The intent is not to allow only "DNS-valid" hostnames, | ||
73 | * but merely make dumpleases output safe for shells to use. | ||
74 | * We accept "0-9A-Za-z._-", all other chars turn to dots. | ||
75 | */ | ||
76 | while (*p) { | ||
77 | if (!isalnum(*p) && *p != '-' && *p != '_') | ||
78 | *p = '.'; | ||
79 | p++; | ||
80 | } | ||
81 | } | ||
82 | if (chaddr) | ||
83 | memcpy(oldest->lease_mac, chaddr, 6); | ||
84 | oldest->lease_nip = yiaddr; | ||
85 | oldest->expires = time(NULL) + leasetime; | ||
86 | } | ||
87 | |||
88 | return oldest; | ||
89 | } | ||
90 | |||
91 | /* True if a lease has expired */ | ||
92 | int FAST_FUNC is_expired_lease(struct dyn_lease *lease) | ||
93 | { | ||
94 | return (lease->expires < (leasetime_t) time(NULL)); | ||
95 | } | ||
96 | |||
97 | /* Find the first lease that matches MAC, NULL if no match */ | ||
98 | struct dyn_lease* FAST_FUNC find_lease_by_mac(const uint8_t *mac) | ||
99 | { | ||
100 | unsigned i; | ||
101 | |||
102 | for (i = 0; i < server_config.max_leases; i++) | ||
103 | if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) | ||
104 | return &g_leases[i]; | ||
105 | |||
106 | return NULL; | ||
107 | } | ||
108 | |||
109 | /* Find the first lease that matches IP, NULL is no match */ | ||
110 | struct dyn_lease* FAST_FUNC find_lease_by_nip(uint32_t nip) | ||
111 | { | ||
112 | unsigned i; | ||
113 | |||
114 | for (i = 0; i < server_config.max_leases; i++) | ||
115 | if (g_leases[i].lease_nip == nip) | ||
116 | return &g_leases[i]; | ||
117 | |||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | /* Check if the IP is taken; if it is, add it to the lease table */ | ||
122 | static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigned arpping_ms) | ||
123 | { | ||
124 | struct in_addr temp; | ||
125 | int r; | ||
126 | |||
127 | r = arpping(nip, safe_mac, | ||
128 | server_config.server_nip, | ||
129 | server_config.server_mac, | ||
130 | server_config.interface, | ||
131 | arpping_ms); | ||
132 | if (r) | ||
133 | return r; | ||
134 | |||
135 | temp.s_addr = nip; | ||
136 | bb_error_msg("%s belongs to someone, reserving it for %u seconds", | ||
137 | inet_ntoa(temp), (unsigned)server_config.conflict_time); | ||
138 | add_lease(NULL, nip, server_config.conflict_time, NULL, 0); | ||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | /* Find a new usable (we think) address */ | ||
143 | uint32_t FAST_FUNC find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arpping_ms) | ||
144 | { | ||
145 | uint32_t addr; | ||
146 | struct dyn_lease *oldest_lease = NULL; | ||
147 | |||
148 | #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC | ||
149 | uint32_t stop; | ||
150 | unsigned i, hash; | ||
151 | |||
152 | /* hash hwaddr: use the SDBM hashing algorithm. Seems to give good | ||
153 | * dispersal even with similarly-valued "strings". | ||
154 | */ | ||
155 | hash = 0; | ||
156 | for (i = 0; i < 6; i++) | ||
157 | hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; | ||
158 | |||
159 | /* pick a seed based on hwaddr then iterate until we find a free address. */ | ||
160 | addr = server_config.start_ip | ||
161 | + (hash % (1 + server_config.end_ip - server_config.start_ip)); | ||
162 | stop = addr; | ||
163 | #else | ||
164 | addr = server_config.start_ip; | ||
165 | #define stop (server_config.end_ip + 1) | ||
166 | #endif | ||
167 | do { | ||
168 | uint32_t nip; | ||
169 | struct dyn_lease *lease; | ||
170 | |||
171 | /* ie, 192.168.55.0 */ | ||
172 | if ((addr & 0xff) == 0) | ||
173 | goto next_addr; | ||
174 | /* ie, 192.168.55.255 */ | ||
175 | if ((addr & 0xff) == 0xff) | ||
176 | goto next_addr; | ||
177 | nip = htonl(addr); | ||
178 | /* skip our own address */ | ||
179 | if (nip == server_config.server_nip) | ||
180 | goto next_addr; | ||
181 | /* is this a static lease addr? */ | ||
182 | if (is_nip_reserved(server_config.static_leases, nip)) | ||
183 | goto next_addr; | ||
184 | |||
185 | lease = find_lease_by_nip(nip); | ||
186 | if (!lease) { | ||
187 | //TODO: DHCP servers do not always sit on the same subnet as clients: should *ping*, not arp-ping! | ||
188 | if (nobody_responds_to_arp(nip, safe_mac, arpping_ms)) | ||
189 | return nip; | ||
190 | } else { | ||
191 | if (!oldest_lease || lease->expires < oldest_lease->expires) | ||
192 | oldest_lease = lease; | ||
193 | } | ||
194 | |||
195 | next_addr: | ||
196 | addr++; | ||
197 | #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC | ||
198 | if (addr > server_config.end_ip) | ||
199 | addr = server_config.start_ip; | ||
200 | #endif | ||
201 | } while (addr != stop); | ||
202 | |||
203 | if (oldest_lease | ||
204 | && is_expired_lease(oldest_lease) | ||
205 | && nobody_responds_to_arp(oldest_lease->lease_nip, safe_mac, arpping_ms) | ||
206 | ) { | ||
207 | return oldest_lease->lease_nip; | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
diff --git a/networking/udhcp/static_leases.c b/networking/udhcp/static_leases.c deleted file mode 100644 index b7f9e5c59..000000000 --- a/networking/udhcp/static_leases.c +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Storing and retrieving data for static leases | ||
4 | * | ||
5 | * Wade Berrier <wberrier@myrealbox.com> September 2004 | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | #include "common.h" | ||
10 | #include "dhcpd.h" | ||
11 | |||
12 | /* Takes the address of the pointer to the static_leases linked list, | ||
13 | * address to a 6 byte mac address, | ||
14 | * 4 byte IP address */ | ||
15 | void FAST_FUNC add_static_lease(struct static_lease **st_lease_pp, | ||
16 | uint8_t *mac, | ||
17 | uint32_t nip) | ||
18 | { | ||
19 | struct static_lease *st_lease; | ||
20 | |||
21 | /* Find the tail of the list */ | ||
22 | while ((st_lease = *st_lease_pp) != NULL) { | ||
23 | st_lease_pp = &st_lease->next; | ||
24 | } | ||
25 | |||
26 | /* Add new node */ | ||
27 | *st_lease_pp = st_lease = xzalloc(sizeof(*st_lease)); | ||
28 | memcpy(st_lease->mac, mac, 6); | ||
29 | st_lease->nip = nip; | ||
30 | /*st_lease->next = NULL;*/ | ||
31 | } | ||
32 | |||
33 | /* Find static lease IP by mac */ | ||
34 | uint32_t FAST_FUNC get_static_nip_by_mac(struct static_lease *st_lease, void *mac) | ||
35 | { | ||
36 | while (st_lease) { | ||
37 | if (memcmp(st_lease->mac, mac, 6) == 0) | ||
38 | return st_lease->nip; | ||
39 | st_lease = st_lease->next; | ||
40 | } | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | /* Check to see if an IP is reserved as a static IP */ | ||
46 | int FAST_FUNC is_nip_reserved(struct static_lease *st_lease, uint32_t nip) | ||
47 | { | ||
48 | while (st_lease) { | ||
49 | if (st_lease->nip == nip) | ||
50 | return 1; | ||
51 | st_lease = st_lease->next; | ||
52 | } | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | ||
58 | /* Print out static leases just to check what's going on */ | ||
59 | /* Takes the address of the pointer to the static_leases linked list */ | ||
60 | void FAST_FUNC log_static_leases(struct static_lease **st_lease_pp) | ||
61 | { | ||
62 | struct static_lease *cur; | ||
63 | |||
64 | if (dhcp_verbose < 2) | ||
65 | return; | ||
66 | |||
67 | cur = *st_lease_pp; | ||
68 | while (cur) { | ||
69 | bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", | ||
70 | cur->mac[0], cur->mac[1], cur->mac[2], | ||
71 | cur->mac[3], cur->mac[4], cur->mac[5], | ||
72 | cur->nip | ||
73 | ); | ||
74 | cur = cur->next; | ||
75 | } | ||
76 | } | ||
77 | #endif | ||
diff --git a/networking/wget.c b/networking/wget.c index c886dd391..460b4b833 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -62,9 +62,10 @@ | |||
62 | //config: a helper program to talk over HTTPS. | 62 | //config: a helper program to talk over HTTPS. |
63 | //config: | 63 | //config: |
64 | //config: OpenSSL has a simple SSL client for debug purposes. | 64 | //config: OpenSSL has a simple SSL client for debug purposes. |
65 | //config: If you select "openssl" helper, wget will effectively call | 65 | //config: If you select "openssl" helper, wget will effectively run: |
66 | //config: "openssl s_client -quiet -connect IP:443 2>/dev/null" | 66 | //config: "openssl s_client -quiet -connect hostname:443 |
67 | //config: and pipe its data through it. | 67 | //config: -servername hostname 2>/dev/null" and pipe its data |
68 | //config: through it. -servername is not used if hostname is numeric. | ||
68 | //config: Note inconvenient API: host resolution is done twice, | 69 | //config: Note inconvenient API: host resolution is done twice, |
69 | //config: and there is no guarantee openssl's idea of IPv6 address | 70 | //config: and there is no guarantee openssl's idea of IPv6 address |
70 | //config: format is the same as ours. | 71 | //config: format is the same as ours. |
@@ -99,7 +100,7 @@ | |||
99 | 100 | ||
100 | //usage:#define wget_trivial_usage | 101 | //usage:#define wget_trivial_usage |
101 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( | 102 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( |
102 | //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" | 103 | //usage: "[-c|--continue] [--spider] [-q|--quiet] [-O|--output-document FILE]\n" |
103 | //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" | 104 | //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" |
104 | /* Since we ignore these opts, we don't show them in --help */ | 105 | /* Since we ignore these opts, we don't show them in --help */ |
105 | /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ | 106 | /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ |
@@ -107,21 +108,23 @@ | |||
107 | //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | 108 | //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." |
108 | //usage: ) | 109 | //usage: ) |
109 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( | 110 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( |
110 | //usage: "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" | 111 | //usage: "[-cq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" |
111 | //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | 112 | //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." |
112 | //usage: ) | 113 | //usage: ) |
113 | //usage:#define wget_full_usage "\n\n" | 114 | //usage:#define wget_full_usage "\n\n" |
114 | //usage: "Retrieve files via HTTP or FTP\n" | 115 | //usage: "Retrieve files via HTTP or FTP\n" |
115 | //usage: "\n -s Spider mode - only check file existence" | 116 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( |
116 | //usage: "\n -c Continue retrieval of aborted transfer" | 117 | //usage: "\n --spider Spider mode - only check file existence" |
117 | //usage: "\n -q Quiet" | 118 | //usage: ) |
118 | //usage: "\n -P DIR Save to DIR (default .)" | 119 | //usage: "\n -c Continue retrieval of aborted transfer" |
120 | //usage: "\n -q Quiet" | ||
121 | //usage: "\n -P DIR Save to DIR (default .)" | ||
119 | //usage: IF_FEATURE_WGET_TIMEOUT( | 122 | //usage: IF_FEATURE_WGET_TIMEOUT( |
120 | //usage: "\n -T SEC Network read timeout is SEC seconds" | 123 | //usage: "\n -T SEC Network read timeout is SEC seconds" |
121 | //usage: ) | 124 | //usage: ) |
122 | //usage: "\n -O FILE Save to FILE ('-' for stdout)" | 125 | //usage: "\n -O FILE Save to FILE ('-' for stdout)" |
123 | //usage: "\n -U STR Use STR for User-Agent header" | 126 | //usage: "\n -U STR Use STR for User-Agent header" |
124 | //usage: "\n -Y Use proxy ('on' or 'off')" | 127 | //usage: "\n -Y on/off Use proxy" |
125 | 128 | ||
126 | #include "libbb.h" | 129 | #include "libbb.h" |
127 | 130 | ||
@@ -228,17 +231,17 @@ struct globals { | |||
228 | /* Must match option string! */ | 231 | /* Must match option string! */ |
229 | enum { | 232 | enum { |
230 | WGET_OPT_CONTINUE = (1 << 0), | 233 | WGET_OPT_CONTINUE = (1 << 0), |
231 | WGET_OPT_SPIDER = (1 << 1), | 234 | WGET_OPT_QUIET = (1 << 1), |
232 | WGET_OPT_QUIET = (1 << 2), | 235 | WGET_OPT_OUTNAME = (1 << 2), |
233 | WGET_OPT_OUTNAME = (1 << 3), | 236 | WGET_OPT_PREFIX = (1 << 3), |
234 | WGET_OPT_PREFIX = (1 << 4), | 237 | WGET_OPT_PROXY = (1 << 4), |
235 | WGET_OPT_PROXY = (1 << 5), | 238 | WGET_OPT_USER_AGENT = (1 << 5), |
236 | WGET_OPT_USER_AGENT = (1 << 6), | 239 | WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 6), |
237 | WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 7), | 240 | WGET_OPT_RETRIES = (1 << 7), |
238 | WGET_OPT_RETRIES = (1 << 8), | 241 | WGET_OPT_nsomething = (1 << 8), |
239 | WGET_OPT_PASSIVE = (1 << 9), | 242 | WGET_OPT_HEADER = (1 << 9) * ENABLE_FEATURE_WGET_LONG_OPTIONS, |
240 | WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, | 243 | WGET_OPT_POST_DATA = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, |
241 | WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, | 244 | WGET_OPT_SPIDER = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, |
242 | }; | 245 | }; |
243 | 246 | ||
244 | enum { | 247 | enum { |
@@ -349,6 +352,30 @@ static void set_alarm(void) | |||
349 | # define clear_alarm() ((void)0) | 352 | # define clear_alarm() ((void)0) |
350 | #endif | 353 | #endif |
351 | 354 | ||
355 | #if ENABLE_FEATURE_WGET_OPENSSL | ||
356 | /* | ||
357 | * is_ip_address() attempts to verify whether or not a string | ||
358 | * contains an IPv4 or IPv6 address (vs. an FQDN). The result | ||
359 | * of inet_pton() can be used to determine this. | ||
360 | * | ||
361 | * TODO add proper error checking when inet_pton() returns -1 | ||
362 | * (some form of system error has occurred, and errno is set) | ||
363 | */ | ||
364 | static int is_ip_address(const char *string) | ||
365 | { | ||
366 | struct sockaddr_in sa; | ||
367 | |||
368 | int result = inet_pton(AF_INET, string, &(sa.sin_addr)); | ||
369 | # if ENABLE_FEATURE_IPV6 | ||
370 | if (result == 0) { | ||
371 | struct sockaddr_in6 sa6; | ||
372 | result = inet_pton(AF_INET6, string, &(sa6.sin6_addr)); | ||
373 | } | ||
374 | # endif | ||
375 | return (result == 1); | ||
376 | } | ||
377 | #endif | ||
378 | |||
352 | static FILE *open_socket(len_and_sockaddr *lsa) | 379 | static FILE *open_socket(len_and_sockaddr *lsa) |
353 | { | 380 | { |
354 | int fd; | 381 | int fd; |
@@ -635,6 +662,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ | |||
635 | static int spawn_https_helper_openssl(const char *host, unsigned port) | 662 | static int spawn_https_helper_openssl(const char *host, unsigned port) |
636 | { | 663 | { |
637 | char *allocated = NULL; | 664 | char *allocated = NULL; |
665 | char *servername; | ||
638 | int sp[2]; | 666 | int sp[2]; |
639 | int pid; | 667 | int pid; |
640 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) | 668 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) |
@@ -645,12 +673,14 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
645 | 673 | ||
646 | if (!strchr(host, ':')) | 674 | if (!strchr(host, ':')) |
647 | host = allocated = xasprintf("%s:%u", host, port); | 675 | host = allocated = xasprintf("%s:%u", host, port); |
676 | servername = xstrdup(host); | ||
677 | strrchr(servername, ':')[0] = '\0'; | ||
648 | 678 | ||
649 | fflush_all(); | 679 | fflush_all(); |
650 | pid = xvfork(); | 680 | pid = xvfork(); |
651 | if (pid == 0) { | 681 | if (pid == 0) { |
652 | /* Child */ | 682 | /* Child */ |
653 | char *argv[6]; | 683 | char *argv[8]; |
654 | 684 | ||
655 | close(sp[0]); | 685 | close(sp[0]); |
656 | xmove_fd(sp[1], 0); | 686 | xmove_fd(sp[1], 0); |
@@ -662,12 +692,22 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
662 | */ | 692 | */ |
663 | xmove_fd(2, 3); | 693 | xmove_fd(2, 3); |
664 | xopen("/dev/null", O_RDWR); | 694 | xopen("/dev/null", O_RDWR); |
695 | memset(&argv, 0, sizeof(argv)); | ||
665 | argv[0] = (char*)"openssl"; | 696 | argv[0] = (char*)"openssl"; |
666 | argv[1] = (char*)"s_client"; | 697 | argv[1] = (char*)"s_client"; |
667 | argv[2] = (char*)"-quiet"; | 698 | argv[2] = (char*)"-quiet"; |
668 | argv[3] = (char*)"-connect"; | 699 | argv[3] = (char*)"-connect"; |
669 | argv[4] = (char*)host; | 700 | argv[4] = (char*)host; |
670 | argv[5] = NULL; | 701 | /* |
702 | * Per RFC 6066 Section 3, the only permitted values in the | ||
703 | * TLS server_name (SNI) field are FQDNs (DNS hostnames). | ||
704 | * IPv4 and IPv6 addresses, port numbers are not allowed. | ||
705 | */ | ||
706 | if (!is_ip_address(servername)) { | ||
707 | argv[5] = (char*)"-servername"; | ||
708 | argv[6] = (char*)servername; | ||
709 | } | ||
710 | |||
671 | BB_EXECVP(argv[0], argv); | 711 | BB_EXECVP(argv[0], argv); |
672 | xmove_fd(3, 2); | 712 | xmove_fd(3, 2); |
673 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 713 | # if ENABLE_FEATURE_WGET_SSL_HELPER |
@@ -680,6 +720,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
680 | } | 720 | } |
681 | 721 | ||
682 | /* Parent */ | 722 | /* Parent */ |
723 | free(servername); | ||
683 | free(allocated); | 724 | free(allocated); |
684 | close(sp[1]); | 725 | close(sp[1]); |
685 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 726 | # if ENABLE_FEATURE_WGET_SSL_HELPER |
@@ -1058,6 +1099,12 @@ static void download_one_url(const char *url) | |||
1058 | } | 1099 | } |
1059 | 1100 | ||
1060 | fflush(sfp); | 1101 | fflush(sfp); |
1102 | /* If we use SSL helper, keeping our end of the socket open for writing | ||
1103 | * makes our end (i.e. the same fd!) readable (EAGAIN instead of EOF) | ||
1104 | * even after child closes its copy of the fd. | ||
1105 | * This helps: | ||
1106 | */ | ||
1107 | shutdown(fileno(sfp), SHUT_WR); | ||
1061 | 1108 | ||
1062 | /* | 1109 | /* |
1063 | * Retrieve HTTP response line and check for "200" status code. | 1110 | * Retrieve HTTP response line and check for "200" status code. |
@@ -1077,7 +1124,21 @@ static void download_one_url(const char *url) | |||
1077 | while (gethdr(sfp) != NULL) | 1124 | while (gethdr(sfp) != NULL) |
1078 | /* eat all remaining headers */; | 1125 | /* eat all remaining headers */; |
1079 | goto read_response; | 1126 | goto read_response; |
1127 | |||
1128 | /* Success responses */ | ||
1080 | case 200: | 1129 | case 200: |
1130 | /* fall through */ | ||
1131 | case 201: /* 201 Created */ | ||
1132 | /* "The request has been fulfilled and resulted in a new resource being created" */ | ||
1133 | /* Standard wget is reported to treat this as success */ | ||
1134 | /* fall through */ | ||
1135 | case 202: /* 202 Accepted */ | ||
1136 | /* "The request has been accepted for processing, but the processing has not been completed" */ | ||
1137 | /* Treat as success: fall through */ | ||
1138 | case 203: /* 203 Non-Authoritative Information */ | ||
1139 | /* "Use of this response code is not required and is only appropriate when the response would otherwise be 200 (OK)" */ | ||
1140 | /* fall through */ | ||
1141 | case 204: /* 204 No Content */ | ||
1081 | /* | 1142 | /* |
1082 | Response 204 doesn't say "null file", it says "metadata | 1143 | Response 204 doesn't say "null file", it says "metadata |
1083 | has changed but data didn't": | 1144 | has changed but data didn't": |
@@ -1102,7 +1163,6 @@ is always terminated by the first empty line after the header fields." | |||
1102 | However, in real world it was observed that some web servers | 1163 | However, in real world it was observed that some web servers |
1103 | (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero. | 1164 | (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero. |
1104 | */ | 1165 | */ |
1105 | case 204: | ||
1106 | if (G.beg_range != 0) { | 1166 | if (G.beg_range != 0) { |
1107 | /* "Range:..." was not honored by the server. | 1167 | /* "Range:..." was not honored by the server. |
1108 | * Restart download from the beginning. | 1168 | * Restart download from the beginning. |
@@ -1110,11 +1170,14 @@ However, in real world it was observed that some web servers | |||
1110 | reset_beg_range_to_zero(); | 1170 | reset_beg_range_to_zero(); |
1111 | } | 1171 | } |
1112 | break; | 1172 | break; |
1173 | /* 205 Reset Content ?? what to do on this ?? */ | ||
1174 | |||
1113 | case 300: /* redirection */ | 1175 | case 300: /* redirection */ |
1114 | case 301: | 1176 | case 301: |
1115 | case 302: | 1177 | case 302: |
1116 | case 303: | 1178 | case 303: |
1117 | break; | 1179 | break; |
1180 | |||
1118 | case 206: /* Partial Content */ | 1181 | case 206: /* Partial Content */ |
1119 | if (G.beg_range != 0) | 1182 | if (G.beg_range != 0) |
1120 | /* "Range:..." worked. Good. */ | 1183 | /* "Range:..." worked. Good. */ |
@@ -1231,8 +1294,6 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
1231 | static const char wget_longopts[] ALIGN1 = | 1294 | static const char wget_longopts[] ALIGN1 = |
1232 | /* name, has_arg, val */ | 1295 | /* name, has_arg, val */ |
1233 | "continue\0" No_argument "c" | 1296 | "continue\0" No_argument "c" |
1234 | //FIXME: -s isn't --spider, it's --save-headers! | ||
1235 | "spider\0" No_argument "s" | ||
1236 | "quiet\0" No_argument "q" | 1297 | "quiet\0" No_argument "q" |
1237 | "output-document\0" Required_argument "O" | 1298 | "output-document\0" Required_argument "O" |
1238 | "directory-prefix\0" Required_argument "P" | 1299 | "directory-prefix\0" Required_argument "P" |
@@ -1244,6 +1305,7 @@ IF_FEATURE_WGET_TIMEOUT( | |||
1244 | IF_DESKTOP( "tries\0" Required_argument "t") | 1305 | IF_DESKTOP( "tries\0" Required_argument "t") |
1245 | "header\0" Required_argument "\xff" | 1306 | "header\0" Required_argument "\xff" |
1246 | "post-data\0" Required_argument "\xfe" | 1307 | "post-data\0" Required_argument "\xfe" |
1308 | "spider\0" No_argument "\xfd" | ||
1247 | /* Ignored (we always use PASV): */ | 1309 | /* Ignored (we always use PASV): */ |
1248 | IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") | 1310 | IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") |
1249 | /* Ignored (we don't do ssl) */ | 1311 | /* Ignored (we don't do ssl) */ |
@@ -1275,7 +1337,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") | |||
1275 | #endif | 1337 | #endif |
1276 | opt_complementary = "-1" /* at least one URL */ | 1338 | opt_complementary = "-1" /* at least one URL */ |
1277 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ | 1339 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ |
1278 | getopt32(argv, "csqO:P:Y:U:T:+" | 1340 | getopt32(argv, "cqO:P:Y:U:T:+" |
1279 | /*ignored:*/ "t:" | 1341 | /*ignored:*/ "t:" |
1280 | /*ignored:*/ "n::" | 1342 | /*ignored:*/ "n::" |
1281 | /* wget has exactly four -n<letter> opts, all of which we can ignore: | 1343 | /* wget has exactly four -n<letter> opts, all of which we can ignore: |
@@ -1294,6 +1356,14 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") | |||
1294 | IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) | 1356 | IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) |
1295 | IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) | 1357 | IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) |
1296 | ); | 1358 | ); |
1359 | #if 0 /* option bits debug */ | ||
1360 | if (option_mask32 & WGET_OPT_RETRIES) bb_error_msg("-t NUM"); | ||
1361 | if (option_mask32 & WGET_OPT_nsomething) bb_error_msg("-nsomething"); | ||
1362 | if (option_mask32 & WGET_OPT_HEADER) bb_error_msg("--header"); | ||
1363 | if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data"); | ||
1364 | if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider"); | ||
1365 | exit(0); | ||
1366 | #endif | ||
1297 | argv += optind; | 1367 | argv += optind; |
1298 | 1368 | ||
1299 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS | 1369 | #if ENABLE_FEATURE_WGET_LONG_OPTIONS |