aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-11-21 14:25:15 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-11-21 14:25:15 +0100
commit5f118ff8851adb8370e8f130bb2ec2e80b55246c (patch)
tree6d8d2841a2ce317f0195fe5954dbbc8f046546bf
parent2951add2bf240e47b1d2e7bc384f138428391366 (diff)
parentfc186711fe75cfc4abda9a7ff29050bc7a56313b (diff)
downloadbusybox-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.h12
-rw-r--r--libbb/dump.c25
-rw-r--r--mailutils/mail.c2
-rw-r--r--mailutils/mail.h7
-rw-r--r--mailutils/makemime.c34
-rw-r--r--mailutils/reformime.c1
-rw-r--r--mailutils/sendmail.c22
-rw-r--r--networking/udhcp/common.c19
-rw-r--r--networking/udhcp/common.h3
-rw-r--r--networking/udhcp/d6_common.h5
-rw-r--r--networking/udhcp/d6_dhcpc.c126
-rw-r--r--networking/udhcp/dhcpc.c30
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 */
213typedef unsigned long uoff_t; 213typedef 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" */
222typedef unsigned long long uoff_t; 222typedef 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
239typedef unsigned long uoff_t; 239typedef 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 */
251struct 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)
99static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) 100static 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)
119void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) 119void 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
144int makemime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 166int makemime_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
145int makemime_main(int argc UNUSED_PARAM, char **argv) 167int 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 */
544int 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 */
312int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC;
313
311POP_SAVED_FUNCTION_VISIBILITY 314POP_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
86struct client6_data_t { 89struct 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
132static 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 */
133static char **fill_envp(struct d6_packet *packet 139static 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: 225static 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
126static 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 */
145static int mton(uint32_t mask) 127static 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 */
747static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t requested) 729static 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 }