diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-11-21 14:25:15 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-11-21 14:25:15 +0100 |
commit | 5f118ff8851adb8370e8f130bb2ec2e80b55246c (patch) | |
tree | 6d8d2841a2ce317f0195fe5954dbbc8f046546bf | |
parent | 2951add2bf240e47b1d2e7bc384f138428391366 (diff) | |
parent | fc186711fe75cfc4abda9a7ff29050bc7a56313b (diff) | |
download | busybox-w32-5f118ff8851adb8370e8f130bb2ec2e80b55246c.tar.gz busybox-w32-5f118ff8851adb8370e8f130bb2ec2e80b55246c.tar.bz2 busybox-w32-5f118ff8851adb8370e8f130bb2ec2e80b55246c.zip |
Merge branch 'master' of git+ssh://busybox.net/var/lib/git/busybox
-rw-r--r-- | include/libbb.h | 12 | ||||
-rw-r--r-- | libbb/dump.c | 25 | ||||
-rw-r--r-- | mailutils/mail.c | 2 | ||||
-rw-r--r-- | mailutils/mail.h | 7 | ||||
-rw-r--r-- | mailutils/makemime.c | 34 | ||||
-rw-r--r-- | mailutils/reformime.c | 1 | ||||
-rw-r--r-- | mailutils/sendmail.c | 22 | ||||
-rw-r--r-- | networking/udhcp/common.c | 19 | ||||
-rw-r--r-- | networking/udhcp/common.h | 3 | ||||
-rw-r--r-- | networking/udhcp/d6_common.h | 5 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 126 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 30 |
12 files changed, 203 insertions, 83 deletions
diff --git a/include/libbb.h b/include/libbb.h index 09e8d28e7..3f6fe47ed 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -211,7 +211,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
211 | # if ULONG_MAX > 0xffffffff | 211 | # if ULONG_MAX > 0xffffffff |
212 | /* "long" is long enough on this system */ | 212 | /* "long" is long enough on this system */ |
213 | typedef unsigned long uoff_t; | 213 | typedef unsigned long uoff_t; |
214 | # define XATOOFF(a) xatoul_range(a, 0, LONG_MAX) | 214 | # define XATOOFF(a) xatoul_range((a), 0, LONG_MAX) |
215 | /* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */ | 215 | /* usage: sz = BB_STRTOOFF(s, NULL, 10); if (errno || sz < 0) die(); */ |
216 | # define BB_STRTOOFF bb_strtoul | 216 | # define BB_STRTOOFF bb_strtoul |
217 | # define STRTOOFF strtoul | 217 | # define STRTOOFF strtoul |
@@ -220,7 +220,7 @@ typedef unsigned long uoff_t; | |||
220 | # else | 220 | # else |
221 | /* "long" is too short, need "long long" */ | 221 | /* "long" is too short, need "long long" */ |
222 | typedef unsigned long long uoff_t; | 222 | typedef unsigned long long uoff_t; |
223 | # define XATOOFF(a) xatoull_range(a, 0, LLONG_MAX) | 223 | # define XATOOFF(a) xatoull_range((a), 0, LLONG_MAX) |
224 | # define BB_STRTOOFF bb_strtoull | 224 | # define BB_STRTOOFF bb_strtoull |
225 | # define STRTOOFF strtoull | 225 | # define STRTOOFF strtoull |
226 | # define OFF_FMT "ll" | 226 | # define OFF_FMT "ll" |
@@ -237,7 +237,7 @@ typedef unsigned long uoff_t; | |||
237 | # define OFF_FMT "l" | 237 | # define OFF_FMT "l" |
238 | # else | 238 | # else |
239 | typedef unsigned long uoff_t; | 239 | typedef unsigned long uoff_t; |
240 | # define XATOOFF(a) xatoul_range(a, 0, LONG_MAX) | 240 | # define XATOOFF(a) xatoul_range((a), 0, LONG_MAX) |
241 | # define BB_STRTOOFF bb_strtoul | 241 | # define BB_STRTOOFF bb_strtoul |
242 | # define STRTOOFF strtol | 242 | # define STRTOOFF strtol |
243 | # define OFF_FMT "l" | 243 | # define OFF_FMT "l" |
@@ -245,6 +245,12 @@ typedef unsigned long uoff_t; | |||
245 | #endif | 245 | #endif |
246 | /* scary. better ideas? (but do *test* them first!) */ | 246 | /* scary. better ideas? (but do *test* them first!) */ |
247 | #define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) | 247 | #define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) |
248 | /* Users report bionic to use 32-bit off_t even if LARGEFILE support is requested. | ||
249 | * We misdetected that. Don't let it build: | ||
250 | */ | ||
251 | struct BUG_off_t_size_is_misdetected { | ||
252 | char BUG_off_t_size_is_misdetected[sizeof(off_t) == sizeof(uoff_t) ? 1 : -1]; | ||
253 | }; | ||
248 | 254 | ||
249 | /* Some useful definitions */ | 255 | /* Some useful definitions */ |
250 | #undef FALSE | 256 | #undef FALSE |
diff --git a/libbb/dump.c b/libbb/dump.c index 919fe135c..7e435643b 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -71,7 +71,8 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
71 | * skip any special chars -- save precision in | 71 | * skip any special chars -- save precision in |
72 | * case it's a %s format. | 72 | * case it's a %s format. |
73 | */ | 73 | */ |
74 | while (strchr(index_str + 1, *++fmt)); | 74 | while (strchr(index_str + 1, *++fmt)) |
75 | continue; | ||
75 | if (*fmt == '.' && isdigit(*++fmt)) { | 76 | if (*fmt == '.' && isdigit(*++fmt)) { |
76 | prec = atoi(fmt); | 77 | prec = atoi(fmt); |
77 | while (isdigit(*++fmt)) | 78 | while (isdigit(*++fmt)) |
@@ -99,8 +100,8 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
99 | static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | 100 | static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) |
100 | { | 101 | { |
101 | enum { NOTOKAY, USEBCNT, USEPREC } sokay; | 102 | enum { NOTOKAY, USEBCNT, USEPREC } sokay; |
102 | PR *pr; | ||
103 | FU *fu; | 103 | FU *fu; |
104 | PR *pr; | ||
104 | char *p1, *p2, *p3; | 105 | char *p1, *p2, *p3; |
105 | char savech, *fmtp; | 106 | char savech, *fmtp; |
106 | const char *byte_count_str; | 107 | const char *byte_count_str; |
@@ -292,16 +293,18 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
292 | * interprets any data at all, and has no iteration count, | 293 | * interprets any data at all, and has no iteration count, |
293 | * repeat it as necessary. | 294 | * repeat it as necessary. |
294 | * | 295 | * |
295 | * if, rep count is greater than 1, no trailing whitespace | 296 | * if rep count is greater than 1, no trailing whitespace |
296 | * gets output from the last iteration of the format unit. | 297 | * gets output from the last iteration of the format unit. |
297 | */ | 298 | */ |
298 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 299 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
299 | if (!fu->nextfu && fs->bcnt < dumper->blocksize | 300 | if (!fu->nextfu |
300 | && !(fu->flags & F_SETREP) && fu->bcnt | 301 | && fs->bcnt < dumper->blocksize |
302 | && !(fu->flags & F_SETREP) | ||
303 | && fu->bcnt | ||
301 | ) { | 304 | ) { |
302 | fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; | 305 | fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; |
303 | } | 306 | } |
304 | if (fu->reps > 1) { | 307 | if (fu->reps > 1 && fu->nextpr) { |
305 | for (pr = fu->nextpr;; pr = pr->nextpr) | 308 | for (pr = fu->nextpr;; pr = pr->nextpr) |
306 | if (!pr->nextpr) | 309 | if (!pr->nextpr) |
307 | break; | 310 | break; |
@@ -721,7 +724,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
721 | p = fmt; | 724 | p = fmt; |
722 | for (;;) { | 725 | for (;;) { |
723 | p = skip_whitespace(p); | 726 | p = skip_whitespace(p); |
724 | if (!*p) { | 727 | if (*p == '\0') { |
725 | break; | 728 | break; |
726 | } | 729 | } |
727 | 730 | ||
@@ -749,7 +752,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
749 | 752 | ||
750 | /* skip slash and trailing white space */ | 753 | /* skip slash and trailing white space */ |
751 | if (*p == '/') { | 754 | if (*p == '/') { |
752 | p = skip_whitespace(++p); | 755 | p = skip_whitespace(p + 1); |
753 | } | 756 | } |
754 | 757 | ||
755 | /* byte count */ | 758 | /* byte count */ |
@@ -763,7 +766,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
763 | } | 766 | } |
764 | tfu->bcnt = atoi(savep); | 767 | tfu->bcnt = atoi(savep); |
765 | /* skip trailing white space */ | 768 | /* skip trailing white space */ |
766 | p = skip_whitespace(++p); | 769 | p = skip_whitespace(p + 1); |
767 | } | 770 | } |
768 | 771 | ||
769 | /* format */ | 772 | /* format */ |
@@ -771,7 +774,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
771 | bb_error_msg_and_die("bad format {%s}", fmt); | 774 | bb_error_msg_and_die("bad format {%s}", fmt); |
772 | } | 775 | } |
773 | for (savep = ++p; *p != '"';) { | 776 | for (savep = ++p; *p != '"';) { |
774 | if (*p++ == 0) { | 777 | if (*p++ == '\0') { |
775 | bb_error_msg_and_die("bad format {%s}", fmt); | 778 | bb_error_msg_and_die("bad format {%s}", fmt); |
776 | } | 779 | } |
777 | } | 780 | } |
@@ -782,7 +785,7 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
782 | 785 | ||
783 | /* alphabetic escape sequences have to be done in place */ | 786 | /* alphabetic escape sequences have to be done in place */ |
784 | for (p2 = p1;; ++p1, ++p2) { | 787 | for (p2 = p1;; ++p1, ++p2) { |
785 | if (!*p1) { | 788 | if (*p1 == '\0') { |
786 | *p2 = *p1; | 789 | *p2 = *p1; |
787 | break; | 790 | break; |
788 | } | 791 | } |
diff --git a/mailutils/mail.c b/mailutils/mail.c index f5260d9db..199f64407 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c | |||
@@ -119,7 +119,7 @@ static char* FAST_FUNC parse_url(char *url, char **user, char **pass) | |||
119 | void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) | 119 | void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) |
120 | { | 120 | { |
121 | enum { | 121 | enum { |
122 | SRC_BUF_SIZE = 45, /* This *MUST* be a multiple of 3 */ | 122 | SRC_BUF_SIZE = 57, /* This *MUST* be a multiple of 3 */ |
123 | DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), | 123 | DST_BUF_SIZE = 4 * ((SRC_BUF_SIZE + 2) / 3), |
124 | }; | 124 | }; |
125 | #define src_buf text | 125 | #define src_buf text |
diff --git a/mailutils/mail.h b/mailutils/mail.h index d1d783055..fa0c5b378 100644 --- a/mailutils/mail.h +++ b/mailutils/mail.h | |||
@@ -16,22 +16,15 @@ struct globals { | |||
16 | char *pass; | 16 | char *pass; |
17 | FILE *fp0; // initial stdin | 17 | FILE *fp0; // initial stdin |
18 | char *opt_charset; | 18 | char *opt_charset; |
19 | char *content_type; | ||
20 | }; | 19 | }; |
21 | 20 | ||
22 | #define G (*ptr_to_globals) | 21 | #define G (*ptr_to_globals) |
23 | #define timeout (G.timeout ) | 22 | #define timeout (G.timeout ) |
24 | #define verbose (G.verbose ) | 23 | #define verbose (G.verbose ) |
25 | #define opts (G.opts ) | 24 | #define opts (G.opts ) |
26 | //#define user (G.user ) | ||
27 | //#define pass (G.pass ) | ||
28 | //#define fp0 (G.fp0 ) | ||
29 | //#define opt_charset (G.opt_charset) | ||
30 | //#define content_type (G.content_type) | ||
31 | #define INIT_G() do { \ | 25 | #define INIT_G() do { \ |
32 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 26 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
33 | G.opt_charset = (char *)CONFIG_FEATURE_MIME_CHARSET; \ | 27 | G.opt_charset = (char *)CONFIG_FEATURE_MIME_CHARSET; \ |
34 | G.content_type = (char *)"text/plain"; \ | ||
35 | } while (0) | 28 | } while (0) |
36 | 29 | ||
37 | //char FAST_FUNC *parse_url(char *url, char **user, char **pass); | 30 | //char FAST_FUNC *parse_url(char *url, char **user, char **pass); |
diff --git a/mailutils/makemime.c b/mailutils/makemime.c index a9ff03d03..4b07e54de 100644 --- a/mailutils/makemime.c +++ b/mailutils/makemime.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * makemime: create MIME-encoded message | 3 | * makemime: create MIME-encoded message |
4 | * reformime: parse MIME-encoded message | ||
5 | * | 4 | * |
6 | * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> | 5 | * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> |
7 | * | 6 | * |
@@ -135,19 +134,42 @@ Content-Transfer-Encoding: 7bit | |||
135 | //usage: "\n -o FILE Output. Default: stdout" | 134 | //usage: "\n -o FILE Output. Default: stdout" |
136 | //usage: "\n -a HDR Add header. Examples:" | 135 | //usage: "\n -a HDR Add header. Examples:" |
137 | //usage: "\n \"From: user@host.org\", \"Date: `date -R`\"" | 136 | //usage: "\n \"From: user@host.org\", \"Date: `date -R`\"" |
138 | //usage: "\n -c CT Content type. Default: text/plain" | 137 | //usage: "\n -c CT Content type. Default: application/octet-stream" |
139 | //usage: "\n -C CS Charset. Default: " CONFIG_FEATURE_MIME_CHARSET | 138 | //usage: "\n -C CS Charset. Default: " CONFIG_FEATURE_MIME_CHARSET |
140 | /* //usage: "\n -e ENC Transfer encoding. Ignored. base64 is assumed" */ | 139 | /* //usage: "\n -e ENC Transfer encoding. Ignored. base64 is assumed" */ |
141 | //usage: "\n" | 140 | //usage: "\n" |
142 | //usage: "\nOther options are silently ignored" | 141 | //usage: "\nOther options are silently ignored" |
143 | 142 | ||
143 | /* | ||
144 | * -c [Content-Type] should create just one MIME section | ||
145 | * with "Content-Type:", "Content-Transfer-Encoding:", and HDR from "-a HDR". | ||
146 | * NB: without "Content-Disposition:" auto-added, unlike we do now | ||
147 | * NB2: -c has *optional* param which nevertheless _can_ be specified after a space :( | ||
148 | * | ||
149 | * -m [multipart/mixed] should create multipart MIME section | ||
150 | * with "Content-Type:", "Content-Transfer-Encoding:", and HDR from "-a HDR", | ||
151 | * and add FILE to it _verbatim_: | ||
152 | * HEADERS | ||
153 | * | ||
154 | * --=_1_1321709112_1605 | ||
155 | * FILE_CONTENTS | ||
156 | * --=_1_1321709112_1605 | ||
157 | * without any encoding of FILE_CONTENTS. (Basically, it expects that FILE | ||
158 | * is the result of "makemime -c"). | ||
159 | * | ||
160 | * -j MULTIPART_FILE1 SINGLE_FILE2 should output MULTIPART_FILE1 + SINGLE_FILE2 | ||
161 | * | ||
162 | * Our current behavior is a mutant "-m + -c + -j" one: we create multipart MIME | ||
163 | * and we put "-c" encoded FILEs into many multipart sections. | ||
164 | */ | ||
165 | |||
144 | int makemime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 166 | int makemime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
145 | int makemime_main(int argc UNUSED_PARAM, char **argv) | 167 | int makemime_main(int argc UNUSED_PARAM, char **argv) |
146 | { | 168 | { |
147 | llist_t *opt_headers = NULL, *l; | 169 | llist_t *opt_headers = NULL, *l; |
148 | const char *opt_output; | 170 | const char *opt_output; |
171 | const char *content_type = "application/octet-stream"; | ||
149 | #define boundary opt_output | 172 | #define boundary opt_output |
150 | |||
151 | enum { | 173 | enum { |
152 | OPT_c = 1 << 0, // create (non-multipart) section | 174 | OPT_c = 1 << 0, // create (non-multipart) section |
153 | OPT_e = 1 << 1, // Content-Transfer-Encoding. Ignored. Assumed base64 | 175 | OPT_e = 1 << 1, // Content-Transfer-Encoding. Ignored. Assumed base64 |
@@ -164,8 +186,8 @@ int makemime_main(int argc UNUSED_PARAM, char **argv) | |||
164 | // parse options | 186 | // parse options |
165 | opt_complementary = "a::"; | 187 | opt_complementary = "a::"; |
166 | opts = getopt32(argv, | 188 | opts = getopt32(argv, |
167 | "c:e:o:C:N:a:", //:m:j:", | 189 | "c:e:o:C:N:a:", // "m:j:", |
168 | &G.content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL | 190 | &content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL |
169 | ); | 191 | ); |
170 | //argc -= optind; | 192 | //argc -= optind; |
171 | argv += optind; | 193 | argv += optind; |
@@ -202,7 +224,7 @@ int makemime_main(int argc UNUSED_PARAM, char **argv) | |||
202 | "Content-Disposition: inline; filename=\"%s\"\n" | 224 | "Content-Disposition: inline; filename=\"%s\"\n" |
203 | "Content-Transfer-Encoding: base64\n" | 225 | "Content-Transfer-Encoding: base64\n" |
204 | , boundary | 226 | , boundary |
205 | , G.content_type | 227 | , content_type |
206 | , G.opt_charset | 228 | , G.opt_charset |
207 | , bb_get_last_path_component_strip(*argv) | 229 | , bb_get_last_path_component_strip(*argv) |
208 | ); | 230 | ); |
diff --git a/mailutils/reformime.c b/mailutils/reformime.c index 5e28ef729..8e7d455f6 100644 --- a/mailutils/reformime.c +++ b/mailutils/reformime.c | |||
@@ -1,6 +1,5 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * makemime: create MIME-encoded message | ||
4 | * reformime: parse MIME-encoded message | 3 | * reformime: parse MIME-encoded message |
5 | * | 4 | * |
6 | * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> | 5 | * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> |
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index dbd491002..aa381c60f 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c | |||
@@ -281,17 +281,19 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) | |||
281 | 281 | ||
282 | // analyze headers | 282 | // analyze headers |
283 | // To: or Cc: headers add recipients | 283 | // To: or Cc: headers add recipients |
284 | if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) { | 284 | if (opts & OPT_t) { |
285 | rcptto(sane_address(s+3)); | 285 | if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) { |
286 | goto addheader; | 286 | rcptto(sane_address(s+3)); |
287 | goto addheader; | ||
288 | } | ||
289 | // Bcc: header adds blind copy (hidden) recipient | ||
290 | if (0 == strncasecmp("Bcc:", s, 4)) { | ||
291 | rcptto(sane_address(s+4)); | ||
292 | free(s); | ||
293 | continue; // N.B. Bcc: vanishes from headers! | ||
294 | } | ||
287 | } | 295 | } |
288 | // Bcc: header adds blind copy (hidden) recipient | 296 | if (strchr(s, ':') || (list && isspace(s[0]))) { |
289 | if (0 == strncasecmp("Bcc:", s, 4)) { | ||
290 | rcptto(sane_address(s+4)); | ||
291 | free(s); | ||
292 | // N.B. Bcc: vanishes from headers! | ||
293 | } else | ||
294 | if (strchr(s, ':') || (list && skip_whitespace(s) != s)) { | ||
295 | // other headers go verbatim | 297 | // other headers go verbatim |
296 | // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. | 298 | // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. |
297 | // Continuation is denoted by prefixing additional lines with whitespace(s). | 299 | // Continuation is denoted by prefixing additional lines with whitespace(s). |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 2e6113627..a89dce3ae 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -539,3 +539,22 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) | |||
539 | 539 | ||
540 | return retval; | 540 | return retval; |
541 | } | 541 | } |
542 | |||
543 | /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ | ||
544 | int FAST_FUNC sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) | ||
545 | { | ||
546 | char hexstrbuf[16 * 2]; | ||
547 | bin2hex(hexstrbuf, (void*)ip, 16); | ||
548 | return sprintf(dest, /* "%s" */ | ||
549 | "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", | ||
550 | /* pre, */ | ||
551 | hexstrbuf + 0 * 4, | ||
552 | hexstrbuf + 1 * 4, | ||
553 | hexstrbuf + 2 * 4, | ||
554 | hexstrbuf + 3 * 4, | ||
555 | hexstrbuf + 4 * 4, | ||
556 | hexstrbuf + 5 * 4, | ||
557 | hexstrbuf + 6 * 4, | ||
558 | hexstrbuf + 7 * 4 | ||
559 | ); | ||
560 | } | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index a7f9395b8..479ae49f3 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -308,6 +308,9 @@ int arpping(uint32_t test_nip, | |||
308 | uint8_t *from_mac, | 308 | uint8_t *from_mac, |
309 | const char *interface) FAST_FUNC; | 309 | const char *interface) FAST_FUNC; |
310 | 310 | ||
311 | /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ | ||
312 | int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; | ||
313 | |||
311 | POP_SAVED_FUNCTION_VISIBILITY | 314 | POP_SAVED_FUNCTION_VISIBILITY |
312 | 315 | ||
313 | #endif | 316 | #endif |
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index 36d822f7e..4dd7e621e 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h | |||
@@ -81,11 +81,16 @@ struct d6_option { | |||
81 | #define D6_OPT_RECONF_MSG 19 | 81 | #define D6_OPT_RECONF_MSG 19 |
82 | #define D6_OPT_RECONF_ACCEPT 20 | 82 | #define D6_OPT_RECONF_ACCEPT 20 |
83 | 83 | ||
84 | #define D6_OPT_IA_PD 25 | ||
85 | #define D6_OPT_IAPREFIX 26 | ||
86 | |||
84 | /*** Other shared functions ***/ | 87 | /*** Other shared functions ***/ |
85 | 88 | ||
86 | struct client6_data_t { | 89 | struct client6_data_t { |
87 | struct d6_option *server_id; | 90 | struct d6_option *server_id; |
88 | struct d6_option *ia_na; | 91 | struct d6_option *ia_na; |
92 | char **env_ptr; | ||
93 | unsigned env_idx; | ||
89 | }; | 94 | }; |
90 | 95 | ||
91 | #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) | 96 | #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 5c98e82f1..23e6862dc 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -129,32 +129,114 @@ static void *d6_store_blob(void *dst, const void *src, unsigned len) | |||
129 | 129 | ||
130 | /*** Script execution code ***/ | 130 | /*** Script execution code ***/ |
131 | 131 | ||
132 | static char** new_env(void) | ||
133 | { | ||
134 | client6_data.env_ptr = xrealloc_vector(client6_data.env_ptr, 3, client6_data.env_idx); | ||
135 | return &client6_data.env_ptr[client6_data.env_idx++]; | ||
136 | } | ||
137 | |||
132 | /* put all the parameters into the environment */ | 138 | /* put all the parameters into the environment */ |
133 | static char **fill_envp(struct d6_packet *packet | 139 | static void option_to_env(uint8_t *option, uint8_t *option_end) |
134 | UNUSED_PARAM | ||
135 | ) | ||
136 | { | 140 | { |
137 | int envc; | 141 | /* "length minus 4" */ |
138 | char **envp, **curr; | 142 | int len_m4 = option_end - option - 4; |
143 | while (len_m4 >= 0) { | ||
144 | uint32_t v32; | ||
145 | char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; | ||
139 | 146 | ||
140 | #define BITMAP unsigned | 147 | if (option[0] != 0 || option[2] != 0) |
141 | #define BBITS (sizeof(BITMAP) * 8) | 148 | break; |
142 | #define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1))) | 149 | |
143 | #define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS]) | 150 | switch (option[1]) { |
144 | ///BITMAP found_opts[256 / BBITS]; | 151 | //case D6_OPT_CLIENTID: |
152 | //case D6_OPT_SERVERID: | ||
153 | case D6_OPT_IA_NA: | ||
154 | case D6_OPT_IA_PD: | ||
155 | option_to_env(option + 16, option + 4 + option[3]); | ||
156 | break; | ||
157 | //case D6_OPT_IA_TA: | ||
158 | case D6_OPT_IAADDR: | ||
159 | /* 0 1 2 3 | ||
160 | * 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 | ||
161 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
162 | * | OPTION_IAADDR | option-len | | ||
163 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
164 | * | | | ||
165 | * | IPv6 address | | ||
166 | * | | | ||
167 | * | | | ||
168 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
169 | * | preferred-lifetime | | ||
170 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
171 | * | valid-lifetime | | ||
172 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
173 | */ | ||
174 | sprint_nip6(ipv6str, option + 4); | ||
175 | *new_env() = xasprintf("ipv6=%s", ipv6str); | ||
176 | |||
177 | move_from_unaligned32(v32, option + 4 + 16 + 4); | ||
178 | *new_env() = xasprintf("lease=%u", (unsigned)v32); | ||
179 | break; | ||
180 | |||
181 | //case D6_OPT_ORO: | ||
182 | //case D6_OPT_PREFERENCE: | ||
183 | //case D6_OPT_ELAPSED_TIME: | ||
184 | //case D6_OPT_RELAY_MSG: | ||
185 | //case D6_OPT_AUTH: | ||
186 | //case D6_OPT_UNICAST: | ||
187 | //case D6_OPT_STATUS_CODE: | ||
188 | //case D6_OPT_RAPID_COMMIT: | ||
189 | //case D6_OPT_USER_CLASS: | ||
190 | //case D6_OPT_VENDOR_CLASS: | ||
191 | //case D6_OPT_VENDOR_OPTS: | ||
192 | //case D6_OPT_INTERFACE_ID: | ||
193 | //case D6_OPT_RECONF_MSG: | ||
194 | //case D6_OPT_RECONF_ACCEPT: | ||
195 | |||
196 | case D6_OPT_IAPREFIX: | ||
197 | /* 0 1 2 3 | ||
198 | * 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 | ||
199 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
200 | * | OPTION_IAPREFIX | option-length | | ||
201 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
202 | * | preferred-lifetime | | ||
203 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
204 | * | valid-lifetime | | ||
205 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
206 | * | prefix-length | | | ||
207 | * +-+-+-+-+-+-+-+-+ IPv6 prefix | | ||
208 | * | (16 octets) | | ||
209 | * | | | ||
210 | * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
211 | * | | | ||
212 | * +-+-+-+-+-+-+-+-+ | ||
213 | */ | ||
214 | //move_from_unaligned32(v32, option + 4 + 4); | ||
215 | //*new_env() = xasprintf("lease=%u", (unsigned)v32); | ||
145 | 216 | ||
146 | ///memset(found_opts, 0, sizeof(found_opts)); | 217 | sprint_nip6(ipv6str, option + 4 + 4 + 1); |
218 | *new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4])); | ||
219 | } | ||
220 | option += 4 + option[3]; | ||
221 | len_m4 -= 4 + option[3]; | ||
222 | } | ||
223 | } | ||
147 | 224 | ||
148 | /* We need 2 elements for: | 225 | static char **fill_envp(struct d6_packet *packet) |
149 | * "interface=IFACE" | 226 | { |
150 | * terminating NULL | 227 | char **envp, **curr; |
151 | */ | 228 | |
152 | envc = 2; | 229 | client6_data.env_ptr = NULL; |
230 | client6_data.env_idx = 0; | ||
231 | |||
232 | *new_env() = xasprintf("interface=%s", client_config.interface); | ||
153 | 233 | ||
154 | curr = envp = xzalloc(sizeof(envp[0]) * envc); | 234 | if (packet) |
235 | option_to_env(packet->d6_options, packet->d6_options + sizeof(packet->d6_options)); | ||
155 | 236 | ||
156 | *curr = xasprintf("interface=%s", client_config.interface); | 237 | envp = curr = client6_data.env_ptr; |
157 | putenv(*curr++); | 238 | while (*curr) |
239 | putenv(*curr++); | ||
158 | 240 | ||
159 | return envp; | 241 | return envp; |
160 | } | 242 | } |
@@ -1329,19 +1411,19 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1329 | free(client6_data.ia_na); | 1411 | free(client6_data.ia_na); |
1330 | client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); | 1412 | client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); |
1331 | if (!client6_data.ia_na) { | 1413 | if (!client6_data.ia_na) { |
1332 | bb_error_msg("no lease time, ignoring packet"); | 1414 | bb_error_msg("no %s option, ignoring packet", "IA_NA"); |
1333 | continue; | 1415 | continue; |
1334 | } | 1416 | } |
1335 | if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { | 1417 | if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { |
1336 | bb_error_msg("IA_NA option is too short:%d bytes", client6_data.ia_na->len); | 1418 | bb_error_msg("IA_NA option is too short:%d bytes", client6_data.ia_na->len); |
1337 | continue; | 1419 | continue; |
1338 | } | 1420 | } |
1339 | iaaddr = d6_find_option(client6_data.ia_na->data, | 1421 | iaaddr = d6_find_option(client6_data.ia_na->data + 4 + 4 + 4, |
1340 | client6_data.ia_na->data + client6_data.ia_na->len, | 1422 | client6_data.ia_na->data + client6_data.ia_na->len, |
1341 | D6_OPT_IAADDR | 1423 | D6_OPT_IAADDR |
1342 | ); | 1424 | ); |
1343 | if (!iaaddr) { | 1425 | if (!iaaddr) { |
1344 | bb_error_msg("no lease time, ignoring packet"); | 1426 | bb_error_msg("no %s option, ignoring packet", "IAADDR"); |
1345 | continue; | 1427 | continue; |
1346 | } | 1428 | } |
1347 | if (iaaddr->len < (16 + 4 + 4)) { | 1429 | if (iaaddr->len < (16 + 4 + 4)) { |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 3c4e8dee1..945600c6b 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -123,24 +123,6 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) | |||
123 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); | 123 | return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); |
124 | } | 124 | } |
125 | 125 | ||
126 | static int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) | ||
127 | { | ||
128 | char hexstrbuf[16 * 2]; | ||
129 | bin2hex(hexstrbuf, (void*)ip, 16); | ||
130 | return sprintf(dest, /* "%s" */ | ||
131 | "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", | ||
132 | /* pre, */ | ||
133 | hexstrbuf + 0 * 4, | ||
134 | hexstrbuf + 1 * 4, | ||
135 | hexstrbuf + 2 * 4, | ||
136 | hexstrbuf + 3 * 4, | ||
137 | hexstrbuf + 4 * 4, | ||
138 | hexstrbuf + 5 * 4, | ||
139 | hexstrbuf + 6 * 4, | ||
140 | hexstrbuf + 7 * 4 | ||
141 | ); | ||
142 | } | ||
143 | |||
144 | /* really simple implementation, just count the bits */ | 126 | /* really simple implementation, just count the bits */ |
145 | static int mton(uint32_t mask) | 127 | static int mton(uint32_t mask) |
146 | { | 128 | { |
@@ -744,7 +726,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
744 | #if ENABLE_FEATURE_UDHCPC_ARPING | 726 | #if ENABLE_FEATURE_UDHCPC_ARPING |
745 | /* Broadcast a DHCP decline message */ | 727 | /* Broadcast a DHCP decline message */ |
746 | /* NOINLINE: limit stack usage in caller */ | 728 | /* NOINLINE: limit stack usage in caller */ |
747 | static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t requested) | 729 | static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested) |
748 | { | 730 | { |
749 | struct dhcp_packet packet; | 731 | struct dhcp_packet packet; |
750 | 732 | ||
@@ -753,12 +735,14 @@ static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t request | |||
753 | */ | 735 | */ |
754 | init_packet(&packet, DHCPDECLINE); | 736 | init_packet(&packet, DHCPDECLINE); |
755 | 737 | ||
738 | #if 0 | ||
756 | /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, | 739 | /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, |
757 | * but in case the server is buggy and wants DHCPDECLINE's xid | 740 | * but in case the server is buggy and wants DHCPDECLINE's xid |
758 | * to match the xid which started entire handshake, | 741 | * to match the xid which started entire handshake, |
759 | * we use the same xid we used in initial DHCPDISCOVER: | 742 | * we use the same xid we used in initial DHCPDISCOVER: |
760 | */ | 743 | */ |
761 | packet.xid = xid; | 744 | packet.xid = xid; |
745 | #endif | ||
762 | /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ | 746 | /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ |
763 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); | 747 | udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); |
764 | 748 | ||
@@ -1149,7 +1133,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1149 | int discover_retries = 3; | 1133 | int discover_retries = 3; |
1150 | uint32_t server_addr = server_addr; /* for compiler */ | 1134 | uint32_t server_addr = server_addr; /* for compiler */ |
1151 | uint32_t requested_ip = 0; | 1135 | uint32_t requested_ip = 0; |
1152 | uint32_t xid = 0; | 1136 | uint32_t xid = xid; /* for compiler */ |
1153 | int packet_num; | 1137 | int packet_num; |
1154 | int timeout; /* must be signed */ | 1138 | int timeout; /* must be signed */ |
1155 | unsigned already_waited_sec; | 1139 | unsigned already_waited_sec; |
@@ -1538,7 +1522,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1538 | 1522 | ||
1539 | switch (state) { | 1523 | switch (state) { |
1540 | case INIT_SELECTING: | 1524 | case INIT_SELECTING: |
1541 | /* Must be a DHCPOFFER to one of our xid's */ | 1525 | /* Must be a DHCPOFFER */ |
1542 | if (*message == DHCPOFFER) { | 1526 | if (*message == DHCPOFFER) { |
1543 | /* What exactly is server's IP? There are several values. | 1527 | /* What exactly is server's IP? There are several values. |
1544 | * Example DHCP offer captured with tchdump: | 1528 | * Example DHCP offer captured with tchdump: |
@@ -1618,7 +1602,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1618 | ) { | 1602 | ) { |
1619 | bb_info_msg("Offered address is in use " | 1603 | bb_info_msg("Offered address is in use " |
1620 | "(got ARP reply), declining"); | 1604 | "(got ARP reply), declining"); |
1621 | send_decline(xid, server_addr, packet.yiaddr); | 1605 | send_decline(/*xid,*/ server_addr, packet.yiaddr); |
1622 | 1606 | ||
1623 | if (state != REQUESTING) | 1607 | if (state != REQUESTING) |
1624 | udhcp_run_script(NULL, "deconfig"); | 1608 | udhcp_run_script(NULL, "deconfig"); |
@@ -1655,6 +1639,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1655 | opt = ((opt & ~OPT_b) | OPT_f); | 1639 | opt = ((opt & ~OPT_b) | OPT_f); |
1656 | } | 1640 | } |
1657 | #endif | 1641 | #endif |
1642 | /* make future renew packets use different xid */ | ||
1643 | /* xid = random_xid(); ...but why bother? */ | ||
1658 | already_waited_sec = 0; | 1644 | already_waited_sec = 0; |
1659 | continue; /* back to main loop */ | 1645 | continue; /* back to main loop */ |
1660 | } | 1646 | } |