aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-07-25 10:41:42 +0100
committerRon Yorston <rmy@pobox.com>2018-07-25 10:41:42 +0100
commit59873514f17cefd6ba3997dad5779f75433fd4e6 (patch)
tree1c9d0a3450ed95f0b820285b9f9fc217c902e652 /networking
parent779fd5745ac11bf752f5f4b977a274a39c192f90 (diff)
parent81de30de05beebabfa72f2a01ec4f33e9a1923e3 (diff)
downloadbusybox-w32-59873514f17cefd6ba3997dad5779f75433fd4e6.tar.gz
busybox-w32-59873514f17cefd6ba3997dad5779f75433fd4e6.tar.bz2
busybox-w32-59873514f17cefd6ba3997dad5779f75433fd4e6.zip
Merge branch 'busybox'
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.src2
-rw-r--r--networking/nc_bloaty.c2
-rw-r--r--networking/nslookup.c2
-rw-r--r--networking/ntpd.c17
-rw-r--r--networking/tls.c20
-rw-r--r--networking/udhcp/Config.src2
-rw-r--r--networking/udhcp/common.c118
-rw-r--r--networking/udhcp/common.h68
-rw-r--r--networking/udhcp/d6_common.h3
-rw-r--r--networking/udhcp/d6_dhcpc.c117
-rw-r--r--networking/udhcp/dhcpc.c15
-rw-r--r--networking/udhcp/dhcpd.c9
-rw-r--r--networking/udhcp/packet.c7
-rw-r--r--networking/wget.c10
14 files changed, 263 insertions, 129 deletions
diff --git a/networking/Config.src b/networking/Config.src
index 492c60da4..2ce5287de 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -1,6 +1,6 @@
1# 1#
2# For a description of the syntax of this configuration file, 2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt. 3# see docs/Kconfig-language.txt.
4# 4#
5 5
6menu "Networking Utilities" 6menu "Networking Utilities"
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c
index 64098648a..42c84de45 100644
--- a/networking/nc_bloaty.c
+++ b/networking/nc_bloaty.c
@@ -791,7 +791,7 @@ int nc_main(int argc UNUSED_PARAM, char **argv)
791 "np:s:uvw:+"/* -w N */ IF_NC_SERVER("lk") 791 "np:s:uvw:+"/* -w N */ IF_NC_SERVER("lk")
792 IF_NC_EXTRA("i:o:z") 792 IF_NC_EXTRA("i:o:z")
793 "\0" 793 "\0"
794 "?2:vv:ll", /* max 2 params; -v and -l are counters */ 794 "?2:vv"IF_NC_SERVER(":ll"), /* max 2 params; -v and -l are counters */
795 &str_p, &str_s, &o_wait 795 &str_p, &str_s, &o_wait
796 IF_NC_EXTRA(, &str_i, &str_o) 796 IF_NC_EXTRA(, &str_i, &str_o)
797 , &o_verbose IF_NC_SERVER(, &cnt_l) 797 , &o_verbose IF_NC_SERVER(, &cnt_l)
diff --git a/networking/nslookup.c b/networking/nslookup.c
index fd241a5ca..3a614b0c6 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -712,11 +712,11 @@ static void add_query(int type, const char *dname)
712static char *make_ptr(const char *addrstr) 712static char *make_ptr(const char *addrstr)
713{ 713{
714 unsigned char addr[16]; 714 unsigned char addr[16];
715 int i;
716 715
717#if ENABLE_FEATURE_IPV6 716#if ENABLE_FEATURE_IPV6
718 if (inet_pton(AF_INET6, addrstr, addr)) { 717 if (inet_pton(AF_INET6, addrstr, addr)) {
719 if (memcmp(addr, v4_mapped, 12) != 0) { 718 if (memcmp(addr, v4_mapped, 12) != 0) {
719 int i;
720 char resbuf[80]; 720 char resbuf[80];
721 char *ptr = resbuf; 721 char *ptr = resbuf;
722 for (i = 0; i < 16; i++) { 722 for (i = 0; i < 16; i++) {
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 6cd497090..7b800369e 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -93,10 +93,10 @@
93 93
94#include "libbb.h" 94#include "libbb.h"
95#include <math.h> 95#include <math.h>
96#include <netinet/ip.h> /* For IPTOS_LOWDELAY definition */ 96#include <netinet/ip.h> /* For IPTOS_DSCP_AF21 definition */
97#include <sys/timex.h> 97#include <sys/timex.h>
98#ifndef IPTOS_LOWDELAY 98#ifndef IPTOS_DSCP_AF21
99# define IPTOS_LOWDELAY 0x10 99# define IPTOS_DSCP_AF21 0x48
100#endif 100#endif
101 101
102 102
@@ -149,6 +149,7 @@
149 */ 149 */
150 150
151#define INITIAL_SAMPLES 4 /* how many samples do we want for init */ 151#define INITIAL_SAMPLES 4 /* how many samples do we want for init */
152#define MIN_FREQHOLD 10 /* adjust offset, but not freq in this many first adjustments */
152#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */ 153#define BAD_DELAY_GROWTH 4 /* drop packet if its delay grew by more than this */
153 154
154#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */ 155#define RETRY_INTERVAL 32 /* on send/recv error, retry in N secs (need to be power of 2) */
@@ -910,7 +911,7 @@ send_query_to_peer(peer_t *p)
910#if ENABLE_FEATURE_IPV6 911#if ENABLE_FEATURE_IPV6
911 if (family == AF_INET) 912 if (family == AF_INET)
912#endif 913#endif
913 setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); 914 setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_DSCP_AF21);
914 free(local_lsa); 915 free(local_lsa);
915 } 916 }
916 917
@@ -1753,7 +1754,7 @@ update_local_clock(peer_t *p)
1753//15:19:39.114 update from:<IP> offset:+0.327022 delay:0.158384 jitter:0.108538 clock drift:-1.393ppm tc:4 1754//15:19:39.114 update from:<IP> offset:+0.327022 delay:0.158384 jitter:0.108538 clock drift:-1.393ppm tc:4
1754//15:20:12.715 update from:<IP> offset:+0.275596 delay:0.158297 jitter:0.097292 clock drift:-1.393ppm tc:4 1755//15:20:12.715 update from:<IP> offset:+0.275596 delay:0.158297 jitter:0.097292 clock drift:-1.393ppm tc:4
1755//15:20:45.111 update from:<IP> offset:+0.225715 delay:0.158271 jitter:0.087841 clock drift:-1.393ppm tc:4 1756//15:20:45.111 update from:<IP> offset:+0.225715 delay:0.158271 jitter:0.087841 clock drift:-1.393ppm tc:4
1756// If allwed to continue, it would start increasing tmx.freq now. 1757// If allowed to continue, it would start increasing tmx.freq now.
1757// Instead, it was ^Ced, and started anew: 1758// Instead, it was ^Ced, and started anew:
1758//15:21:15.043 no valid datapoints, no peer selected 1759//15:21:15.043 no valid datapoints, no peer selected
1759//15:21:17.408 update from:<IP> offset:+0.175910 delay:0.158314 jitter:0.076683 clock drift:-1.393ppm tc:4 1760//15:21:17.408 update from:<IP> offset:+0.175910 delay:0.158314 jitter:0.076683 clock drift:-1.393ppm tc:4
@@ -1776,9 +1777,9 @@ update_local_clock(peer_t *p)
1776//15:31:53.473 update from:<IP> offset:+0.000007 delay:0.158142 jitter:0.010922 clock drift:+9.343ppm tc:6 1777//15:31:53.473 update from:<IP> offset:+0.000007 delay:0.158142 jitter:0.010922 clock drift:+9.343ppm tc:6
1777//15:32:58.902 update from:<IP> offset:-0.000728 delay:0.158222 jitter:0.009454 clock drift:+9.298ppm tc:6 1778//15:32:58.902 update from:<IP> offset:-0.000728 delay:0.158222 jitter:0.009454 clock drift:+9.298ppm tc:6
1778 /* 1779 /*
1779 * This expression would choose 15 in the above example. 1780 * This expression would choose MIN_FREQHOLD + 7 in the above example.
1780 */ 1781 */
1781 G.FREQHOLD_cnt = 8 + ((unsigned)(abs(tmx.offset)) >> 16); 1782 G.FREQHOLD_cnt = MIN_FREQHOLD + ((unsigned)(abs(tmx.offset)) >> 16);
1782 } 1783 }
1783 G.FREQHOLD_cnt--; 1784 G.FREQHOLD_cnt--;
1784 tmx.status |= STA_FREQHOLD; 1785 tmx.status |= STA_FREQHOLD;
@@ -2320,7 +2321,7 @@ static NOINLINE void ntp_init(char **argv)
2320 xfunc_die(); 2321 xfunc_die();
2321 } 2322 }
2322 socket_want_pktinfo(G_listen_fd); 2323 socket_want_pktinfo(G_listen_fd);
2323 setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); 2324 setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_DSCP_AF21);
2324 } 2325 }
2325#endif 2326#endif
2326 /* I hesitate to set -20 prio. -15 should be high enough for timekeeping */ 2327 /* I hesitate to set -20 prio. -15 should be high enough for timekeeping */
diff --git a/networking/tls.c b/networking/tls.c
index ec5a56d57..fce1d0ea6 100644
--- a/networking/tls.c
+++ b/networking/tls.c
@@ -1088,6 +1088,8 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
1088 * We need Certificate.tbsCertificate.subjectPublicKeyInfo.publicKey 1088 * We need Certificate.tbsCertificate.subjectPublicKeyInfo.publicKey
1089 */ 1089 */
1090 uint8_t *end = der + len; 1090 uint8_t *end = der + len;
1091 uint8_t tag_class, pc, tag_number;
1092 int version_present;
1091 1093
1092 /* enter "Certificate" item: [der, end) will be only Cert */ 1094 /* enter "Certificate" item: [der, end) will be only Cert */
1093 der = enter_der_item(der, &end); 1095 der = enter_der_item(der, &end);
@@ -1095,8 +1097,24 @@ static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len)
1095 /* enter "tbsCertificate" item: [der, end) will be only tbsCert */ 1097 /* enter "tbsCertificate" item: [der, end) will be only tbsCert */
1096 der = enter_der_item(der, &end); 1098 der = enter_der_item(der, &end);
1097 1099
1100 /*
1101 * Skip version field only if it is present. For a v1 certificate, the
1102 * version field won't be present since v1 is the default value for the
1103 * version field and fields with default values should be omitted (see
1104 * RFC 5280 sections 4.1 and 4.1.2.1). If the version field is present
1105 * it will have a tag class of 2 (context-specific), bit 6 as 1
1106 * (constructed), and a tag number of 0 (see ITU-T X.690 sections 8.1.2
1107 * and 8.14).
1108 */
1109 tag_class = der[0] >> 6; /* bits 8-7 */
1110 pc = (der[0] & 32) >> 5; /* bit 6 */
1111 tag_number = der[0] & 31; /* bits 5-1 */
1112 version_present = tag_class == 2 && pc == 1 && tag_number == 0;
1113 if (version_present) {
1114 der = skip_der_item(der, end); /* version */
1115 }
1116
1098 /* skip up to subjectPublicKeyInfo */ 1117 /* skip up to subjectPublicKeyInfo */
1099 der = skip_der_item(der, end); /* version */
1100 der = skip_der_item(der, end); /* serialNumber */ 1118 der = skip_der_item(der, end); /* serialNumber */
1101 der = skip_der_item(der, end); /* signatureAlgo */ 1119 der = skip_der_item(der, end); /* signatureAlgo */
1102 der = skip_der_item(der, end); /* issuer */ 1120 der = skip_der_item(der, end); /* issuer */
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index 50bff2e8c..e5958804b 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -1,6 +1,6 @@
1# 1#
2# For a description of the syntax of this configuration file, 2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt. 3# see docs/Kconfig-language.txt.
4# 4#
5 5
6config UDHCPD 6config UDHCPD
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index fbf9c6878..e5fd74f91 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -65,6 +65,7 @@ const struct dhcp_optflag dhcp_optflags[] = {
65#endif 65#endif
66 { OPTION_STRING , 0xd1 }, /* DHCP_PXE_CONF_FILE */ 66 { OPTION_STRING , 0xd1 }, /* DHCP_PXE_CONF_FILE */
67 { OPTION_STRING , 0xd2 }, /* DHCP_PXE_PATH_PREFIX */ 67 { OPTION_STRING , 0xd2 }, /* DHCP_PXE_PATH_PREFIX */
68 { OPTION_U32 , 0xd3 }, /* DHCP_REBOOT_TIME */
68 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ 69 { OPTION_6RD , 0xd4 }, /* DHCP_6RD */
69 { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ 70 { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */
70 { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ 71 { OPTION_STRING , 0xfc }, /* DHCP_WPAD */
@@ -92,50 +93,51 @@ const struct dhcp_optflag dhcp_optflags[] = {
92 */ 93 */
93/* Must match dhcp_optflags[] order */ 94/* Must match dhcp_optflags[] order */
94const char dhcp_option_strings[] ALIGN1 = 95const char dhcp_option_strings[] ALIGN1 =
95 "subnet" "\0" /* DHCP_SUBNET */ 96 "subnet" "\0" /* DHCP_SUBNET */
96 "timezone" "\0" /* DHCP_TIME_OFFSET */ 97 "timezone" "\0" /* DHCP_TIME_OFFSET */
97 "router" "\0" /* DHCP_ROUTER */ 98 "router" "\0" /* DHCP_ROUTER */
98// "timesrv" "\0" /* DHCP_TIME_SERVER */ 99// "timesrv" "\0" /* DHCP_TIME_SERVER */
99// "namesrv" "\0" /* DHCP_NAME_SERVER */ 100// "namesrv" "\0" /* DHCP_NAME_SERVER */
100 "dns" "\0" /* DHCP_DNS_SERVER */ 101 "dns" "\0" /* DHCP_DNS_SERVER */
101// "logsrv" "\0" /* DHCP_LOG_SERVER */ 102// "logsrv" "\0" /* DHCP_LOG_SERVER */
102// "cookiesrv" "\0" /* DHCP_COOKIE_SERVER */ 103// "cookiesrv" "\0" /* DHCP_COOKIE_SERVER */
103 "lprsrv" "\0" /* DHCP_LPR_SERVER */ 104 "lprsrv" "\0" /* DHCP_LPR_SERVER */
104 "hostname" "\0" /* DHCP_HOST_NAME */ 105 "hostname" "\0" /* DHCP_HOST_NAME */
105 "bootsize" "\0" /* DHCP_BOOT_SIZE */ 106 "bootsize" "\0" /* DHCP_BOOT_SIZE */
106 "domain" "\0" /* DHCP_DOMAIN_NAME */ 107 "domain" "\0" /* DHCP_DOMAIN_NAME */
107 "swapsrv" "\0" /* DHCP_SWAP_SERVER */ 108 "swapsrv" "\0" /* DHCP_SWAP_SERVER */
108 "rootpath" "\0" /* DHCP_ROOT_PATH */ 109 "rootpath" "\0" /* DHCP_ROOT_PATH */
109 "ipttl" "\0" /* DHCP_IP_TTL */ 110 "ipttl" "\0" /* DHCP_IP_TTL */
110 "mtu" "\0" /* DHCP_MTU */ 111 "mtu" "\0" /* DHCP_MTU */
111 "broadcast" "\0" /* DHCP_BROADCAST */ 112 "broadcast" "\0" /* DHCP_BROADCAST */
112 "routes" "\0" /* DHCP_ROUTES */ 113 "routes" "\0" /* DHCP_ROUTES */
113 "nisdomain" "\0" /* DHCP_NIS_DOMAIN */ 114 "nisdomain" "\0" /* DHCP_NIS_DOMAIN */
114 "nissrv" "\0" /* DHCP_NIS_SERVER */ 115 "nissrv" "\0" /* DHCP_NIS_SERVER */
115 "ntpsrv" "\0" /* DHCP_NTP_SERVER */ 116 "ntpsrv" "\0" /* DHCP_NTP_SERVER */
116 "wins" "\0" /* DHCP_WINS_SERVER */ 117 "wins" "\0" /* DHCP_WINS_SERVER */
117 "lease" "\0" /* DHCP_LEASE_TIME */ 118 "lease" "\0" /* DHCP_LEASE_TIME */
118 "serverid" "\0" /* DHCP_SERVER_ID */ 119 "serverid" "\0" /* DHCP_SERVER_ID */
119 "message" "\0" /* DHCP_ERR_MESSAGE */ 120 "message" "\0" /* DHCP_ERR_MESSAGE */
120 "tftp" "\0" /* DHCP_TFTP_SERVER_NAME */ 121 "tftp" "\0" /* DHCP_TFTP_SERVER_NAME*/
121 "bootfile" "\0" /* DHCP_BOOT_FILE */ 122 "bootfile" "\0" /* DHCP_BOOT_FILE */
122// "userclass" "\0" /* DHCP_USER_CLASS */ 123// "userclass" "\0" /* DHCP_USER_CLASS */
123#if ENABLE_FEATURE_UDHCP_RFC3397 124#if ENABLE_FEATURE_UDHCP_RFC3397
124 "search" "\0" /* DHCP_DOMAIN_SEARCH */ 125 "search" "\0" /* DHCP_DOMAIN_SEARCH */
125// doesn't work in udhcpd.conf since OPTION_SIP_SERVERS 126// doesn't work in udhcpd.conf since OPTION_SIP_SERVERS
126// is not handled yet by "string->option" conversion code: 127// is not handled yet by "string->option" conversion code:
127 "sipsrv" "\0" /* DHCP_SIP_SERVERS */ 128 "sipsrv" "\0" /* DHCP_SIP_SERVERS */
128#endif 129#endif
129 "staticroutes" "\0"/* DHCP_STATIC_ROUTES */ 130 "staticroutes" "\0" /* DHCP_STATIC_ROUTES */
130#if ENABLE_FEATURE_UDHCP_8021Q 131#if ENABLE_FEATURE_UDHCP_8021Q
131 "vlanid" "\0" /* DHCP_VLAN_ID */ 132 "vlanid" "\0" /* DHCP_VLAN_ID */
132 "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ 133 "vlanpriority" "\0" /* DHCP_VLAN_PRIORITY */
133#endif 134#endif
134 "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */ 135 "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */
135 "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX */ 136 "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX */
136 "ip6rd" "\0" /* DHCP_6RD */ 137 "reboottime" "\0" /* DHCP_REBOOT_TIME */
137 "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ 138 "ip6rd" "\0" /* DHCP_6RD */
138 "wpad" "\0" /* DHCP_WPAD */ 139 "msstaticroutes" "\0" /* DHCP_MS_STATIC_ROUTES*/
140 "wpad" "\0" /* DHCP_WPAD */
139 ; 141 ;
140#endif 142#endif
141 143
@@ -379,12 +381,18 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg)
379 * and to parse udhcpd.conf's "opt OPTNAME OPTVAL" directives. 381 * and to parse udhcpd.conf's "opt OPTNAME OPTVAL" directives.
380 */ 382 */
381/* helper: add an option to the opt_list */ 383/* helper: add an option to the opt_list */
384#if !ENABLE_UDHCPC6
385#define attach_option(opt_list, optflag, buffer, length, dhcpv6) \
386 attach_option(opt_list, optflag, buffer, length)
387#endif
382static NOINLINE void attach_option( 388static NOINLINE void attach_option(
383 struct option_set **opt_list, 389 struct option_set **opt_list,
384 const struct dhcp_optflag *optflag, 390 const struct dhcp_optflag *optflag,
385 char *buffer, 391 char *buffer,
386 int length) 392 int length,
393 bool dhcpv6)
387{ 394{
395 IF_NOT_UDHCPC6(bool dhcpv6 = 0;)
388 struct option_set *existing; 396 struct option_set *existing;
389 char *allocated = NULL; 397 char *allocated = NULL;
390 398
@@ -410,10 +418,21 @@ static NOINLINE void attach_option(
410 /* make a new option */ 418 /* make a new option */
411 log2("attaching option %02x to list", optflag->code); 419 log2("attaching option %02x to list", optflag->code);
412 new = xmalloc(sizeof(*new)); 420 new = xmalloc(sizeof(*new));
413 new->data = xmalloc(length + OPT_DATA); 421 if (!dhcpv6) {
414 new->data[OPT_CODE] = optflag->code; 422 new->data = xmalloc(length + OPT_DATA);
415 new->data[OPT_LEN] = length; 423 new->data[OPT_CODE] = optflag->code;
416 memcpy(new->data + OPT_DATA, (allocated ? allocated : buffer), length); 424 new->data[OPT_LEN] = length;
425 memcpy(new->data + OPT_DATA, (allocated ? allocated : buffer),
426 length);
427 } else {
428 new->data = xmalloc(length + D6_OPT_DATA);
429 new->data[D6_OPT_CODE] = optflag->code >> 8;
430 new->data[D6_OPT_CODE + 1] = optflag->code & 0xff;
431 new->data[D6_OPT_LEN] = length >> 8;
432 new->data[D6_OPT_LEN + 1] = length & 0xff;
433 memcpy(new->data + D6_OPT_DATA, (allocated ? allocated : buffer),
434 length);
435 }
417 436
418 curr = opt_list; 437 curr = opt_list;
419 while (*curr && (*curr)->data[OPT_CODE] < optflag->code) 438 while (*curr && (*curr)->data[OPT_CODE] < optflag->code)
@@ -450,7 +469,9 @@ static NOINLINE void attach_option(
450 free(allocated); 469 free(allocated);
451} 470}
452 471
453int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg, const struct dhcp_optflag *optflags, const char *option_strings) 472int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg,
473 const struct dhcp_optflag *optflags, const char *option_strings,
474 bool dhcpv6)
454{ 475{
455 struct option_set **opt_list = arg; 476 struct option_set **opt_list = arg;
456 char *opt; 477 char *opt;
@@ -489,9 +510,10 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg, const struct dh
489 int length; 510 int length;
490 char *val; 511 char *val;
491 512
492 if (optflag->flags == OPTION_BIN) 513 if (optflag->flags == OPTION_BIN) {
493 val = trim(strtok(NULL, "")); /* do not split "'q w e'" */ 514 val = strtok(NULL, ""); /* do not split "'q w e'" */
494 else 515 trim(val);
516 } else
495 val = strtok(NULL, ", \t"); 517 val = strtok(NULL, ", \t");
496 if (!val) 518 if (!val)
497 break; 519 break;
@@ -601,7 +623,7 @@ case_OPTION_STRING:
601 } 623 }
602 624
603 if (retval) 625 if (retval)
604 attach_option(opt_list, optflag, opt, length); 626 attach_option(opt_list, optflag, opt, length, dhcpv6);
605 } while (retval && (optflag->flags & OPTION_LIST)); 627 } while (retval && (optflag->flags & OPTION_LIST));
606 628
607 return retval; 629 return retval;
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 13059f106..7ad603d33 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -122,9 +122,9 @@ enum {
122//#define DHCP_LOG_SERVER 0x07 /* port 704 UDP log (not syslog) 122//#define DHCP_LOG_SERVER 0x07 /* port 704 UDP log (not syslog)
123//#define DHCP_COOKIE_SERVER 0x08 /* "quote of the day" server */ 123//#define DHCP_COOKIE_SERVER 0x08 /* "quote of the day" server */
124//#define DHCP_LPR_SERVER 0x09 124//#define DHCP_LPR_SERVER 0x09
125#define DHCP_HOST_NAME 0x0c /* either client informs server or server gives name to client */ 125#define DHCP_HOST_NAME 0x0c /* 12: either client informs server or server gives name to client */
126//#define DHCP_BOOT_SIZE 0x0d 126//#define DHCP_BOOT_SIZE 0x0d
127//#define DHCP_DOMAIN_NAME 0x0f /* server gives domain suffix */ 127//#define DHCP_DOMAIN_NAME 0x0f /* 15: server gives domain suffix */
128//#define DHCP_SWAP_SERVER 0x10 128//#define DHCP_SWAP_SERVER 0x10
129//#define DHCP_ROOT_PATH 0x11 129//#define DHCP_ROOT_PATH 0x11
130//#define DHCP_IP_TTL 0x17 130//#define DHCP_IP_TTL 0x17
@@ -135,35 +135,40 @@ enum {
135//#define DHCP_NIS_SERVER 0x29 135//#define DHCP_NIS_SERVER 0x29
136//#define DHCP_NTP_SERVER 0x2a 136//#define DHCP_NTP_SERVER 0x2a
137//#define DHCP_WINS_SERVER 0x2c 137//#define DHCP_WINS_SERVER 0x2c
138#define DHCP_REQUESTED_IP 0x32 /* sent by client if specific IP is wanted */ 138#define DHCP_REQUESTED_IP 0x32 /* 50: sent by client if specific IP is wanted */
139#define DHCP_LEASE_TIME 0x33 139#define DHCP_LEASE_TIME 0x33 /* 51: */
140#define DHCP_OPTION_OVERLOAD 0x34 140#define DHCP_OPTION_OVERLOAD 0x34 /* 52: */
141#define DHCP_MESSAGE_TYPE 0x35 141#define DHCP_MESSAGE_TYPE 0x35 /* 53: */
142#define DHCP_SERVER_ID 0x36 /* by default server's IP */ 142#define DHCP_SERVER_ID 0x36 /* 54: server's IP */
143#define DHCP_PARAM_REQ 0x37 /* list of options client wants */ 143#define DHCP_PARAM_REQ 0x37 /* 55: list of options client wants */
144//#define DHCP_ERR_MESSAGE 0x38 /* error message when sending NAK etc */ 144//#define DHCP_ERR_MESSAGE 0x38 /* 56: error message when sending NAK etc */
145#define DHCP_MAX_SIZE 0x39 145#define DHCP_MAX_SIZE 0x39 /* 57: */
146#define DHCP_VENDOR 0x3c /* client's vendor (a string) */ 146#define DHCP_VENDOR 0x3c /* 60: client's vendor (a string) */
147#define DHCP_CLIENT_ID 0x3d /* by default client's MAC addr, but may be arbitrarily long */ 147#define DHCP_CLIENT_ID 0x3d /* 61: by default client's MAC addr, but may be arbitrarily long */
148//#define DHCP_TFTP_SERVER_NAME 0x42 /* same as 'sname' field */ 148//#define DHCP_TFTP_SERVER_NAME 0x42 /* 66: same as 'sname' field */
149//#define DHCP_BOOT_FILE 0x43 /* same as 'file' field */ 149//#define DHCP_BOOT_FILE 0x43 /* 67: same as 'file' field */
150//#define DHCP_USER_CLASS 0x4d /* RFC 3004. set of LASCII strings. "I am a printer" etc */ 150//#define DHCP_USER_CLASS 0x4d /* 77: RFC 3004. set of LASCII strings. "I am a printer" etc */
151#define DHCP_FQDN 0x51 /* client asks to update DNS to map its FQDN to its new IP */ 151#define DHCP_FQDN 0x51 /* 81: client asks to update DNS to map its FQDN to its new IP */
152//#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ 152//#define DHCP_DOMAIN_SEARCH 0x77 /* 119: RFC 3397. set of ASCIZ string, DNS-style compressed */
153//#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ 153//#define DHCP_SIP_SERVERS 0x78 /* 120: RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */
154//#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ 154//#define DHCP_STATIC_ROUTES 0x79 /* 121: RFC 3442. (mask,ip,router) tuples */
155//#define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ 155//#define DHCP_VLAN_ID 0x84 /* 132: 802.1P VLAN ID */
156//#define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ 156//#define DHCP_VLAN_PRIORITY 0x85 /* 133: 802.1Q VLAN priority */
157//#define DHCP_PXE_CONF_FILE 0xd1 /* RFC 5071 Configuration File */ 157//#define DHCP_PXE_CONF_FILE 0xd1 /* 209: RFC 5071 Configuration File */
158//#define DHCP_PXE_PATH_PREFIX 0xd2 /* RFC 5071 Configuration File */ 158//#define DHCP_PXE_PATH_PREFIX 0xd2 /* 210: RFC 5071 Configuration File */
159//#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ 159//#define DHCP_REBOOT_TIME 0xd3 /* 211: RFC 5071 Reboot time */
160//#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ 160//#define DHCP_MS_STATIC_ROUTES 0xf9 /* 249: Microsoft's pre-RFC 3442 code for 0x79? */
161#define DHCP_END 0xff 161//#define DHCP_WPAD 0xfc /* 252: MSIE's Web Proxy Autodiscovery Protocol */
162#define DHCP_END 0xff /* 255: */
162 163
163/* Offsets in option byte sequence */ 164/* Offsets in option byte sequence */
164#define OPT_CODE 0 165#define OPT_CODE 0
165#define OPT_LEN 1 166#define OPT_LEN 1
166#define OPT_DATA 2 167#define OPT_DATA 2
168/* Offsets in option byte sequence for DHCPv6 */
169#define D6_OPT_CODE 0
170#define D6_OPT_LEN 2
171#define D6_OPT_DATA 4
167/* Bits in "overload" option */ 172/* Bits in "overload" option */
168#define OPTION_FIELD 0 173#define OPTION_FIELD 0
169#define FILE_FIELD 1 174#define FILE_FIELD 1
@@ -290,10 +295,15 @@ void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC;
290/* 2nd param is "uint32_t*" */ 295/* 2nd param is "uint32_t*" */
291int FAST_FUNC udhcp_str2nip(const char *str, void *arg); 296int FAST_FUNC udhcp_str2nip(const char *str, void *arg);
292/* 2nd param is "struct option_set**" */ 297/* 2nd param is "struct option_set**" */
298#if !ENABLE_UDHCPC6
299#define udhcp_str2optset(str, arg, optflags, option_strings, dhcpv6) \
300 udhcp_str2optset(str, arg, optflags, option_strings)
301#endif
293int FAST_FUNC udhcp_str2optset(const char *str, 302int FAST_FUNC udhcp_str2optset(const char *str,
294 void *arg, 303 void *arg,
295 const struct dhcp_optflag *optflags, 304 const struct dhcp_optflag *optflags,
296 const char *option_strings); 305 const char *option_strings,
306 bool dhcpv6);
297 307
298#if ENABLE_UDHCPC || ENABLE_UDHCPD 308#if ENABLE_UDHCPC || ENABLE_UDHCPD
299void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; 309void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC;
@@ -308,9 +318,7 @@ int udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
308 318
309int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, 319int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
310 uint32_t source_nip, int source_port, 320 uint32_t source_nip, int source_port,
311 uint32_t dest_nip, int dest_port, 321 uint32_t dest_nip, int dest_port) FAST_FUNC;
312 int send_flags
313) FAST_FUNC;
314 322
315void udhcp_sp_setup(void) FAST_FUNC; 323void udhcp_sp_setup(void) FAST_FUNC;
316void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; 324void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC;
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h
index e9c0397ae..d0506e2bb 100644
--- a/networking/udhcp/d6_common.h
+++ b/networking/udhcp/d6_common.h
@@ -128,6 +128,9 @@ struct d6_option {
128#define D6_OPT_TZ_POSIX 41 128#define D6_OPT_TZ_POSIX 41
129#define D6_OPT_TZ_NAME 42 129#define D6_OPT_TZ_NAME 42
130 130
131#define D6_OPT_BOOT_URL 59
132#define D6_OPT_BOOT_PARAM 60
133
131/*** Other shared functions ***/ 134/*** Other shared functions ***/
132 135
133struct client6_data_t { 136struct client6_data_t {
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c
index 85d9da724..ed2255ef3 100644
--- a/networking/udhcp/d6_dhcpc.c
+++ b/networking/udhcp/d6_dhcpc.c
@@ -38,6 +38,14 @@
38//config: help 38//config: help
39//config: You can request POSIX timezone with "-O tz" and timezone name 39//config: You can request POSIX timezone with "-O tz" and timezone name
40//config: with "-O timezone". 40//config: with "-O timezone".
41//config:
42//config:config FEATURE_UDHCPC6_RFC5970
43//config: bool "Support RFC 5970 (Network Boot)"
44//config: default y
45//config: depends on UDHCPC6
46//config: help
47//config: You can request bootfile-url with "-O bootfile_url" and
48//config: bootfile-params with "-O bootfile_params".
41 49
42//applet:IF_UDHCPC6(APPLET(udhcpc6, BB_DIR_USR_BIN, BB_SUID_DROP)) 50//applet:IF_UDHCPC6(APPLET(udhcpc6, BB_DIR_USR_BIN, BB_SUID_DROP))
43 51
@@ -71,6 +79,12 @@ static const struct dhcp_optflag d6_optflags[] = {
71 { OPTION_STRING, D6_OPT_TZ_POSIX }, 79 { OPTION_STRING, D6_OPT_TZ_POSIX },
72 { OPTION_STRING, D6_OPT_TZ_NAME }, 80 { OPTION_STRING, D6_OPT_TZ_NAME },
73#endif 81#endif
82#if ENABLE_FEATURE_UDHCPC6_RFC5970
83 { OPTION_STRING, D6_OPT_BOOT_URL },
84 { OPTION_STRING, D6_OPT_BOOT_PARAM },
85#endif
86 { OPTION_STRING, 0xd1 }, /* DHCP_PXE_CONF_FILE */
87 { OPTION_STRING, 0xd2 }, /* DHCP_PXE_PATH_PREFIX */
74 { 0, 0 } 88 { 0, 0 }
75}; 89};
76/* Must match d6_optflags[] order */ 90/* Must match d6_optflags[] order */
@@ -86,6 +100,12 @@ static const char d6_option_strings[] ALIGN1 =
86 "tz" "\0" /* D6_OPT_TZ_POSIX */ 100 "tz" "\0" /* D6_OPT_TZ_POSIX */
87 "timezone" "\0" /* D6_OPT_TZ_NAME */ 101 "timezone" "\0" /* D6_OPT_TZ_NAME */
88#endif 102#endif
103#if ENABLE_FEATURE_UDHCPC6_RFC5970
104 "bootfile_url" "\0" /* D6_OPT_BOOT_URL */
105 "bootfile_param" "\0" /* D6_OPT_BOOT_PARAM */
106#endif
107 "pxeconffile" "\0" /* DHCP_PXE_CONF_FILE */
108 "pxepathprefix" "\0" /* DHCP_PXE_PATH_PREFIX */
89 "\0"; 109 "\0";
90 110
91#if ENABLE_LONG_OPTS 111#if ENABLE_LONG_OPTS
@@ -195,8 +215,37 @@ static char** new_env(void)
195 return &client6_data.env_ptr[client6_data.env_idx++]; 215 return &client6_data.env_ptr[client6_data.env_idx++];
196} 216}
197 217
218static char *string_option_to_env(const uint8_t *option,
219 const uint8_t *option_end)
220{
221 const char *ptr, *name = NULL;
222 unsigned val_len;
223 int i;
224
225 ptr = d6_option_strings;
226 i = 0;
227 while (*ptr) {
228 if (d6_optflags[i].code == option[1]) {
229 name = ptr;
230 goto found;
231 }
232 ptr += strlen(ptr) + 1;
233 i++;
234 }
235 bb_error_msg("can't find option name for 0x%x, skipping", option[1]);
236 return NULL;
237
238 found:
239 val_len = (option[2] << 8) | option[3];
240 if (val_len + &option[D6_OPT_DATA] > option_end) {
241 bb_error_msg("option data exceeds option length");
242 return NULL;
243 }
244 return xasprintf("%s=%.*s", name, val_len, (char*)option + 4);
245}
246
198/* put all the parameters into the environment */ 247/* put all the parameters into the environment */
199static void option_to_env(uint8_t *option, uint8_t *option_end) 248static void option_to_env(const uint8_t *option, const uint8_t *option_end)
200{ 249{
201#if ENABLE_FEATURE_UDHCPC6_RFC3646 250#if ENABLE_FEATURE_UDHCPC6_RFC3646
202 int addrs, option_offset; 251 int addrs, option_offset;
@@ -239,6 +288,10 @@ static void option_to_env(uint8_t *option, uint8_t *option_end)
239 * | valid-lifetime | 288 * | valid-lifetime |
240 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 289 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
241 */ 290 */
291 /* Make sure payload contains an address */
292 if (option[3] < 24)
293 break;
294
242 sprint_nip6(ipv6str, option + 4); 295 sprint_nip6(ipv6str, option + 4);
243 *new_env() = xasprintf("ipv6=%s", ipv6str); 296 *new_env() = xasprintf("ipv6=%s", ipv6str);
244 297
@@ -354,13 +407,23 @@ static void option_to_env(uint8_t *option, uint8_t *option_end)
354 *new_env() = xasprintf("tz_name=%.*s", (int)option[3], (char*)option + 4); 407 *new_env() = xasprintf("tz_name=%.*s", (int)option[3], (char*)option + 4);
355 break; 408 break;
356#endif 409#endif
410 case D6_OPT_BOOT_URL:
411 case D6_OPT_BOOT_PARAM:
412 case 0xd1: /* DHCP_PXE_CONF_FILE */
413 case 0xd2: /* DHCP_PXE_PATH_PREFIX */
414 {
415 char *tmp = string_option_to_env(option, option_end);
416 if (tmp)
417 *new_env() = tmp;
418 break;
419 }
357 } 420 }
358 len_m4 -= 4 + option[3]; 421 len_m4 -= 4 + option[3];
359 option += 4 + option[3]; 422 option += 4 + option[3];
360 } 423 }
361} 424}
362 425
363static char **fill_envp(struct d6_packet *packet) 426static char **fill_envp(const uint8_t *option, const uint8_t *option_end)
364{ 427{
365 char **envp, **curr; 428 char **envp, **curr;
366 429
@@ -369,8 +432,8 @@ static char **fill_envp(struct d6_packet *packet)
369 432
370 *new_env() = xasprintf("interface=%s", client_config.interface); 433 *new_env() = xasprintf("interface=%s", client_config.interface);
371 434
372 if (packet) 435 if (option)
373 option_to_env(packet->d6_options, packet->d6_options + sizeof(packet->d6_options)); 436 option_to_env(option, option_end);
374 437
375 envp = curr = client6_data.env_ptr; 438 envp = curr = client6_data.env_ptr;
376 while (*curr) 439 while (*curr)
@@ -380,12 +443,13 @@ static char **fill_envp(struct d6_packet *packet)
380} 443}
381 444
382/* Call a script with a par file and env vars */ 445/* Call a script with a par file and env vars */
383static void d6_run_script(struct d6_packet *packet, const char *name) 446static void d6_run_script(const uint8_t *option, const uint8_t *option_end,
447 const char *name)
384{ 448{
385 char **envp, **curr; 449 char **envp, **curr;
386 char *argv[3]; 450 char *argv[3];
387 451
388 envp = fill_envp(packet); 452 envp = fill_envp(option, option_end);
389 453
390 /* call script */ 454 /* call script */
391 log1("executing %s %s", client_config.script, name); 455 log1("executing %s %s", client_config.script, name);
@@ -401,6 +465,11 @@ static void d6_run_script(struct d6_packet *packet, const char *name)
401 free(envp); 465 free(envp);
402} 466}
403 467
468/* Call a script with a par file and no env var */
469static void d6_run_script_no_option(const char *name)
470{
471 d6_run_script(NULL, NULL, name);
472}
404 473
405/*** Sending/receiving packets ***/ 474/*** Sending/receiving packets ***/
406 475
@@ -426,8 +495,10 @@ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid
426 495
427static uint8_t *add_d6_client_options(uint8_t *ptr) 496static uint8_t *add_d6_client_options(uint8_t *ptr)
428{ 497{
498 struct option_set *curr;
429 uint8_t *start = ptr; 499 uint8_t *start = ptr;
430 unsigned option; 500 unsigned option;
501 uint16_t len;
431 502
432 ptr += 4; 503 ptr += 4;
433 for (option = 1; option < 256; option++) { 504 for (option = 1; option < 256; option++) {
@@ -450,7 +521,12 @@ static uint8_t *add_d6_client_options(uint8_t *ptr)
450 ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); 521 ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req));
451#endif 522#endif
452 /* Add -x options if any */ 523 /* Add -x options if any */
453 //... 524 curr = client_config.options;
525 while (curr) {
526 len = (curr->data[D6_OPT_LEN] << 8) | curr->data[D6_OPT_LEN + 1];
527 ptr = mempcpy(ptr, curr->data, D6_OPT_DATA + len);
528 curr = curr->next;
529 }
454 530
455 return ptr; 531 return ptr;
456} 532}
@@ -727,15 +803,13 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st
727 opt_ptr = add_d6_client_options(opt_ptr); 803 opt_ptr = add_d6_client_options(opt_ptr);
728 804
729 bb_error_msg("sending %s", "renew"); 805 bb_error_msg("sending %s", "renew");
730 if (server_ipv6) { 806 if (server_ipv6)
731 return d6_send_kernel_packet( 807 return d6_send_kernel_packet(
732 &packet, (opt_ptr - (uint8_t*) &packet), 808 &packet, (opt_ptr - (uint8_t*) &packet),
733 our_cur_ipv6, CLIENT_PORT6, 809 our_cur_ipv6, CLIENT_PORT6,
734 server_ipv6, SERVER_PORT6, 810 server_ipv6, SERVER_PORT6,
735 client_config.ifindex 811 client_config.ifindex
736 /* TODO? send_flags: MSG_DONTROUTE (see IPv4 code for reason why) */
737 ); 812 );
738 }
739 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); 813 return d6_mcast_from_client_config_ifindex(&packet, opt_ptr);
740} 814}
741 815
@@ -969,7 +1043,7 @@ static void perform_renew(void)
969 state = RENEW_REQUESTED; 1043 state = RENEW_REQUESTED;
970 break; 1044 break;
971 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */ 1045 case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
972 d6_run_script(NULL, "deconfig"); 1046 d6_run_script_no_option("deconfig");
973 case REQUESTING: 1047 case REQUESTING:
974 case RELEASED: 1048 case RELEASED:
975 change_listen_mode(LISTEN_RAW); 1049 change_listen_mode(LISTEN_RAW);
@@ -998,7 +1072,7 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou
998 * Users requested to be notified in all cases, even if not in one 1072 * Users requested to be notified in all cases, even if not in one
999 * of the states above. 1073 * of the states above.
1000 */ 1074 */
1001 d6_run_script(NULL, "deconfig"); 1075 d6_run_script_no_option("deconfig");
1002 change_listen_mode(LISTEN_NONE); 1076 change_listen_mode(LISTEN_NONE);
1003 state = RELEASED; 1077 state = RELEASED;
1004} 1078}
@@ -1157,7 +1231,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1157 } 1231 }
1158 while (list_x) { 1232 while (list_x) {
1159 char *optstr = xstrdup(llist_pop(&list_x)); 1233 char *optstr = xstrdup(llist_pop(&list_x));
1160 udhcp_str2optset(optstr, &client_config.options, d6_optflags, d6_option_strings); 1234 udhcp_str2optset(optstr, &client_config.options,
1235 d6_optflags, d6_option_strings,
1236 /*dhcpv6:*/ 1
1237 );
1161 free(optstr); 1238 free(optstr);
1162 } 1239 }
1163 1240
@@ -1204,7 +1281,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1204 udhcp_sp_setup(); 1281 udhcp_sp_setup();
1205 1282
1206 state = INIT_SELECTING; 1283 state = INIT_SELECTING;
1207 d6_run_script(NULL, "deconfig"); 1284 d6_run_script_no_option("deconfig");
1208 change_listen_mode(LISTEN_RAW); 1285 change_listen_mode(LISTEN_RAW);
1209 packet_num = 0; 1286 packet_num = 0;
1210 timeout = 0; 1287 timeout = 0;
@@ -1285,7 +1362,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1285 continue; 1362 continue;
1286 } 1363 }
1287 leasefail: 1364 leasefail:
1288 d6_run_script(NULL, "leasefail"); 1365 d6_run_script_no_option("leasefail");
1289#if BB_MMU /* -b is not supported on NOMMU */ 1366#if BB_MMU /* -b is not supported on NOMMU */
1290 if (opt & OPT_b) { /* background if no lease */ 1367 if (opt & OPT_b) { /* background if no lease */
1291 bb_error_msg("no lease, forking to background"); 1368 bb_error_msg("no lease, forking to background");
@@ -1359,7 +1436,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1359 } 1436 }
1360 /* Timed out, enter init state */ 1437 /* Timed out, enter init state */
1361 bb_error_msg("lease lost, entering init state"); 1438 bb_error_msg("lease lost, entering init state");
1362 d6_run_script(NULL, "deconfig"); 1439 d6_run_script_no_option("deconfig");
1363 state = INIT_SELECTING; 1440 state = INIT_SELECTING;
1364 client_config.first_secs = 0; /* make secs field count from 0 */ 1441 client_config.first_secs = 0; /* make secs field count from 0 */
1365 /*timeout = 0; - already is */ 1442 /*timeout = 0; - already is */
@@ -1466,9 +1543,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1466 if (option && (option->data[0] | option->data[1]) != 0) { 1543 if (option && (option->data[0] | option->data[1]) != 0) {
1467 /* return to init state */ 1544 /* return to init state */
1468 bb_error_msg("received DHCP NAK (%u)", option->data[4]); 1545 bb_error_msg("received DHCP NAK (%u)", option->data[4]);
1469 d6_run_script(&packet, "nak"); 1546 d6_run_script(packet.d6_options,
1547 packet_end, "nak");
1470 if (state != REQUESTING) 1548 if (state != REQUESTING)
1471 d6_run_script(NULL, "deconfig"); 1549 d6_run_script_no_option("deconfig");
1472 change_listen_mode(LISTEN_RAW); 1550 change_listen_mode(LISTEN_RAW);
1473 sleep(3); /* avoid excessive network traffic */ 1551 sleep(3); /* avoid excessive network traffic */
1474 state = INIT_SELECTING; 1552 state = INIT_SELECTING;
@@ -1665,7 +1743,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv)
1665 if (timeout < 0x10) 1743 if (timeout < 0x10)
1666 timeout = 0x10; 1744 timeout = 0x10;
1667 /* enter bound state */ 1745 /* enter bound state */
1668 d6_run_script(&packet, state == REQUESTING ? "bound" : "renew"); 1746 d6_run_script(packet.d6_options, packet_end,
1747 (state == REQUESTING ? "bound" : "renew"));
1669 1748
1670 state = BOUND; 1749 state = BOUND;
1671 change_listen_mode(LISTEN_NONE); 1750 change_listen_mode(LISTEN_NONE);
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index bd9e8fdc2..c2805a009 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -693,16 +693,10 @@ static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint
693 693
694static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server) 694static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t server)
695{ 695{
696 if (server) { 696 if (server)
697 /* Without MSG_DONTROUTE, the packet was seen routed over
698 * _other interface_ if server ID is bogus (example: 1.1.1.1).
699 */
700 return udhcp_send_kernel_packet(packet, 697 return udhcp_send_kernel_packet(packet,
701 ciaddr, CLIENT_PORT, 698 ciaddr, CLIENT_PORT,
702 server, SERVER_PORT, 699 server, SERVER_PORT);
703 /*send_flags: "to hosts only on directly connected networks" */ MSG_DONTROUTE
704 );
705 }
706 return raw_bcast_from_client_config_ifindex(packet, ciaddr); 700 return raw_bcast_from_client_config_ifindex(packet, ciaddr);
707} 701}
708 702
@@ -1337,7 +1331,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv)
1337 } 1331 }
1338 while (list_x) { 1332 while (list_x) {
1339 char *optstr = xstrdup(llist_pop(&list_x)); 1333 char *optstr = xstrdup(llist_pop(&list_x));
1340 udhcp_str2optset(optstr, &client_config.options, dhcp_optflags, dhcp_option_strings); 1334 udhcp_str2optset(optstr, &client_config.options,
1335 dhcp_optflags, dhcp_option_strings,
1336 /*dhcpv6:*/ 0
1337 );
1341 free(optstr); 1338 free(optstr);
1342 } 1339 }
1343 1340
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 19f94a2d7..a8cd3f03b 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -362,7 +362,10 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg)
362} 362}
363 363
364static int FAST_FUNC read_optset(const char *line, void *arg) { 364static int FAST_FUNC read_optset(const char *line, void *arg) {
365 return udhcp_str2optset(line, arg, dhcp_optflags, dhcp_option_strings); 365 return udhcp_str2optset(line, arg,
366 dhcp_optflags, dhcp_option_strings,
367 /*dhcpv6:*/ 0
368 );
366} 369}
367 370
368struct config_keyword { 371struct config_keyword {
@@ -588,9 +591,7 @@ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt)
588 591
589 udhcp_send_kernel_packet(dhcp_pkt, 592 udhcp_send_kernel_packet(dhcp_pkt,
590 server_config.server_nip, SERVER_PORT, 593 server_config.server_nip, SERVER_PORT,
591 dhcp_pkt->gateway_nip, SERVER_PORT, 594 dhcp_pkt->gateway_nip, SERVER_PORT);
592 /*send_flags:*/ 0
593 );
594} 595}
595 596
596static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast) 597static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast)
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index fc2bb5416..ff16904f7 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -189,8 +189,7 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
189/* Let the kernel do all the work for packet generation */ 189/* Let the kernel do all the work for packet generation */
190int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, 190int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
191 uint32_t source_nip, int source_port, 191 uint32_t source_nip, int source_port,
192 uint32_t dest_nip, int dest_port, 192 uint32_t dest_nip, int dest_port)
193 int send_flags)
194{ 193{
195 struct sockaddr_in sa; 194 struct sockaddr_in sa;
196 unsigned padding; 195 unsigned padding;
@@ -227,8 +226,8 @@ int FAST_FUNC udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
227 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options); 226 padding = DHCP_OPTIONS_BUFSIZE - 1 - udhcp_end_option(dhcp_pkt->options);
228 if (padding > DHCP_SIZE - 300) 227 if (padding > DHCP_SIZE - 300)
229 padding = DHCP_SIZE - 300; 228 padding = DHCP_SIZE - 300;
230 result = send(fd, dhcp_pkt, DHCP_SIZE - padding, send_flags); 229 result = safe_write(fd, dhcp_pkt, DHCP_SIZE - padding);
231 msg = "send"; 230 msg = "write";
232 ret_close: 231 ret_close:
233 close(fd); 232 close(fd);
234 if (result < 0) { 233 if (result < 0) {
diff --git a/networking/wget.c b/networking/wget.c
index 85eae061b..bd2f4edcf 100644
--- a/networking/wget.c
+++ b/networking/wget.c
@@ -137,6 +137,7 @@
137//usage: "Retrieve files via HTTP or FTP\n" 137//usage: "Retrieve files via HTTP or FTP\n"
138//usage: IF_FEATURE_WGET_LONG_OPTIONS( 138//usage: IF_FEATURE_WGET_LONG_OPTIONS(
139//usage: "\n --spider Only check URL existence: $? is 0 if exists" 139//usage: "\n --spider Only check URL existence: $? is 0 if exists"
140///////: "\n --no-check-certificate Don't validate the server's certificate"
140//usage: ) 141//usage: )
141//usage: "\n -c Continue retrieval of aborted transfer" 142//usage: "\n -c Continue retrieval of aborted transfer"
142//usage: "\n -q Quiet" 143//usage: "\n -q Quiet"
@@ -271,6 +272,7 @@ enum {
271 WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, 272 WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
272 WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, 273 WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
273 WGET_OPT_SPIDER = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS, 274 WGET_OPT_SPIDER = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
275 WGET_OPT_NO_CHECK_CERT = (1 << 13) * ENABLE_FEATURE_WGET_LONG_OPTIONS,
274}; 276};
275 277
276enum { 278enum {
@@ -721,6 +723,9 @@ static void spawn_ssl_client(const char *host, int network_fd, int flags)
721 int pid; 723 int pid;
722 char *servername, *p; 724 char *servername, *p;
723 725
726 if (!(option_mask32 & WGET_OPT_NO_CHECK_CERT))
727 bb_error_msg("note: TLS certificate validation not implemented");
728
724 servername = xstrdup(host); 729 servername = xstrdup(host);
725 p = strrchr(servername, ':'); 730 p = strrchr(servername, ':');
726 if (p) *p = '\0'; 731 if (p) *p = '\0';
@@ -1362,6 +1367,7 @@ However, in real world it was observed that some web servers
1362 /* server.user remains untouched */ 1367 /* server.user remains untouched */
1363 free(server.allocated); 1368 free(server.allocated);
1364 server.allocated = NULL; 1369 server.allocated = NULL;
1370 server.protocol = target.protocol;
1365 server.host = target.host; 1371 server.host = target.host;
1366 /* strip_ipv6_scope_id(target.host); - no! */ 1372 /* strip_ipv6_scope_id(target.host); - no! */
1367 /* we assume remote never gives us IPv6 addr with scope id */ 1373 /* we assume remote never gives us IPv6 addr with scope id */
@@ -1434,10 +1440,9 @@ IF_DESKTOP( "tries\0" Required_argument "t")
1434 "header\0" Required_argument "\xff" 1440 "header\0" Required_argument "\xff"
1435 "post-data\0" Required_argument "\xfe" 1441 "post-data\0" Required_argument "\xfe"
1436 "spider\0" No_argument "\xfd" 1442 "spider\0" No_argument "\xfd"
1443 "no-check-certificate\0" No_argument "\xfc"
1437 /* Ignored (we always use PASV): */ 1444 /* Ignored (we always use PASV): */
1438IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") 1445IF_DESKTOP( "passive-ftp\0" No_argument "\xf0")
1439 /* Ignored (we don't do ssl) */
1440IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0")
1441 /* Ignored (we don't support caching) */ 1446 /* Ignored (we don't support caching) */
1442IF_DESKTOP( "no-cache\0" No_argument "\xf0") 1447IF_DESKTOP( "no-cache\0" No_argument "\xf0")
1443IF_DESKTOP( "no-verbose\0" No_argument "\xf0") 1448IF_DESKTOP( "no-verbose\0" No_argument "\xf0")
@@ -1497,6 +1502,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0")
1497 if (option_mask32 & WGET_OPT_HEADER) bb_error_msg("--header"); 1502 if (option_mask32 & WGET_OPT_HEADER) bb_error_msg("--header");
1498 if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data"); 1503 if (option_mask32 & WGET_OPT_POST_DATA) bb_error_msg("--post-data");
1499 if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider"); 1504 if (option_mask32 & WGET_OPT_SPIDER) bb_error_msg("--spider");
1505 if (option_mask32 & WGET_OPT_NO_CHECK_CERT) bb_error_msg("--no-check-certificate");
1500 exit(0); 1506 exit(0);
1501#endif 1507#endif
1502 argv += optind; 1508 argv += optind;