diff options
author | Ron Yorston <rmy@pobox.com> | 2017-07-18 15:58:52 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2017-07-18 15:58:52 +0100 |
commit | b680f05ad449505e3d914bebd4c8d83bf768c094 (patch) | |
tree | c08ded13d430b0e7e0104f2eb594fad190ce98a3 /networking | |
parent | 258200ff81d5a9da54dab35acf36213eff1e399b (diff) | |
parent | 513a2457b65894b10b9fd6aa8753fca59eced08c (diff) | |
download | busybox-w32-b680f05ad449505e3d914bebd4c8d83bf768c094.tar.gz busybox-w32-b680f05ad449505e3d914bebd4c8d83bf768c094.tar.bz2 busybox-w32-b680f05ad449505e3d914bebd4c8d83bf768c094.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'networking')
-rw-r--r-- | networking/inetd.c | 20 | ||||
-rw-r--r-- | networking/libiproute/iproute.c | 26 | ||||
-rw-r--r-- | networking/libiproute/iprule.c | 73 | ||||
-rw-r--r-- | networking/tls.c | 4 | ||||
-rw-r--r-- | networking/tls_aes.c | 4 | ||||
-rw-r--r-- | networking/tls_pstm.c | 2 | ||||
-rw-r--r-- | networking/tls_pstm_montgomery_reduce.c | 2 | ||||
-rw-r--r-- | networking/tls_pstm_mul_comba.c | 5 | ||||
-rw-r--r-- | networking/tls_pstm_sqr_comba.c | 8 | ||||
-rw-r--r-- | networking/udhcp/common.c | 27 | ||||
-rw-r--r-- | networking/udhcp/common.h | 19 | ||||
-rw-r--r-- | networking/udhcp/d6_common.h | 39 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 248 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 4 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 1 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 8 | ||||
-rw-r--r-- | networking/udhcp/packet.c | 2 |
17 files changed, 339 insertions, 153 deletions
diff --git a/networking/inetd.c b/networking/inetd.c index 01e659f13..3bf157b70 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -227,7 +227,8 @@ | |||
227 | 227 | ||
228 | #if ENABLE_FEATURE_INETD_RPC | 228 | #if ENABLE_FEATURE_INETD_RPC |
229 | # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) | 229 | # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) |
230 | # error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support" | 230 | # warning "You probably need to build uClibc with UCLIBC_HAS_RPC for NFS support" |
231 | /* not #error, since user may be using e.g. libtirpc instead */ | ||
231 | # endif | 232 | # endif |
232 | # include <rpc/rpc.h> | 233 | # include <rpc/rpc.h> |
233 | # include <rpc/pmap_clnt.h> | 234 | # include <rpc/pmap_clnt.h> |
@@ -1513,8 +1514,11 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1513 | } /* for (;;) */ | 1514 | } /* for (;;) */ |
1514 | } | 1515 | } |
1515 | 1516 | ||
1516 | #if !BB_MMU | 1517 | #if ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_ECHO \ |
1518 | || ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD | ||
1519 | # if !BB_MMU | ||
1517 | static const char *const cat_args[] = { "cat", NULL }; | 1520 | static const char *const cat_args[] = { "cat", NULL }; |
1521 | # endif | ||
1518 | #endif | 1522 | #endif |
1519 | 1523 | ||
1520 | /* | 1524 | /* |
@@ -1525,14 +1529,14 @@ static const char *const cat_args[] = { "cat", NULL }; | |||
1525 | /* ARGSUSED */ | 1529 | /* ARGSUSED */ |
1526 | static void FAST_FUNC echo_stream(int s, servtab_t *sep UNUSED_PARAM) | 1530 | static void FAST_FUNC echo_stream(int s, servtab_t *sep UNUSED_PARAM) |
1527 | { | 1531 | { |
1528 | #if BB_MMU | 1532 | # if BB_MMU |
1529 | while (1) { | 1533 | while (1) { |
1530 | ssize_t sz = safe_read(s, line, LINE_SIZE); | 1534 | ssize_t sz = safe_read(s, line, LINE_SIZE); |
1531 | if (sz <= 0) | 1535 | if (sz <= 0) |
1532 | break; | 1536 | break; |
1533 | xwrite(s, line, sz); | 1537 | xwrite(s, line, sz); |
1534 | } | 1538 | } |
1535 | #else | 1539 | # else |
1536 | /* We are after vfork here! */ | 1540 | /* We are after vfork here! */ |
1537 | /* move network socket to stdin/stdout */ | 1541 | /* move network socket to stdin/stdout */ |
1538 | xmove_fd(s, STDIN_FILENO); | 1542 | xmove_fd(s, STDIN_FILENO); |
@@ -1542,7 +1546,7 @@ static void FAST_FUNC echo_stream(int s, servtab_t *sep UNUSED_PARAM) | |||
1542 | xopen(bb_dev_null, O_WRONLY); | 1546 | xopen(bb_dev_null, O_WRONLY); |
1543 | BB_EXECVP("cat", (char**)cat_args); | 1547 | BB_EXECVP("cat", (char**)cat_args); |
1544 | /* on failure we return to main, which does exit(EXIT_FAILURE) */ | 1548 | /* on failure we return to main, which does exit(EXIT_FAILURE) */ |
1545 | #endif | 1549 | # endif |
1546 | } | 1550 | } |
1547 | static void FAST_FUNC echo_dg(int s, servtab_t *sep) | 1551 | static void FAST_FUNC echo_dg(int s, servtab_t *sep) |
1548 | { | 1552 | { |
@@ -1566,10 +1570,10 @@ static void FAST_FUNC echo_dg(int s, servtab_t *sep) | |||
1566 | /* ARGSUSED */ | 1570 | /* ARGSUSED */ |
1567 | static void FAST_FUNC discard_stream(int s, servtab_t *sep UNUSED_PARAM) | 1571 | static void FAST_FUNC discard_stream(int s, servtab_t *sep UNUSED_PARAM) |
1568 | { | 1572 | { |
1569 | #if BB_MMU | 1573 | # if BB_MMU |
1570 | while (safe_read(s, line, LINE_SIZE) > 0) | 1574 | while (safe_read(s, line, LINE_SIZE) > 0) |
1571 | continue; | 1575 | continue; |
1572 | #else | 1576 | # else |
1573 | /* We are after vfork here! */ | 1577 | /* We are after vfork here! */ |
1574 | /* move network socket to stdin */ | 1578 | /* move network socket to stdin */ |
1575 | xmove_fd(s, STDIN_FILENO); | 1579 | xmove_fd(s, STDIN_FILENO); |
@@ -1580,7 +1584,7 @@ static void FAST_FUNC discard_stream(int s, servtab_t *sep UNUSED_PARAM) | |||
1580 | xdup2(STDOUT_FILENO, STDERR_FILENO); | 1584 | xdup2(STDOUT_FILENO, STDERR_FILENO); |
1581 | BB_EXECVP("cat", (char**)cat_args); | 1585 | BB_EXECVP("cat", (char**)cat_args); |
1582 | /* on failure we return to main, which does exit(EXIT_FAILURE) */ | 1586 | /* on failure we return to main, which does exit(EXIT_FAILURE) */ |
1583 | #endif | 1587 | # endif |
1584 | } | 1588 | } |
1585 | /* ARGSUSED */ | 1589 | /* ARGSUSED */ |
1586 | static void FAST_FUNC discard_dg(int s, servtab_t *sep UNUSED_PARAM) | 1590 | static void FAST_FUNC discard_dg(int s, servtab_t *sep UNUSED_PARAM) |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index cc3443a92..6a41b8331 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -28,7 +28,7 @@ struct filter_t { | |||
28 | int flushe; | 28 | int flushe; |
29 | struct rtnl_handle *rth; | 29 | struct rtnl_handle *rth; |
30 | //int protocol, protocolmask; - write-only fields?! | 30 | //int protocol, protocolmask; - write-only fields?! |
31 | //int scope, scopemask; - unused | 31 | int scope, scopemask; |
32 | //int type; - read-only | 32 | //int type; - read-only |
33 | //int typemask; - unused | 33 | //int typemask; - unused |
34 | //int tos, tosmask; - unused | 34 | //int tos, tosmask; - unused |
@@ -120,6 +120,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | } | 122 | } |
123 | if ((G_filter.scope ^ r->rtm_scope) & G_filter.scopemask) | ||
124 | return 0; | ||
123 | if (G_filter.rdst.family | 125 | if (G_filter.rdst.family |
124 | && (r->rtm_family != G_filter.rdst.family || G_filter.rdst.bitlen > r->rtm_dst_len) | 126 | && (r->rtm_family != G_filter.rdst.family || G_filter.rdst.bitlen > r->rtm_dst_len) |
125 | ) { | 127 | ) { |
@@ -270,7 +272,11 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
270 | printf("table %s ", rtnl_rttable_n2a(tid)); | 272 | printf("table %s ", rtnl_rttable_n2a(tid)); |
271 | #endif | 273 | #endif |
272 | 274 | ||
273 | /* Todo: parse & show "proto kernel", "scope link" here */ | 275 | /* Todo: parse & show "proto kernel" here */ |
276 | if (!(r->rtm_flags & RTM_F_CLONED)) { | ||
277 | if ((r->rtm_scope != RT_SCOPE_UNIVERSE) && G_filter.scopemask != -1) | ||
278 | printf("scope %s ", rtnl_rtscope_n2a(r->rtm_scope)); | ||
279 | } | ||
274 | 280 | ||
275 | if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) { | 281 | if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) { |
276 | /* Do not use format_host(). It is our local addr | 282 | /* Do not use format_host(). It is our local addr |
@@ -761,10 +767,11 @@ static int iproute_list_or_flush(char **argv, int flush) | |||
761 | char *id = NULL; | 767 | char *id = NULL; |
762 | char *od = NULL; | 768 | char *od = NULL; |
763 | static const char keywords[] ALIGN1 = | 769 | static const char keywords[] ALIGN1 = |
770 | /* If you add stuff here, update iproute_full_usage */ | ||
764 | /* "ip route list/flush" parameters: */ | 771 | /* "ip route list/flush" parameters: */ |
765 | "protocol\0" "dev\0" "oif\0" "iif\0" | 772 | "protocol\0" "dev\0" "oif\0" "iif\0" |
766 | "via\0" "table\0" "cache\0" | 773 | "via\0" "table\0" "cache\0" |
767 | "from\0" "to\0" | 774 | "from\0" "to\0" "scope\0" |
768 | /* and possible further keywords */ | 775 | /* and possible further keywords */ |
769 | "all\0" | 776 | "all\0" |
770 | "root\0" | 777 | "root\0" |
@@ -775,7 +782,7 @@ static int iproute_list_or_flush(char **argv, int flush) | |||
775 | enum { | 782 | enum { |
776 | KW_proto, KW_dev, KW_oif, KW_iif, | 783 | KW_proto, KW_dev, KW_oif, KW_iif, |
777 | KW_via, KW_table, KW_cache, | 784 | KW_via, KW_table, KW_cache, |
778 | KW_from, KW_to, | 785 | KW_from, KW_to, KW_scope, |
779 | /* */ | 786 | /* */ |
780 | KW_all, | 787 | KW_all, |
781 | KW_root, | 788 | KW_root, |
@@ -834,6 +841,17 @@ static int iproute_list_or_flush(char **argv, int flush) | |||
834 | /* The command 'ip route flush cache' is used by OpenSWAN. | 841 | /* The command 'ip route flush cache' is used by OpenSWAN. |
835 | * Assuming it's a synonym for 'ip route flush table cache' */ | 842 | * Assuming it's a synonym for 'ip route flush table cache' */ |
836 | G_filter.tb = -1; | 843 | G_filter.tb = -1; |
844 | } else if (arg == KW_scope) { | ||
845 | uint32_t scope; | ||
846 | NEXT_ARG(); | ||
847 | G_filter.scopemask = -1; | ||
848 | if (rtnl_rtscope_a2n(&scope, *argv)) { | ||
849 | if (strcmp(*argv, "all") != 0) | ||
850 | invarg_1_to_2(*argv, "scope"); | ||
851 | scope = RT_SCOPE_NOWHERE; | ||
852 | G_filter.scopemask = 0; | ||
853 | } | ||
854 | G_filter.scope = scope; | ||
837 | } else if (arg == KW_from) { | 855 | } else if (arg == KW_from) { |
838 | NEXT_ARG(); | 856 | NEXT_ARG(); |
839 | parm = index_in_substrings(keywords, *argv); | 857 | parm = index_in_substrings(keywords, *argv); |
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index 8f3f86286..1bb5e759e 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c | |||
@@ -17,25 +17,32 @@ | |||
17 | #include <netinet/ip.h> | 17 | #include <netinet/ip.h> |
18 | #include <arpa/inet.h> | 18 | #include <arpa/inet.h> |
19 | 19 | ||
20 | /* from <linux/fib_rules.h>: */ | ||
21 | #define FRA_SUPPRESS_IFGROUP 13 | ||
22 | #define FRA_SUPPRESS_PREFIXLEN 14 | ||
23 | |||
20 | #include "ip_common.h" /* #include "libbb.h" is inside */ | 24 | #include "ip_common.h" /* #include "libbb.h" is inside */ |
21 | #include "rt_names.h" | 25 | #include "rt_names.h" |
22 | #include "utils.h" | 26 | #include "utils.h" |
23 | 27 | ||
24 | /* | 28 | /* If you add stuff here, update iprule_full_usage */ |
25 | static void usage(void) __attribute__((noreturn)); | 29 | static const char keywords[] ALIGN1 = |
26 | 30 | "from\0""to\0""preference\0""order\0""priority\0" | |
27 | static void usage(void) | 31 | "tos\0""fwmark\0""realms\0""table\0""lookup\0" |
28 | { | 32 | "suppress_prefixlength\0""suppress_ifgroup\0" |
29 | fprintf(stderr, "Usage: ip rule [ list | add | del ] SELECTOR ACTION\n"); | 33 | "dev\0""iif\0""nat\0""map-to\0""type\0""help\0" |
30 | fprintf(stderr, "SELECTOR := [ from PREFIX ] [ to PREFIX ] [ tos TOS ] [ fwmark FWMARK ]\n"); | 34 | ; |
31 | fprintf(stderr, " [ dev STRING ] [ pref NUMBER ]\n"); | 35 | #define keyword_preference (keywords + sizeof("from") + sizeof("to")) |
32 | fprintf(stderr, "ACTION := [ table TABLE_ID ] [ nat ADDRESS ]\n"); | 36 | #define keyword_fwmark (keyword_preference + sizeof("preference") + sizeof("order") + sizeof("priority") + sizeof("tos")) |
33 | fprintf(stderr, " [ prohibit | reject | unreachable ]\n"); | 37 | #define keyword_realms (keyword_fwmark + sizeof("fwmark")) |
34 | fprintf(stderr, " [ realms [SRCREALM/]DSTREALM ]\n"); | 38 | #define keyword_suppress_prefixlength (keyword_realms + sizeof("realms") + sizeof("table") + sizeof("lookup")) |
35 | fprintf(stderr, "TABLE_ID := [ local | main | default | NUMBER ]\n"); | 39 | #define keyword_suppress_ifgroup (keyword_suppress_prefixlength + sizeof("suppress_prefixlength")) |
36 | exit(-1); | 40 | enum { |
37 | } | 41 | ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, |
38 | */ | 42 | ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, |
43 | ARG_suppress_prefixlength, ARG_suppress_ifgroup, | ||
44 | ARG_dev, ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help, | ||
45 | }; | ||
39 | 46 | ||
40 | static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | 47 | static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, |
41 | struct nlmsghdr *n, void *arg UNUSED_PARAM) | 48 | struct nlmsghdr *n, void *arg UNUSED_PARAM) |
@@ -119,6 +126,17 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, | |||
119 | else if (r->rtm_table) | 126 | else if (r->rtm_table) |
120 | printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); | 127 | printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); |
121 | 128 | ||
129 | if (tb[FRA_SUPPRESS_PREFIXLEN]) { | ||
130 | int pl = *(uint32_t*)RTA_DATA(tb[FRA_SUPPRESS_PREFIXLEN]); | ||
131 | if (pl != -1) | ||
132 | printf("%s %d ", keyword_suppress_prefixlength, pl); | ||
133 | } | ||
134 | if (tb[FRA_SUPPRESS_IFGROUP]) { | ||
135 | int grp = *(uint32_t*)RTA_DATA(tb[FRA_SUPPRESS_IFGROUP]); | ||
136 | if (grp != -1) | ||
137 | printf("%s %d ", keyword_suppress_ifgroup, grp); | ||
138 | } | ||
139 | |||
122 | if (tb[RTA_FLOW]) { | 140 | if (tb[RTA_FLOW]) { |
123 | uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]); | 141 | uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]); |
124 | uint32_t from = to>>16; | 142 | uint32_t from = to>>16; |
@@ -174,15 +192,6 @@ static int iprule_list(char **argv) | |||
174 | /* Return value becomes exitcode. It's okay to not return at all */ | 192 | /* Return value becomes exitcode. It's okay to not return at all */ |
175 | static int iprule_modify(int cmd, char **argv) | 193 | static int iprule_modify(int cmd, char **argv) |
176 | { | 194 | { |
177 | static const char keywords[] ALIGN1 = | ||
178 | "from\0""to\0""preference\0""order\0""priority\0" | ||
179 | "tos\0""fwmark\0""realms\0""table\0""lookup\0""dev\0" | ||
180 | "iif\0""nat\0""map-to\0""type\0""help\0"; | ||
181 | enum { | ||
182 | ARG_from = 1, ARG_to, ARG_preference, ARG_order, ARG_priority, | ||
183 | ARG_tos, ARG_fwmark, ARG_realms, ARG_table, ARG_lookup, ARG_dev, | ||
184 | ARG_iif, ARG_nat, ARG_map_to, ARG_type, ARG_help | ||
185 | }; | ||
186 | bool table_ok = 0; | 195 | bool table_ok = 0; |
187 | struct rtnl_handle rth; | 196 | struct rtnl_handle rth; |
188 | struct { | 197 | struct { |
@@ -232,7 +241,7 @@ static int iprule_modify(int cmd, char **argv) | |||
232 | ) { | 241 | ) { |
233 | uint32_t pref; | 242 | uint32_t pref; |
234 | NEXT_ARG(); | 243 | NEXT_ARG(); |
235 | pref = get_u32(*argv, "preference"); | 244 | pref = get_u32(*argv, keyword_preference); |
236 | addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); | 245 | addattr32(&req.n, sizeof(req), RTA_PRIORITY, pref); |
237 | } else if (key == ARG_tos) { | 246 | } else if (key == ARG_tos) { |
238 | uint32_t tos; | 247 | uint32_t tos; |
@@ -243,13 +252,13 @@ static int iprule_modify(int cmd, char **argv) | |||
243 | } else if (key == ARG_fwmark) { | 252 | } else if (key == ARG_fwmark) { |
244 | uint32_t fwmark; | 253 | uint32_t fwmark; |
245 | NEXT_ARG(); | 254 | NEXT_ARG(); |
246 | fwmark = get_u32(*argv, "fwmark"); | 255 | fwmark = get_u32(*argv, keyword_fwmark); |
247 | addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); | 256 | addattr32(&req.n, sizeof(req), RTA_PROTOINFO, fwmark); |
248 | } else if (key == ARG_realms) { | 257 | } else if (key == ARG_realms) { |
249 | uint32_t realm; | 258 | uint32_t realm; |
250 | NEXT_ARG(); | 259 | NEXT_ARG(); |
251 | if (get_rt_realms(&realm, *argv)) | 260 | if (get_rt_realms(&realm, *argv)) |
252 | invarg_1_to_2(*argv, "realms"); | 261 | invarg_1_to_2(*argv, keyword_realms); |
253 | addattr32(&req.n, sizeof(req), RTA_FLOW, realm); | 262 | addattr32(&req.n, sizeof(req), RTA_FLOW, realm); |
254 | } else if (key == ARG_table || | 263 | } else if (key == ARG_table || |
255 | key == ARG_lookup | 264 | key == ARG_lookup |
@@ -265,6 +274,16 @@ static int iprule_modify(int cmd, char **argv) | |||
265 | addattr32(&req.n, sizeof(req), RTA_TABLE, tid); | 274 | addattr32(&req.n, sizeof(req), RTA_TABLE, tid); |
266 | } | 275 | } |
267 | table_ok = 1; | 276 | table_ok = 1; |
277 | } else if (key == ARG_suppress_prefixlength) { | ||
278 | int prefix_length; | ||
279 | NEXT_ARG(); | ||
280 | prefix_length = get_u32(*argv, keyword_suppress_prefixlength); | ||
281 | addattr32(&req.n, sizeof(req), FRA_SUPPRESS_PREFIXLEN, prefix_length); | ||
282 | } else if (key == ARG_suppress_ifgroup) { | ||
283 | int grp; | ||
284 | NEXT_ARG(); | ||
285 | grp = get_u32(*argv, keyword_suppress_ifgroup); | ||
286 | addattr32(&req.n, sizeof(req), FRA_SUPPRESS_IFGROUP, grp); | ||
268 | } else if (key == ARG_dev || | 287 | } else if (key == ARG_dev || |
269 | key == ARG_iif | 288 | key == ARG_iif |
270 | ) { | 289 | ) { |
diff --git a/networking/tls.c b/networking/tls.c index db518bf90..fd3cb0dba 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -1199,11 +1199,11 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1199 | }; | 1199 | }; |
1200 | struct client_hello *record; | 1200 | struct client_hello *record; |
1201 | int len; | 1201 | int len; |
1202 | int sni_len = sni ? strnlen(sni, 127) : 0; | 1202 | int sni_len = sni ? strnlen(sni, 127 - 9) : 0; |
1203 | 1203 | ||
1204 | len = sizeof(*record); | 1204 | len = sizeof(*record); |
1205 | if (sni_len) | 1205 | if (sni_len) |
1206 | len += 11 + strlen(sni); | 1206 | len += 11 + sni_len; |
1207 | record = tls_get_outbuf(tls, len); | 1207 | record = tls_get_outbuf(tls, len); |
1208 | memset(record, 0, len); | 1208 | memset(record, 0, len); |
1209 | 1209 | ||
diff --git a/networking/tls_aes.c b/networking/tls_aes.c index 6992f1c90..c137442e9 100644 --- a/networking/tls_aes.c +++ b/networking/tls_aes.c | |||
@@ -40,10 +40,6 @@ | |||
40 | */ | 40 | */ |
41 | #include "tls.h" | 41 | #include "tls.h" |
42 | 42 | ||
43 | /* TODO: grep for this and move to libbb */ | ||
44 | #define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) | ||
45 | |||
46 | |||
47 | // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM | 43 | // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM |
48 | // The numbers below can be computed dynamically trading ROM for RAM - | 44 | // The numbers below can be computed dynamically trading ROM for RAM - |
49 | // This can be useful in (embedded) bootloader applications, where ROM is often limited. | 45 | // This can be useful in (embedded) bootloader applications, where ROM is often limited. |
diff --git a/networking/tls_pstm.c b/networking/tls_pstm.c index bd5bae0b7..e12e6c9d4 100644 --- a/networking/tls_pstm.c +++ b/networking/tls_pstm.c | |||
@@ -2127,7 +2127,7 @@ int32 pstm_invmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c) | |||
2127 | { | 2127 | { |
2128 | pstm_int x, y, u, v, B, D; | 2128 | pstm_int x, y, u, v, B, D; |
2129 | int32 res; | 2129 | int32 res; |
2130 | uint16 neg, sanity; | 2130 | int neg, sanity; //bbox: was uint16 |
2131 | 2131 | ||
2132 | /* 2. [modified] b must be odd */ | 2132 | /* 2. [modified] b must be odd */ |
2133 | if (pstm_iseven (b) == 1) { | 2133 | if (pstm_iseven (b) == 1) { |
diff --git a/networking/tls_pstm_montgomery_reduce.c b/networking/tls_pstm_montgomery_reduce.c index dc2fe0a48..3391755e1 100644 --- a/networking/tls_pstm_montgomery_reduce.c +++ b/networking/tls_pstm_montgomery_reduce.c | |||
@@ -345,7 +345,7 @@ int32 pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, pstm_int *m, | |||
345 | { | 345 | { |
346 | pstm_digit *c, *_c, *tmpm, mu; | 346 | pstm_digit *c, *_c, *tmpm, mu; |
347 | int32 oldused, x, y; | 347 | int32 oldused, x, y; |
348 | int16 pa; | 348 | int pa; //bbox: was int16 |
349 | 349 | ||
350 | pa = m->used; | 350 | pa = m->used; |
351 | if (pa > a->alloc) { | 351 | if (pa > a->alloc) { |
diff --git a/networking/tls_pstm_mul_comba.c b/networking/tls_pstm_mul_comba.c index 47cbb9618..6ba152bc1 100644 --- a/networking/tls_pstm_mul_comba.c +++ b/networking/tls_pstm_mul_comba.c | |||
@@ -85,7 +85,8 @@ asm( \ | |||
85 | "addl %%eax,%0 \n\t" \ | 85 | "addl %%eax,%0 \n\t" \ |
86 | "adcl %%edx,%1 \n\t" \ | 86 | "adcl %%edx,%1 \n\t" \ |
87 | "adcl $0,%2 \n\t" \ | 87 | "adcl $0,%2 \n\t" \ |
88 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); | 88 | :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); |
89 | //bbox: ^^^ replaced "=r" with "=rm": %ebx is not available on shared build | ||
89 | 90 | ||
90 | /******************************************************************************/ | 91 | /******************************************************************************/ |
91 | #elif defined(PSTM_X86_64) | 92 | #elif defined(PSTM_X86_64) |
@@ -228,7 +229,7 @@ asm( \ | |||
228 | static int32 pstm_mul_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, | 229 | static int32 pstm_mul_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, |
229 | pstm_int *C, pstm_digit *paD, uint32 paDlen) | 230 | pstm_int *C, pstm_digit *paD, uint32 paDlen) |
230 | { | 231 | { |
231 | int16 paDfail, pa; | 232 | int paDfail, pa; //bbox: was int16 |
232 | int32 ix, iy, iz, tx, ty; | 233 | int32 ix, iy, iz, tx, ty; |
233 | pstm_digit c0, c1, c2, *tmpx, *tmpy, *dst; | 234 | pstm_digit c0, c1, c2, *tmpx, *tmpy, *dst; |
234 | 235 | ||
diff --git a/networking/tls_pstm_sqr_comba.c b/networking/tls_pstm_sqr_comba.c index 36cb9ea97..d5c74d2f0 100644 --- a/networking/tls_pstm_sqr_comba.c +++ b/networking/tls_pstm_sqr_comba.c | |||
@@ -78,7 +78,8 @@ asm( \ | |||
78 | "addl %%eax,%0 \n\t" \ | 78 | "addl %%eax,%0 \n\t" \ |
79 | "adcl %%edx,%1 \n\t" \ | 79 | "adcl %%edx,%1 \n\t" \ |
80 | "adcl $0,%2 \n\t" \ | 80 | "adcl $0,%2 \n\t" \ |
81 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); | 81 | :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); |
82 | //bbox: ^^^ replaced "=r" with "=rm": %ebx is not available on shared build | ||
82 | 83 | ||
83 | #define SQRADD2(i, j) \ | 84 | #define SQRADD2(i, j) \ |
84 | asm( \ | 85 | asm( \ |
@@ -90,7 +91,8 @@ asm( \ | |||
90 | "addl %%eax,%0 \n\t" \ | 91 | "addl %%eax,%0 \n\t" \ |
91 | "adcl %%edx,%1 \n\t" \ | 92 | "adcl %%edx,%1 \n\t" \ |
92 | "adcl $0,%2 \n\t" \ | 93 | "adcl $0,%2 \n\t" \ |
93 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); | 94 | :"=rm"(c0), "=rm"(c1), "=rm"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); |
95 | //bbox: ^^^ replaced "=r" with "=rm": %ebx is not available on shared build | ||
94 | 96 | ||
95 | #define SQRADDSC(i, j) \ | 97 | #define SQRADDSC(i, j) \ |
96 | asm( \ | 98 | asm( \ |
@@ -445,7 +447,7 @@ asm( \ | |||
445 | static int32 pstm_sqr_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, | 447 | static int32 pstm_sqr_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, |
446 | pstm_digit *paD, uint32 paDlen) | 448 | pstm_digit *paD, uint32 paDlen) |
447 | { | 449 | { |
448 | int16 paDfail, pa; | 450 | int paDfail, pa; //bbox: was int16 |
449 | int32 ix, iz; | 451 | int32 ix, iz; |
450 | pstm_digit c0, c1, c2, *dst; | 452 | pstm_digit c0, c1, c2, *dst; |
451 | #ifdef PSTM_ISO | 453 | #ifdef PSTM_ISO |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 420695a20..d3eea5def 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -14,6 +14,7 @@ const uint8_t MAC_BCAST_ADDR[6] ALIGN2 = { | |||
14 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff | 14 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
15 | }; | 15 | }; |
16 | 16 | ||
17 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | ||
17 | /* Supported options are easily added here. | 18 | /* Supported options are easily added here. |
18 | * See RFC2132 for more options. | 19 | * See RFC2132 for more options. |
19 | * OPTION_REQ: these options are requested by udhcpc (unless -o). | 20 | * OPTION_REQ: these options are requested by udhcpc (unless -o). |
@@ -136,6 +137,7 @@ const char dhcp_option_strings[] ALIGN1 = | |||
136 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ | 137 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ |
137 | "wpad" "\0" /* DHCP_WPAD */ | 138 | "wpad" "\0" /* DHCP_WPAD */ |
138 | ; | 139 | ; |
140 | #endif | ||
139 | 141 | ||
140 | /* Lengths of the option types in binary form. | 142 | /* Lengths of the option types in binary form. |
141 | * Used by: | 143 | * Used by: |
@@ -190,21 +192,26 @@ static void log_option(const char *pfx, const uint8_t *opt) | |||
190 | # define log_option(pfx, opt) ((void)0) | 192 | # define log_option(pfx, opt) ((void)0) |
191 | #endif | 193 | #endif |
192 | 194 | ||
193 | unsigned FAST_FUNC udhcp_option_idx(const char *name) | 195 | unsigned FAST_FUNC udhcp_option_idx(const char *name, const char *option_strings) |
194 | { | 196 | { |
195 | int n = index_in_strings(dhcp_option_strings, name); | 197 | int n = index_in_strings(option_strings, name); |
196 | if (n >= 0) | 198 | if (n >= 0) |
197 | return n; | 199 | return n; |
198 | 200 | ||
199 | { | 201 | { |
200 | char buf[sizeof(dhcp_option_strings)]; | 202 | char *buf, *d; |
201 | char *d = buf; | 203 | const char *s; |
202 | const char *s = dhcp_option_strings; | 204 | |
203 | while (s < dhcp_option_strings + sizeof(dhcp_option_strings) - 2) { | 205 | s = option_strings; |
206 | while (*s) | ||
207 | s += strlen(s) + 1; | ||
208 | |||
209 | d = buf = xzalloc(s - option_strings); | ||
210 | s = option_strings; | ||
211 | while (!(*s == '\0' && s[1] == '\0')) { | ||
204 | *d++ = (*s == '\0' ? ' ' : *s); | 212 | *d++ = (*s == '\0' ? ' ' : *s); |
205 | s++; | 213 | s++; |
206 | } | 214 | } |
207 | *d = '\0'; | ||
208 | bb_error_msg_and_die("unknown option '%s', known options: %s", name, buf); | 215 | bb_error_msg_and_die("unknown option '%s', known options: %s", name, buf); |
209 | } | 216 | } |
210 | } | 217 | } |
@@ -315,6 +322,7 @@ void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addo | |||
315 | optionptr[end + len] = DHCP_END; | 322 | optionptr[end + len] = DHCP_END; |
316 | } | 323 | } |
317 | 324 | ||
325 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | ||
318 | /* Add an one to four byte option to a packet */ | 326 | /* Add an one to four byte option to a packet */ |
319 | void FAST_FUNC udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) | 327 | void FAST_FUNC udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) |
320 | { | 328 | { |
@@ -338,6 +346,7 @@ void FAST_FUNC udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, | |||
338 | 346 | ||
339 | bb_error_msg("can't add option 0x%02x", code); | 347 | bb_error_msg("can't add option 0x%02x", code); |
340 | } | 348 | } |
349 | #endif | ||
341 | 350 | ||
342 | /* Find option 'code' in opt_list */ | 351 | /* Find option 'code' in opt_list */ |
343 | struct option_set* FAST_FUNC udhcp_find_option(struct option_set *opt_list, uint8_t code) | 352 | struct option_set* FAST_FUNC udhcp_find_option(struct option_set *opt_list, uint8_t code) |
@@ -451,7 +460,7 @@ static NOINLINE void attach_option( | |||
451 | free(allocated); | 460 | free(allocated); |
452 | } | 461 | } |
453 | 462 | ||
454 | int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) | 463 | int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg, const struct dhcp_optflag *optflags, const char *option_strings) |
455 | { | 464 | { |
456 | struct option_set **opt_list = arg; | 465 | struct option_set **opt_list = arg; |
457 | char *opt, *val; | 466 | char *opt, *val; |
@@ -478,7 +487,7 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) | |||
478 | bin_optflag.code = optcode; | 487 | bin_optflag.code = optcode; |
479 | optflag = &bin_optflag; | 488 | optflag = &bin_optflag; |
480 | } else { | 489 | } else { |
481 | optflag = &dhcp_optflags[udhcp_option_idx(opt)]; | 490 | optflag = &optflags[udhcp_option_idx(opt, option_strings)]; |
482 | } | 491 | } |
483 | 492 | ||
484 | retval = 0; | 493 | retval = 0; |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index ee12cf91b..a9c23a186 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -93,8 +93,10 @@ enum { | |||
93 | OPTION_BIN, | 93 | OPTION_BIN, |
94 | OPTION_STATIC_ROUTES, | 94 | OPTION_STATIC_ROUTES, |
95 | OPTION_6RD, | 95 | OPTION_6RD, |
96 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 96 | #if ENABLE_FEATURE_UDHCP_RFC3397 || ENABLE_FEATURE_UDHCPC6_RFC3646 || ENABLE_FEATURE_UDHCPC6_RFC4704 |
97 | OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ | 97 | OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ |
98 | #endif | ||
99 | #if ENABLE_FEATURE_UDHCP_RFC3397 | ||
98 | OPTION_SIP_SERVERS, | 100 | OPTION_SIP_SERVERS, |
99 | #endif | 101 | #endif |
100 | 102 | ||
@@ -189,17 +191,21 @@ struct option_set { | |||
189 | struct option_set *next; | 191 | struct option_set *next; |
190 | }; | 192 | }; |
191 | 193 | ||
194 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | ||
192 | extern const struct dhcp_optflag dhcp_optflags[]; | 195 | extern const struct dhcp_optflag dhcp_optflags[]; |
193 | extern const char dhcp_option_strings[] ALIGN1; | 196 | extern const char dhcp_option_strings[] ALIGN1; |
197 | #endif | ||
194 | extern const uint8_t dhcp_option_lengths[] ALIGN1; | 198 | extern const uint8_t dhcp_option_lengths[] ALIGN1; |
195 | 199 | ||
196 | unsigned FAST_FUNC udhcp_option_idx(const char *name); | 200 | unsigned FAST_FUNC udhcp_option_idx(const char *name, const char *option_strings); |
197 | 201 | ||
198 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; | 202 | uint8_t *udhcp_get_option(struct dhcp_packet *packet, int code) FAST_FUNC; |
199 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; | 203 | int udhcp_end_option(uint8_t *optionptr) FAST_FUNC; |
200 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; | 204 | void udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt) FAST_FUNC; |
205 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | ||
201 | void udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) FAST_FUNC; | 206 | void udhcp_add_simple_option(struct dhcp_packet *packet, uint8_t code, uint32_t data) FAST_FUNC; |
202 | #if ENABLE_FEATURE_UDHCP_RFC3397 | 207 | #endif |
208 | #if ENABLE_FEATURE_UDHCP_RFC3397 || ENABLE_FEATURE_UDHCPC6_RFC3646 || ENABLE_FEATURE_UDHCPC6_RFC4704 | ||
203 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; | 209 | char *dname_dec(const uint8_t *cstr, int clen, const char *pre) FAST_FUNC; |
204 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; | 210 | uint8_t *dname_enc(const uint8_t *cstr, int clen, const char *src, int *retlen) FAST_FUNC; |
205 | #endif | 211 | #endif |
@@ -284,9 +290,14 @@ void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; | |||
284 | /* 2nd param is "uint32_t*" */ | 290 | /* 2nd param is "uint32_t*" */ |
285 | int FAST_FUNC udhcp_str2nip(const char *str, void *arg); | 291 | int FAST_FUNC udhcp_str2nip(const char *str, void *arg); |
286 | /* 2nd param is "struct option_set**" */ | 292 | /* 2nd param is "struct option_set**" */ |
287 | int FAST_FUNC udhcp_str2optset(const char *str, void *arg); | 293 | int FAST_FUNC udhcp_str2optset(const char *str, |
294 | void *arg, | ||
295 | const struct dhcp_optflag *optflags, | ||
296 | const char *option_strings); | ||
288 | 297 | ||
298 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | ||
289 | void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; | 299 | void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; |
300 | #endif | ||
290 | 301 | ||
291 | int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC; | 302 | int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC; |
292 | 303 | ||
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index fcec8c15a..310550371 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h | |||
@@ -87,8 +87,47 @@ struct d6_option { | |||
87 | #define D6_OPT_IA_PD 25 | 87 | #define D6_OPT_IA_PD 25 |
88 | #define D6_OPT_IAPREFIX 26 | 88 | #define D6_OPT_IAPREFIX 26 |
89 | 89 | ||
90 | /* RFC 4704 "The DHCPv6 Client FQDN Option" | ||
91 | * uint16 option-code OPTION_CLIENT_FQDN (39) | ||
92 | * uint16 option-len 1 + length of domain name | ||
93 | * uint8 flags | ||
94 | * char[] domain-name partial or fully qualified domain name | ||
95 | * | ||
96 | * Flags format is |MBZ|N|O|S| | ||
97 | * The "S" bit indicates whether the server SHOULD or SHOULD NOT perform | ||
98 | * the AAAA RR (FQDN-to-address) DNS updates. A client sets the bit to | ||
99 | * 0 to indicate that the server SHOULD NOT perform the updates and 1 to | ||
100 | * indicate that the server SHOULD perform the updates. The state of | ||
101 | * the bit in the reply from the server indicates the action to be taken | ||
102 | * by the server; if it is 1, the server has taken responsibility for | ||
103 | * AAAA RR updates for the FQDN. | ||
104 | * The "O" bit indicates whether the server has overridden the client's | ||
105 | * preference for the "S" bit. A client MUST set this bit to 0. A | ||
106 | * server MUST set this bit to 1 if the "S" bit in its reply to the | ||
107 | * client does not match the "S" bit received from the client. | ||
108 | * The "N" bit indicates whether the server SHOULD NOT perform any DNS | ||
109 | * updates. A client sets this bit to 0 to request that the server | ||
110 | * SHOULD perform updates (the PTR RR and possibly the AAAA RR based on | ||
111 | * the "S" bit) or to 1 to request that the server SHOULD NOT perform | ||
112 | * any DNS updates. A server sets the "N" bit to indicate whether the | ||
113 | * server SHALL (0) or SHALL NOT (1) perform DNS updates. If the "N" | ||
114 | * bit is 1, the "S" bit MUST be 0. | ||
115 | * | ||
116 | * If a client knows only part of its name, it MAY send a name that is not | ||
117 | * fully qualified, indicating that it knows part of the name but does not | ||
118 | * necessarily know the zone in which the name is to be embedded. | ||
119 | * To send a fully qualified domain name, the Domain Name field is set | ||
120 | * to the DNS-encoded domain name including the terminating zero-length | ||
121 | * label. To send a partial name, the Domain Name field is set to the | ||
122 | * DNS-encoded domain name without the terminating zero-length label. | ||
123 | * A client MAY also leave the Domain Name field empty if it desires the | ||
124 | * server to provide a name. | ||
125 | */ | ||
90 | #define D6_OPT_CLIENT_FQDN 39 | 126 | #define D6_OPT_CLIENT_FQDN 39 |
91 | 127 | ||
128 | #define D6_OPT_TZ_POSIX 41 | ||
129 | #define D6_OPT_TZ_NAME 42 | ||
130 | |||
92 | /*** Other shared functions ***/ | 131 | /*** Other shared functions ***/ |
93 | 132 | ||
94 | struct client6_data_t { | 133 | struct client6_data_t { |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 18a104c61..f6d3fb98b 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -2,26 +2,49 @@ | |||
2 | /* | 2 | /* |
3 | * DHCPv6 client. | 3 | * DHCPv6 client. |
4 | * | 4 | * |
5 | * 2011-11. | 5 | * WARNING: THIS CODE IS INCOMPLETE. |
6 | * WARNING: THIS CODE IS INCOMPLETE. IT IS NOWHERE NEAR | ||
7 | * TO BE READY FOR PRODUCTION USE. | ||
8 | * | 6 | * |
9 | * Copyright (C) 2011 Denys Vlasenko. | 7 | * Copyright (C) 2011-2017 Denys Vlasenko. |
10 | * | 8 | * |
11 | * Licensed under GPLv2, see file LICENSE in this source tree. | 9 | * Licensed under GPLv2, see file LICENSE in this source tree. |
12 | */ | 10 | */ |
13 | 11 | ||
14 | //config:config UDHCPC6 | 12 | //config:config UDHCPC6 |
15 | //config: bool "udhcpc6 (DHCPv6 client, NOT READY)" | 13 | //config: bool "udhcpc6 (DHCPv6 client, EXPERIMENTAL)" |
16 | //config: default n # not yet ready | 14 | //config: default n # not yet ready |
17 | //config: depends on FEATURE_IPV6 | 15 | //config: depends on FEATURE_IPV6 |
18 | //config: help | 16 | //config: help |
19 | //config: udhcpc6 is a DHCPv6 client | 17 | //config: udhcpc6 is a DHCPv6 client |
18 | //config: | ||
19 | //config:config FEATURE_UDHCPC6_RFC3646 | ||
20 | //config: bool "Support RFC 3646 (DNS server and search list)" | ||
21 | //config: default y | ||
22 | //config: depends on UDHCPC6 | ||
23 | //config: help | ||
24 | //config: List of DNS servers and domain search list can be requested with | ||
25 | //config: "-O dns" and "-O search". If server gives these values, | ||
26 | //config: they will be set in environment variables "dns" and "search". | ||
27 | //config: | ||
28 | //config:config FEATURE_UDHCPC6_RFC4704 | ||
29 | //config: bool "Support RFC 4704 (Client FQDN)" | ||
30 | //config: default y | ||
31 | //config: depends on UDHCPC6 | ||
32 | //config: help | ||
33 | //config: You can request FQDN to be given by server using "-O fqdn". | ||
34 | //config: | ||
35 | //config:config FEATURE_UDHCPC6_RFC4833 | ||
36 | //config: bool "Support RFC 4833 (Timezones)" | ||
37 | //config: default y | ||
38 | //config: depends on UDHCPC6 | ||
39 | //config: help | ||
40 | //config: You can request POSIX timezone with "-O tz" and timezone name | ||
41 | //config: with "-O timezone". | ||
20 | 42 | ||
21 | //applet:IF_UDHCPC6(APPLET(udhcpc6, BB_DIR_USR_BIN, BB_SUID_DROP)) | 43 | //applet:IF_UDHCPC6(APPLET(udhcpc6, BB_DIR_USR_BIN, BB_SUID_DROP)) |
22 | 44 | ||
23 | //kbuild:lib-$(CONFIG_UDHCPC6) += d6_dhcpc.o d6_packet.o d6_socket.o common.o socket.o signalpipe.o | 45 | //kbuild:lib-$(CONFIG_UDHCPC6) += d6_dhcpc.o d6_packet.o d6_socket.o common.o socket.o signalpipe.o |
24 | 46 | //kbuild:lib-$(CONFIG_FEATURE_UDHCPC6_RFC3646) += domain_codec.o | |
47 | //kbuild:lib-$(CONFIG_FEATURE_UDHCPC6_RFC4704) += domain_codec.o | ||
25 | 48 | ||
26 | #include <syslog.h> | 49 | #include <syslog.h> |
27 | /* Override ENABLE_FEATURE_PIDFILE - ifupdown needs our pidfile to always exist */ | 50 | /* Override ENABLE_FEATURE_PIDFILE - ifupdown needs our pidfile to always exist */ |
@@ -37,6 +60,34 @@ | |||
37 | 60 | ||
38 | /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ | 61 | /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ |
39 | 62 | ||
63 | static const struct dhcp_optflag d6_optflags[] = { | ||
64 | #if ENABLE_FEATURE_UDHCPC6_RFC3646 | ||
65 | { OPTION_6RD | OPTION_LIST | OPTION_REQ, D6_OPT_DNS_SERVERS }, | ||
66 | { OPTION_DNS_STRING | OPTION_LIST | OPTION_REQ, D6_OPT_DOMAIN_LIST }, | ||
67 | #endif | ||
68 | #if ENABLE_FEATURE_UDHCPC6_RFC4704 | ||
69 | { OPTION_DNS_STRING, D6_OPT_CLIENT_FQDN }, | ||
70 | #endif | ||
71 | #if ENABLE_FEATURE_UDHCPC6_RFC4833 | ||
72 | { OPTION_STRING, D6_OPT_TZ_POSIX }, | ||
73 | { OPTION_STRING, D6_OPT_TZ_NAME }, | ||
74 | #endif | ||
75 | { 0, 0 } | ||
76 | }; | ||
77 | /* Must match d6_optflags[] order */ | ||
78 | static const char d6_option_strings[] ALIGN1 = | ||
79 | #if ENABLE_FEATURE_UDHCPC6_RFC3646 | ||
80 | "dns" "\0" /* D6_OPT_DNS_SERVERS */ | ||
81 | "search" "\0" /* D6_OPT_DOMAIN_LIST */ | ||
82 | #endif | ||
83 | #if ENABLE_FEATURE_UDHCPC6_RFC4704 | ||
84 | "fqdn" "\0" /* D6_OPT_CLIENT_FQDN */ | ||
85 | #endif | ||
86 | #if ENABLE_FEATURE_UDHCPC6_RFC4833 | ||
87 | "tz" "\0" /* D6_OPT_TZ_POSIX */ | ||
88 | "timezone" "\0" /* D6_OPT_TZ_NAME */ | ||
89 | #endif | ||
90 | "\0"; | ||
40 | 91 | ||
41 | #if ENABLE_LONG_OPTS | 92 | #if ENABLE_LONG_OPTS |
42 | static const char udhcpc6_longopts[] ALIGN1 = | 93 | static const char udhcpc6_longopts[] ALIGN1 = |
@@ -88,19 +139,17 @@ enum { | |||
88 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) | 139 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) |
89 | }; | 140 | }; |
90 | 141 | ||
91 | static const char opt_req[] = { | 142 | #if ENABLE_FEATURE_UDHCPC6_RFC4704 |
92 | (D6_OPT_ORO >> 8), (D6_OPT_ORO & 0xff), | ||
93 | 0, 6, | ||
94 | (D6_OPT_DNS_SERVERS >> 8), (D6_OPT_DNS_SERVERS & 0xff), | ||
95 | (D6_OPT_DOMAIN_LIST >> 8), (D6_OPT_DOMAIN_LIST & 0xff), | ||
96 | (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xff) | ||
97 | }; | ||
98 | |||
99 | static const char opt_fqdn_req[] = { | 143 | static const char opt_fqdn_req[] = { |
100 | (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xff), | 144 | (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xff), |
101 | 0, 2, | 145 | 0, 2, /* optlen */ |
102 | 0, 0 | 146 | 0, /* flags: */ |
147 | /* S=0: server SHOULD NOT perform AAAA RR updates */ | ||
148 | /* O=0: client MUST set this bit to 0 */ | ||
149 | /* N=0: server SHOULD perform updates (PTR RR only in our case, since S=0) */ | ||
150 | 0 /* empty DNS-encoded name */ | ||
103 | }; | 151 | }; |
152 | #endif | ||
104 | 153 | ||
105 | /*** Utility functions ***/ | 154 | /*** Utility functions ***/ |
106 | 155 | ||
@@ -136,12 +185,6 @@ static void *d6_copy_option(uint8_t *option, uint8_t *option_end, unsigned code) | |||
136 | return xmemdup(opt, opt[3] + 4); | 185 | return xmemdup(opt, opt[3] + 4); |
137 | } | 186 | } |
138 | 187 | ||
139 | static void *d6_store_blob(void *dst, const void *src, unsigned len) | ||
140 | { | ||
141 | memcpy(dst, src, len); | ||
142 | return dst + len; | ||
143 | } | ||
144 | |||
145 | 188 | ||
146 | /*** Script execution code ***/ | 189 | /*** Script execution code ***/ |
147 | 190 | ||
@@ -154,10 +197,12 @@ static char** new_env(void) | |||
154 | /* put all the parameters into the environment */ | 197 | /* put all the parameters into the environment */ |
155 | static void option_to_env(uint8_t *option, uint8_t *option_end) | 198 | static void option_to_env(uint8_t *option, uint8_t *option_end) |
156 | { | 199 | { |
157 | char *dlist, *ptr; | 200 | #if ENABLE_FEATURE_UDHCPC6_RFC3646 |
201 | int addrs, option_offset; | ||
202 | #endif | ||
158 | /* "length minus 4" */ | 203 | /* "length minus 4" */ |
159 | int len_m4 = option_end - option - 4; | 204 | int len_m4 = option_end - option - 4; |
160 | int olen, ooff; | 205 | |
161 | while (len_m4 >= 0) { | 206 | while (len_m4 >= 0) { |
162 | uint32_t v32; | 207 | uint32_t v32; |
163 | char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; | 208 | char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; |
@@ -165,6 +210,10 @@ static void option_to_env(uint8_t *option, uint8_t *option_end) | |||
165 | if (option[0] != 0 || option[2] != 0) | 210 | if (option[0] != 0 || option[2] != 0) |
166 | break; | 211 | break; |
167 | 212 | ||
213 | /* Check if option-length exceeds size of option */ | ||
214 | if (option[3] > len_m4) | ||
215 | break; | ||
216 | |||
168 | switch (option[1]) { | 217 | switch (option[1]) { |
169 | //case D6_OPT_CLIENTID: | 218 | //case D6_OPT_CLIENTID: |
170 | //case D6_OPT_SERVERID: | 219 | //case D6_OPT_SERVERID: |
@@ -174,7 +223,7 @@ static void option_to_env(uint8_t *option, uint8_t *option_end) | |||
174 | break; | 223 | break; |
175 | //case D6_OPT_IA_TA: | 224 | //case D6_OPT_IA_TA: |
176 | case D6_OPT_IAADDR: | 225 | case D6_OPT_IAADDR: |
177 | /* 0 1 2 3 | 226 | /* 0 1 2 3 |
178 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 227 | * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
179 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 228 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
180 | * | OPTION_IAADDR | option-len | | 229 | * | OPTION_IAADDR | option-len | |
@@ -235,51 +284,76 @@ static void option_to_env(uint8_t *option, uint8_t *option_end) | |||
235 | sprint_nip6(ipv6str, option + 4 + 4 + 1); | 284 | sprint_nip6(ipv6str, option + 4 + 4 + 1); |
236 | *new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4])); | 285 | *new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4])); |
237 | break; | 286 | break; |
238 | case D6_OPT_DNS_SERVERS: | 287 | #if ENABLE_FEATURE_UDHCPC6_RFC3646 |
239 | olen = ((option[2] << 8) | option[3]) / 16; | 288 | case D6_OPT_DNS_SERVERS: { |
240 | dlist = ptr = malloc (4 + olen * 40 - 1); | 289 | char *dlist; |
241 | |||
242 | memcpy (ptr, "dns=", 4); | ||
243 | ptr += 4; | ||
244 | ooff = 0; | ||
245 | |||
246 | while (olen--) { | ||
247 | sprint_nip6(ptr, option + 4 + ooff); | ||
248 | ptr += 39; | ||
249 | ooff += 16; | ||
250 | if (olen) | ||
251 | *ptr++ = ' '; | ||
252 | } | ||
253 | 290 | ||
254 | *new_env() = dlist; | 291 | /* Make sure payload-size is a multiple of 16 */ |
292 | if ((option[3] & 0x0f) != 0) | ||
293 | break; | ||
294 | |||
295 | /* Get the number of addresses on the option */ | ||
296 | addrs = option[3] >> 4; | ||
297 | |||
298 | /* Setup environment variable */ | ||
299 | *new_env() = dlist = xmalloc(4 + addrs * 40 - 1); | ||
300 | dlist = stpcpy(dlist, "dns="); | ||
301 | option_offset = 0; | ||
302 | |||
303 | while (addrs--) { | ||
304 | sprint_nip6(dlist, option + 4 + option_offset); | ||
305 | dlist += 39; | ||
306 | option_offset += 16; | ||
307 | if (addrs) | ||
308 | *dlist++ = ' '; | ||
309 | } | ||
255 | 310 | ||
256 | break; | 311 | break; |
257 | case D6_OPT_DOMAIN_LIST: | 312 | } |
313 | case D6_OPT_DOMAIN_LIST: { | ||
314 | char *dlist; | ||
315 | |||
258 | dlist = dname_dec(option + 4, (option[2] << 8) | option[3], "search="); | 316 | dlist = dname_dec(option + 4, (option[2] << 8) | option[3], "search="); |
259 | if (!dlist) | 317 | if (!dlist) |
260 | break; | 318 | break; |
261 | *new_env() = dlist; | 319 | *new_env() = dlist; |
262 | break; | 320 | break; |
263 | case D6_OPT_CLIENT_FQDN: | 321 | } |
264 | // Work around broken ISC DHCPD6 | 322 | #endif |
323 | #if ENABLE_FEATURE_UDHCPC6_RFC4704 | ||
324 | case D6_OPT_CLIENT_FQDN: { | ||
325 | char *dlist; | ||
326 | |||
327 | if (option[3] == 0) | ||
328 | break; | ||
329 | /* Work around broken ISC DHCPD6. | ||
330 | * ISC DHCPD6 does not implement RFC 4704 correctly: It says the first | ||
331 | * byte of option-payload should contain flags where the bits 7-3 are | ||
332 | * reserved for future use and MUST be zero. Instead ISC DHCPD6 just | ||
333 | * writes the entire FQDN as string to option-payload. We assume a | ||
334 | * broken server here if any of the reserved bits are set. | ||
335 | */ | ||
265 | if (option[4] & 0xf8) { | 336 | if (option[4] & 0xf8) { |
266 | olen = ((option[2] << 8) | option[3]); | 337 | *new_env() = xasprintf("fqdn=%.*s", (int)option[3], (char*)option + 4); |
267 | dlist = xmalloc(olen); | ||
268 | //fixme: | ||
269 | //- explain | ||
270 | //- add len error check | ||
271 | //- merge two allocs into one | ||
272 | memcpy(dlist, option + 4, olen); | ||
273 | *new_env() = xasprintf("fqdn=%s", dlist); | ||
274 | free(dlist); | ||
275 | break; | 338 | break; |
276 | } | 339 | } |
277 | dlist = dname_dec(option + 5, ((option[2] << 8) | option[3]) - 1, "fqdn="); | 340 | dlist = dname_dec(option + 5, (/*(option[2] << 8) |*/ option[3]) - 1, "fqdn="); |
278 | if (!dlist) | 341 | if (!dlist) |
279 | break; | 342 | break; |
280 | *new_env() = dlist; | 343 | *new_env() = dlist; |
281 | break; | 344 | break; |
282 | } | 345 | } |
346 | #endif | ||
347 | #if ENABLE_FEATURE_UDHCPC6_RFC4833 | ||
348 | /* RFC 4833 Timezones */ | ||
349 | case D6_OPT_TZ_POSIX: | ||
350 | *new_env() = xasprintf("tz=%.*s", (int)option[3], (char*)option + 4); | ||
351 | break; | ||
352 | case D6_OPT_TZ_NAME: | ||
353 | *new_env() = xasprintf("tz_name=%.*s", (int)option[3], (char*)option + 4); | ||
354 | break; | ||
355 | #endif | ||
356 | } | ||
283 | len_m4 -= 4 + option[3]; | 357 | len_m4 -= 4 + option[3]; |
284 | option += 4 + option[3]; | 358 | option += 4 + option[3]; |
285 | } | 359 | } |
@@ -346,22 +420,38 @@ static uint8_t *init_d6_packet(struct d6_packet *packet, char type, uint32_t xid | |||
346 | packet->d6_msg_type = type; | 420 | packet->d6_msg_type = type; |
347 | 421 | ||
348 | clientid = (void*)client_config.clientid; | 422 | clientid = (void*)client_config.clientid; |
349 | return d6_store_blob(packet->d6_options, clientid, clientid->len + 2+2); | 423 | return mempcpy(packet->d6_options, clientid, clientid->len + 2+2); |
350 | } | 424 | } |
351 | 425 | ||
352 | static uint8_t *add_d6_client_options(uint8_t *ptr) | 426 | static uint8_t *add_d6_client_options(uint8_t *ptr) |
353 | { | 427 | { |
354 | return ptr; | 428 | uint8_t *start = ptr; |
355 | //uint8_t c; | 429 | unsigned option; |
356 | //int i, end, len; | 430 | |
431 | ptr += 4; | ||
432 | for (option = 1; option < 256; option++) { | ||
433 | if (client_config.opt_mask[option >> 3] & (1 << (option & 7))) { | ||
434 | ptr[0] = (option >> 8); | ||
435 | ptr[1] = option; | ||
436 | ptr += 2; | ||
437 | } | ||
438 | } | ||
357 | 439 | ||
358 | /* Add a "param req" option with the list of options we'd like to have | 440 | if ((ptr - start - 4) != 0) { |
359 | * from stubborn DHCP servers. Pull the data from the struct in common.c. | 441 | start[0] = (D6_OPT_ORO >> 8); |
360 | * No bounds checking because it goes towards the head of the packet. */ | 442 | start[1] = D6_OPT_ORO; |
361 | //... | 443 | start[2] = ((ptr - start - 4) >> 8); |
444 | start[3] = (ptr - start - 4); | ||
445 | } else | ||
446 | ptr = start; | ||
362 | 447 | ||
448 | #if ENABLE_FEATURE_UDHCPC6_RFC4704 | ||
449 | ptr = mempcpy(ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); | ||
450 | #endif | ||
363 | /* Add -x options if any */ | 451 | /* Add -x options if any */ |
364 | //... | 452 | //... |
453 | |||
454 | return ptr; | ||
365 | } | 455 | } |
366 | 456 | ||
367 | static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t *end) | 457 | static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t *end) |
@@ -483,11 +573,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip | |||
483 | iaaddr->len = 16+4+4; | 573 | iaaddr->len = 16+4+4; |
484 | memcpy(iaaddr->data, requested_ipv6, 16); | 574 | memcpy(iaaddr->data, requested_ipv6, 16); |
485 | } | 575 | } |
486 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, len); | 576 | opt_ptr = mempcpy(opt_ptr, client6_data.ia_na, len); |
487 | |||
488 | /* Request additional options */ | ||
489 | opt_ptr = d6_store_blob(opt_ptr, &opt_req, sizeof(opt_req)); | ||
490 | opt_ptr = d6_store_blob(opt_ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); | ||
491 | 577 | ||
492 | /* Add options: | 578 | /* Add options: |
493 | * "param req" option according to -O, options specified with -x | 579 | * "param req" option according to -O, options specified with -x |
@@ -538,13 +624,9 @@ static NOINLINE int send_d6_select(uint32_t xid) | |||
538 | opt_ptr = init_d6_packet(&packet, D6_MSG_REQUEST, xid); | 624 | opt_ptr = init_d6_packet(&packet, D6_MSG_REQUEST, xid); |
539 | 625 | ||
540 | /* server id */ | 626 | /* server id */ |
541 | opt_ptr = d6_store_blob(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); | 627 | opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); |
542 | /* IA NA (contains requested IP) */ | 628 | /* IA NA (contains requested IP) */ |
543 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); | 629 | opt_ptr = mempcpy(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); |
544 | |||
545 | /* Request additional options */ | ||
546 | opt_ptr = d6_store_blob(opt_ptr, &opt_req, sizeof(opt_req)); | ||
547 | opt_ptr = d6_store_blob(opt_ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); | ||
548 | 630 | ||
549 | /* Add options: | 631 | /* Add options: |
550 | * "param req" option according to -O, options specified with -x | 632 | * "param req" option according to -O, options specified with -x |
@@ -611,9 +693,9 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st | |||
611 | opt_ptr = init_d6_packet(&packet, DHCPREQUEST, xid); | 693 | opt_ptr = init_d6_packet(&packet, DHCPREQUEST, xid); |
612 | 694 | ||
613 | /* server id */ | 695 | /* server id */ |
614 | opt_ptr = d6_store_blob(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); | 696 | opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); |
615 | /* IA NA (contains requested IP) */ | 697 | /* IA NA (contains requested IP) */ |
616 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); | 698 | opt_ptr = mempcpy(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); |
617 | 699 | ||
618 | /* Add options: | 700 | /* Add options: |
619 | * "param req" option according to -O, options specified with -x | 701 | * "param req" option according to -O, options specified with -x |
@@ -640,9 +722,9 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu | |||
640 | /* Fill in: msg type, client id */ | 722 | /* Fill in: msg type, client id */ |
641 | opt_ptr = init_d6_packet(&packet, D6_MSG_RELEASE, random_xid()); | 723 | opt_ptr = init_d6_packet(&packet, D6_MSG_RELEASE, random_xid()); |
642 | /* server id */ | 724 | /* server id */ |
643 | opt_ptr = d6_store_blob(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); | 725 | opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); |
644 | /* IA NA (contains our current IP) */ | 726 | /* IA NA (contains our current IP) */ |
645 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); | 727 | opt_ptr = mempcpy(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); |
646 | 728 | ||
647 | bb_error_msg("sending %s", "release"); | 729 | bb_error_msg("sending %s", "release"); |
648 | return d6_send_kernel_packet( | 730 | return d6_send_kernel_packet( |
@@ -1051,20 +1133,18 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1051 | char *optstr = llist_pop(&list_O); | 1133 | char *optstr = llist_pop(&list_O); |
1052 | unsigned n = bb_strtou(optstr, NULL, 0); | 1134 | unsigned n = bb_strtou(optstr, NULL, 0); |
1053 | if (errno || n > 254) { | 1135 | if (errno || n > 254) { |
1054 | n = udhcp_option_idx(optstr); | 1136 | n = udhcp_option_idx(optstr, d6_option_strings); |
1055 | n = dhcp_optflags[n].code; | 1137 | n = d6_optflags[n].code; |
1056 | } | 1138 | } |
1057 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); | 1139 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); |
1058 | } | 1140 | } |
1059 | if (!(opt & OPT_o)) { | 1141 | if (!(opt & OPT_o)) { |
1060 | /* | ||
1061 | unsigned i, n; | 1142 | unsigned i, n; |
1062 | for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) { | 1143 | for (i = 0; (n = d6_optflags[i].code) != 0; i++) { |
1063 | if (dhcp_optflags[i].flags & OPTION_REQ) { | 1144 | if (d6_optflags[i].flags & OPTION_REQ) { |
1064 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); | 1145 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); |
1065 | } | 1146 | } |
1066 | } | 1147 | } |
1067 | */ | ||
1068 | } | 1148 | } |
1069 | while (list_x) { | 1149 | while (list_x) { |
1070 | char *optstr = llist_pop(&list_x); | 1150 | char *optstr = llist_pop(&list_x); |
@@ -1073,7 +1153,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1073 | *colon = ' '; | 1153 | *colon = ' '; |
1074 | /* now it looks similar to udhcpd's config file line: | 1154 | /* now it looks similar to udhcpd's config file line: |
1075 | * "optname optval", using the common routine: */ | 1155 | * "optname optval", using the common routine: */ |
1076 | udhcp_str2optset(optstr, &client_config.options); | 1156 | udhcp_str2optset(optstr, &client_config.options, d6_optflags, d6_option_strings); |
1077 | if (colon) | 1157 | if (colon) |
1078 | *colon = ':'; /* restore it for NOMMU reexec */ | 1158 | *colon = ':'; /* restore it for NOMMU reexec */ |
1079 | } | 1159 | } |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 6aa6731fb..1a66c610e 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -1346,7 +1346,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1346 | char *optstr = llist_pop(&list_O); | 1346 | char *optstr = llist_pop(&list_O); |
1347 | unsigned n = bb_strtou(optstr, NULL, 0); | 1347 | unsigned n = bb_strtou(optstr, NULL, 0); |
1348 | if (errno || n > 254) { | 1348 | if (errno || n > 254) { |
1349 | n = udhcp_option_idx(optstr); | 1349 | n = udhcp_option_idx(optstr, dhcp_option_strings); |
1350 | n = dhcp_optflags[n].code; | 1350 | n = dhcp_optflags[n].code; |
1351 | } | 1351 | } |
1352 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); | 1352 | client_config.opt_mask[n >> 3] |= 1 << (n & 7); |
@@ -1366,7 +1366,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1366 | *colon = ' '; | 1366 | *colon = ' '; |
1367 | /* now it looks similar to udhcpd's config file line: | 1367 | /* now it looks similar to udhcpd's config file line: |
1368 | * "optname optval", using the common routine: */ | 1368 | * "optname optval", using the common routine: */ |
1369 | udhcp_str2optset(optstr, &client_config.options); | 1369 | udhcp_str2optset(optstr, &client_config.options, dhcp_optflags, dhcp_option_strings); |
1370 | if (colon) | 1370 | if (colon) |
1371 | *colon = ':'; /* restore it for NOMMU reexec */ | 1371 | *colon = ':'; /* restore it for NOMMU reexec */ |
1372 | } | 1372 | } |
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 9f423a5b2..7fdbc9a6c 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h | |||
@@ -12,6 +12,7 @@ struct client_config_t { | |||
12 | IF_FEATURE_UDHCP_PORT(uint16_t port;) | 12 | IF_FEATURE_UDHCP_PORT(uint16_t port;) |
13 | int ifindex; /* Index number of the interface to use */ | 13 | int ifindex; /* Index number of the interface to use */ |
14 | uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ | 14 | uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ |
15 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TODO: DHCPv6 has 16-bit option numbers | ||
15 | const char *interface; /* The name of the interface to use */ | 16 | const char *interface; /* The name of the interface to use */ |
16 | char *pidfile; /* Optionally store the process ID */ | 17 | char *pidfile; /* Optionally store the process ID */ |
17 | const char *script; /* User script to run at dhcp events */ | 18 | const char *script; /* User script to run at dhcp events */ |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 5eff026bc..3a5fc2db7 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -361,6 +361,10 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg) | |||
361 | return 1; | 361 | return 1; |
362 | } | 362 | } |
363 | 363 | ||
364 | static int FAST_FUNC read_optset(const char *line, void *arg) { | ||
365 | return udhcp_str2optset(line, arg, dhcp_optflags, dhcp_option_strings); | ||
366 | } | ||
367 | |||
364 | struct config_keyword { | 368 | struct config_keyword { |
365 | const char *keyword; | 369 | const char *keyword; |
366 | int (*handler)(const char *line, void *var) FAST_FUNC; | 370 | int (*handler)(const char *line, void *var) FAST_FUNC; |
@@ -387,8 +391,8 @@ static const struct config_keyword keywords[] = { | |||
387 | {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, | 391 | {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, |
388 | {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, | 392 | {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, |
389 | /* keywords with no defaults must be last! */ | 393 | /* keywords with no defaults must be last! */ |
390 | {"option" , udhcp_str2optset, OFS(options ), ""}, | 394 | {"option" , read_optset , OFS(options ), ""}, |
391 | {"opt" , udhcp_str2optset, OFS(options ), ""}, | 395 | {"opt" , read_optset , OFS(options ), ""}, |
392 | {"notify_file" , read_str , OFS(notify_file ), NULL}, | 396 | {"notify_file" , read_str , OFS(notify_file ), NULL}, |
393 | {"sname" , read_str , OFS(sname ), NULL}, | 397 | {"sname" , read_str , OFS(sname ), NULL}, |
394 | {"boot_file" , read_str , OFS(boot_file ), NULL}, | 398 | {"boot_file" , read_str , OFS(boot_file ), NULL}, |
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 0a31f2643..9e1b46d2f 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <netinet/if_ether.h> | 12 | #include <netinet/if_ether.h> |
13 | #include <netpacket/packet.h> | 13 | #include <netpacket/packet.h> |
14 | 14 | ||
15 | #if ENABLE_UDHCPC || ENABLE_UDHCPD | ||
15 | void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) | 16 | void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) |
16 | { | 17 | { |
17 | memset(packet, 0, sizeof(*packet)); | 18 | memset(packet, 0, sizeof(*packet)); |
@@ -29,6 +30,7 @@ void FAST_FUNC udhcp_init_header(struct dhcp_packet *packet, char type) | |||
29 | packet->options[0] = DHCP_END; | 30 | packet->options[0] = DHCP_END; |
30 | udhcp_add_simple_option(packet, DHCP_MESSAGE_TYPE, type); | 31 | udhcp_add_simple_option(packet, DHCP_MESSAGE_TYPE, type); |
31 | } | 32 | } |
33 | #endif | ||
32 | 34 | ||
33 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | 35 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 |
34 | void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) | 36 | void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) |