diff options
Diffstat (limited to 'networking')
-rw-r--r-- | networking/arp.c | 1 | ||||
-rw-r--r-- | networking/arping.c | 1 | ||||
-rw-r--r-- | networking/brctl.c | 1 | ||||
-rw-r--r-- | networking/ether-wake.c | 1 | ||||
-rw-r--r-- | networking/httpd.c | 192 | ||||
-rw-r--r-- | networking/httpd_indexcgi.c | 80 | ||||
-rw-r--r-- | networking/ifconfig.c | 1 | ||||
-rw-r--r-- | networking/ifenslave.c | 1 | ||||
-rw-r--r-- | networking/ifplugd.c | 1 | ||||
-rw-r--r-- | networking/ip.c | 11 | ||||
-rw-r--r-- | networking/libiproute/ip_common.h | 4 | ||||
-rw-r--r-- | networking/libiproute/ipaddress.c | 104 | ||||
-rw-r--r-- | networking/nameif.c | 1 | ||||
-rw-r--r-- | networking/netstat.c | 1 | ||||
-rw-r--r-- | networking/ntpd.c | 38 | ||||
-rw-r--r-- | networking/parse_pasv_epsv.c | 2 | ||||
-rw-r--r-- | networking/ping.c | 1 | ||||
-rw-r--r-- | networking/route.c | 1 | ||||
-rw-r--r-- | networking/slattach.c | 1 | ||||
-rw-r--r-- | networking/tls.c | 2 | ||||
-rw-r--r-- | networking/traceroute.c | 1 | ||||
-rw-r--r-- | networking/tunctl.c | 1 | ||||
-rw-r--r-- | networking/udhcp/Config.src | 2 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 138 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 1 | ||||
-rw-r--r-- | networking/udhcp/domain_codec.c | 157 | ||||
-rw-r--r-- | networking/vconfig.c | 1 | ||||
-rw-r--r-- | networking/zcip.c | 1 |
28 files changed, 498 insertions, 249 deletions
diff --git a/networking/arp.c b/networking/arp.c index 6519f8156..16783ab95 100644 --- a/networking/arp.c +++ b/networking/arp.c | |||
@@ -15,7 +15,6 @@ | |||
15 | //config:config ARP | 15 | //config:config ARP |
16 | //config: bool "arp (10 kb)" | 16 | //config: bool "arp (10 kb)" |
17 | //config: default y | 17 | //config: default y |
18 | //config: select PLATFORM_LINUX | ||
19 | //config: help | 18 | //config: help |
20 | //config: Manipulate the system ARP cache. | 19 | //config: Manipulate the system ARP cache. |
21 | 20 | ||
diff --git a/networking/arping.c b/networking/arping.c index 2a256aaa0..d44d7d697 100644 --- a/networking/arping.c +++ b/networking/arping.c | |||
@@ -8,7 +8,6 @@ | |||
8 | //config:config ARPING | 8 | //config:config ARPING |
9 | //config: bool "arping (9 kb)" | 9 | //config: bool "arping (9 kb)" |
10 | //config: default y | 10 | //config: default y |
11 | //config: select PLATFORM_LINUX | ||
12 | //config: help | 11 | //config: help |
13 | //config: Ping hosts by ARP packets. | 12 | //config: Ping hosts by ARP packets. |
14 | 13 | ||
diff --git a/networking/brctl.c b/networking/brctl.c index 2f4ac4a87..f057f9b60 100644 --- a/networking/brctl.c +++ b/networking/brctl.c | |||
@@ -12,7 +12,6 @@ | |||
12 | //config:config BRCTL | 12 | //config:config BRCTL |
13 | //config: bool "brctl (4.7 kb)" | 13 | //config: bool "brctl (4.7 kb)" |
14 | //config: default y | 14 | //config: default y |
15 | //config: select PLATFORM_LINUX | ||
16 | //config: help | 15 | //config: help |
17 | //config: Manage ethernet bridges. | 16 | //config: Manage ethernet bridges. |
18 | //config: Supports addbr/delbr and addif/delif. | 17 | //config: Supports addbr/delbr and addif/delif. |
diff --git a/networking/ether-wake.c b/networking/ether-wake.c index f45d43609..36e90acfb 100644 --- a/networking/ether-wake.c +++ b/networking/ether-wake.c | |||
@@ -66,7 +66,6 @@ | |||
66 | //config:config ETHER_WAKE | 66 | //config:config ETHER_WAKE |
67 | //config: bool "ether-wake (4.9 kb)" | 67 | //config: bool "ether-wake (4.9 kb)" |
68 | //config: default y | 68 | //config: default y |
69 | //config: select PLATFORM_LINUX | ||
70 | //config: help | 69 | //config: help |
71 | //config: Send a magic packet to wake up sleeping machines. | 70 | //config: Send a magic packet to wake up sleeping machines. |
72 | 71 | ||
diff --git a/networking/httpd.c b/networking/httpd.c index 5d2d2681c..19cc08fcb 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -214,6 +214,44 @@ | |||
214 | //config: help | 214 | //config: help |
215 | //config: Makes httpd send files using GZIP content encoding if the | 215 | //config: Makes httpd send files using GZIP content encoding if the |
216 | //config: client supports it and a pre-compressed <file>.gz exists. | 216 | //config: client supports it and a pre-compressed <file>.gz exists. |
217 | //config: | ||
218 | //config:config FEATURE_HTTPD_ETAG | ||
219 | //config: bool "Support caching via ETag header" | ||
220 | //config: default y | ||
221 | //config: depends on HTTPD | ||
222 | //config: help | ||
223 | //config: If server responds with ETag then next time client (browser) | ||
224 | //config: resend it via If-None-Match header. | ||
225 | //config: Then httpd will check if file wasn't modified and if not, | ||
226 | //config: return 304 Not Modified status code. | ||
227 | //config: The ETag value is constructed from last modification date | ||
228 | //config: in unix epoch, and size: "hex(last_mod)-hex(file_size)". | ||
229 | //config: It's not completely reliable as hash functions but fair enough. | ||
230 | //config: | ||
231 | //config:config FEATURE_HTTPD_LAST_MODIFIED | ||
232 | //config: bool "Add Last-Modified header to response" | ||
233 | //config: default y | ||
234 | //config: depends on HTTPD | ||
235 | //config: help | ||
236 | //config: The Last-Modified header is used for cache validation. | ||
237 | //config: The client sends last seen mtime to server in If-Modified-Since. | ||
238 | //config: Both headers MUST be an RFC 1123 formatted, which is hard to parse. | ||
239 | //config: Use ETag header instead. | ||
240 | //config: | ||
241 | //config:config FEATURE_HTTPD_DATE | ||
242 | //config: bool "Add Date header to response" | ||
243 | //config: default y | ||
244 | //config: depends on HTTPD | ||
245 | //config: help | ||
246 | //config: RFC2616 says that server MUST add Date header to response. | ||
247 | //config: But it is almost useless and can be omitted. | ||
248 | //config: | ||
249 | //config:config FEATURE_HTTPD_ACL_IP | ||
250 | //config: bool "ACL IP" | ||
251 | //config: default y | ||
252 | //config: depends on HTTPD | ||
253 | //config: help | ||
254 | //config: Support IP deny/allow rules | ||
217 | 255 | ||
218 | //applet:IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 256 | //applet:IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
219 | 257 | ||
@@ -278,7 +316,7 @@ static void send_REQUEST_TIMEOUT_and_exit(int sig) NORETURN; | |||
278 | 316 | ||
279 | static const char DEFAULT_PATH_HTTPD_CONF[] ALIGN1 = "/etc"; | 317 | static const char DEFAULT_PATH_HTTPD_CONF[] ALIGN1 = "/etc"; |
280 | static const char HTTPD_CONF[] ALIGN1 = "httpd.conf"; | 318 | static const char HTTPD_CONF[] ALIGN1 = "httpd.conf"; |
281 | static const char HTTP_200[] ALIGN1 = "HTTP/1.0 200 OK\r\n"; | 319 | static const char HTTP_200[] ALIGN1 = "HTTP/1.1 200 OK\r\n"; |
282 | static const char index_html[] ALIGN1 = "index.html"; | 320 | static const char index_html[] ALIGN1 = "index.html"; |
283 | 321 | ||
284 | typedef struct has_next_ptr { | 322 | typedef struct has_next_ptr { |
@@ -292,6 +330,7 @@ typedef struct Htaccess { | |||
292 | char before_colon[1]; /* really bigger, must be last */ | 330 | char before_colon[1]; /* really bigger, must be last */ |
293 | } Htaccess; | 331 | } Htaccess; |
294 | 332 | ||
333 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
295 | /* Must have "next" as a first member */ | 334 | /* Must have "next" as a first member */ |
296 | typedef struct Htaccess_IP { | 335 | typedef struct Htaccess_IP { |
297 | struct Htaccess_IP *next; | 336 | struct Htaccess_IP *next; |
@@ -299,6 +338,7 @@ typedef struct Htaccess_IP { | |||
299 | unsigned mask; | 338 | unsigned mask; |
300 | int allow_deny; | 339 | int allow_deny; |
301 | } Htaccess_IP; | 340 | } Htaccess_IP; |
341 | #endif | ||
302 | 342 | ||
303 | /* Must have "next" as a first member */ | 343 | /* Must have "next" as a first member */ |
304 | typedef struct Htaccess_Proxy { | 344 | typedef struct Htaccess_Proxy { |
@@ -319,6 +359,7 @@ enum { | |||
319 | HTTP_OK = 200, | 359 | HTTP_OK = 200, |
320 | HTTP_PARTIAL_CONTENT = 206, | 360 | HTTP_PARTIAL_CONTENT = 206, |
321 | HTTP_MOVED_TEMPORARILY = 302, | 361 | HTTP_MOVED_TEMPORARILY = 302, |
362 | HTTP_NOT_MODIFIED = 304, | ||
322 | HTTP_BAD_REQUEST = 400, /* malformed syntax */ | 363 | HTTP_BAD_REQUEST = 400, /* malformed syntax */ |
323 | HTTP_UNAUTHORIZED = 401, /* authentication needed, respond with auth hdr */ | 364 | HTTP_UNAUTHORIZED = 401, /* authentication needed, respond with auth hdr */ |
324 | HTTP_NOT_FOUND = 404, | 365 | HTTP_NOT_FOUND = 404, |
@@ -336,7 +377,6 @@ enum { | |||
336 | HTTP_NO_CONTENT = 204, | 377 | HTTP_NO_CONTENT = 204, |
337 | HTTP_MULTIPLE_CHOICES = 300, | 378 | HTTP_MULTIPLE_CHOICES = 300, |
338 | HTTP_MOVED_PERMANENTLY = 301, | 379 | HTTP_MOVED_PERMANENTLY = 301, |
339 | HTTP_NOT_MODIFIED = 304, | ||
340 | HTTP_PAYMENT_REQUIRED = 402, | 380 | HTTP_PAYMENT_REQUIRED = 402, |
341 | HTTP_BAD_GATEWAY = 502, | 381 | HTTP_BAD_GATEWAY = 502, |
342 | HTTP_SERVICE_UNAVAILABLE = 503, /* overload, maintenance */ | 382 | HTTP_SERVICE_UNAVAILABLE = 503, /* overload, maintenance */ |
@@ -349,6 +389,9 @@ static const uint16_t http_response_type[] ALIGN2 = { | |||
349 | HTTP_PARTIAL_CONTENT, | 389 | HTTP_PARTIAL_CONTENT, |
350 | #endif | 390 | #endif |
351 | HTTP_MOVED_TEMPORARILY, | 391 | HTTP_MOVED_TEMPORARILY, |
392 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
393 | HTTP_NOT_MODIFIED, | ||
394 | #endif | ||
352 | HTTP_REQUEST_TIMEOUT, | 395 | HTTP_REQUEST_TIMEOUT, |
353 | HTTP_NOT_IMPLEMENTED, | 396 | HTTP_NOT_IMPLEMENTED, |
354 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 397 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
@@ -365,7 +408,6 @@ static const uint16_t http_response_type[] ALIGN2 = { | |||
365 | HTTP_NO_CONTENT, | 408 | HTTP_NO_CONTENT, |
366 | HTTP_MULTIPLE_CHOICES, | 409 | HTTP_MULTIPLE_CHOICES, |
367 | HTTP_MOVED_PERMANENTLY, | 410 | HTTP_MOVED_PERMANENTLY, |
368 | HTTP_NOT_MODIFIED, | ||
369 | HTTP_BAD_GATEWAY, | 411 | HTTP_BAD_GATEWAY, |
370 | HTTP_SERVICE_UNAVAILABLE, | 412 | HTTP_SERVICE_UNAVAILABLE, |
371 | #endif | 413 | #endif |
@@ -380,6 +422,9 @@ static const struct { | |||
380 | { "Partial Content", NULL }, | 422 | { "Partial Content", NULL }, |
381 | #endif | 423 | #endif |
382 | { "Found", NULL }, | 424 | { "Found", NULL }, |
425 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
426 | { "Not Modified" }, | ||
427 | #endif | ||
383 | { "Request Timeout", "No request appeared within 60 seconds" }, | 428 | { "Request Timeout", "No request appeared within 60 seconds" }, |
384 | { "Not Implemented", "The requested method is not recognized" }, | 429 | { "Not Implemented", "The requested method is not recognized" }, |
385 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 430 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
@@ -396,7 +441,6 @@ static const struct { | |||
396 | { "No Content" }, | 441 | { "No Content" }, |
397 | { "Multiple Choices" }, | 442 | { "Multiple Choices" }, |
398 | { "Moved Permanently" }, | 443 | { "Moved Permanently" }, |
399 | { "Not Modified" }, | ||
400 | { "Bad Gateway", "" }, | 444 | { "Bad Gateway", "" }, |
401 | { "Service Unavailable", "" }, | 445 | { "Service Unavailable", "" }, |
402 | #endif | 446 | #endif |
@@ -410,6 +454,9 @@ struct globals { | |||
410 | smallint content_gzip; | 454 | smallint content_gzip; |
411 | #endif | 455 | #endif |
412 | time_t last_mod; | 456 | time_t last_mod; |
457 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
458 | char *if_none_match; | ||
459 | #endif | ||
413 | char *rmt_ip_str; /* for $REMOTE_ADDR and $REMOTE_PORT */ | 460 | char *rmt_ip_str; /* for $REMOTE_ADDR and $REMOTE_PORT */ |
414 | const char *bind_addr_or_port; | 461 | const char *bind_addr_or_port; |
415 | 462 | ||
@@ -420,7 +467,9 @@ struct globals { | |||
420 | 467 | ||
421 | const char *found_mime_type; | 468 | const char *found_mime_type; |
422 | const char *found_moved_temporarily; | 469 | const char *found_moved_temporarily; |
470 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
423 | Htaccess_IP *ip_a_d; /* config allow/deny lines */ | 471 | Htaccess_IP *ip_a_d; /* config allow/deny lines */ |
472 | #endif | ||
424 | 473 | ||
425 | IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) | 474 | IF_FEATURE_HTTPD_BASIC_AUTH(const char *g_realm;) |
426 | IF_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;) | 475 | IF_FEATURE_HTTPD_BASIC_AUTH(char *remoteuser;) |
@@ -444,6 +493,9 @@ struct globals { | |||
444 | #define sizeof_hdr_buf COMMON_BUFSIZE | 493 | #define sizeof_hdr_buf COMMON_BUFSIZE |
445 | char *hdr_ptr; | 494 | char *hdr_ptr; |
446 | int hdr_cnt; | 495 | int hdr_cnt; |
496 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
497 | char etag[sizeof("'%llx-%llx'") + 2 * sizeof(long long)*3]; | ||
498 | #endif | ||
447 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES | 499 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES |
448 | const char *http_error_page[ARRAY_SIZE(http_response_type)]; | 500 | const char *http_error_page[ARRAY_SIZE(http_response_type)]; |
449 | #endif | 501 | #endif |
@@ -467,7 +519,6 @@ struct globals { | |||
467 | #define found_mime_type (G.found_mime_type ) | 519 | #define found_mime_type (G.found_mime_type ) |
468 | #define found_moved_temporarily (G.found_moved_temporarily) | 520 | #define found_moved_temporarily (G.found_moved_temporarily) |
469 | #define last_mod (G.last_mod ) | 521 | #define last_mod (G.last_mod ) |
470 | #define ip_a_d (G.ip_a_d ) | ||
471 | #define g_realm (G.g_realm ) | 522 | #define g_realm (G.g_realm ) |
472 | #define remoteuser (G.remoteuser ) | 523 | #define remoteuser (G.remoteuser ) |
473 | #define file_size (G.file_size ) | 524 | #define file_size (G.file_size ) |
@@ -528,11 +579,14 @@ static ALWAYS_INLINE void free_Htaccess_list(Htaccess **pptr) | |||
528 | free_llist((has_next_ptr**)pptr); | 579 | free_llist((has_next_ptr**)pptr); |
529 | } | 580 | } |
530 | 581 | ||
582 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
531 | static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr) | 583 | static ALWAYS_INLINE void free_Htaccess_IP_list(Htaccess_IP **pptr) |
532 | { | 584 | { |
533 | free_llist((has_next_ptr**)pptr); | 585 | free_llist((has_next_ptr**)pptr); |
534 | } | 586 | } |
587 | #endif | ||
535 | 588 | ||
589 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
536 | /* Returns presumed mask width in bits or < 0 on error. | 590 | /* Returns presumed mask width in bits or < 0 on error. |
537 | * Updates strp, stores IP at provided pointer */ | 591 | * Updates strp, stores IP at provided pointer */ |
538 | static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc) | 592 | static int scan_ip(const char **strp, unsigned *ipp, unsigned char endc) |
@@ -617,6 +671,7 @@ static int scan_ip_mask(const char *str, unsigned *ipp, unsigned *maskp) | |||
617 | *maskp = (uint32_t)(~mask); | 671 | *maskp = (uint32_t)(~mask); |
618 | return 0; | 672 | return 0; |
619 | } | 673 | } |
674 | #endif | ||
620 | 675 | ||
621 | /* | 676 | /* |
622 | * Parse configuration file into in-memory linked list. | 677 | * Parse configuration file into in-memory linked list. |
@@ -646,7 +701,9 @@ static void parse_conf(const char *path, int flag) | |||
646 | char buf[160]; | 701 | char buf[160]; |
647 | 702 | ||
648 | /* discard old rules */ | 703 | /* discard old rules */ |
649 | free_Htaccess_IP_list(&ip_a_d); | 704 | #if ENABLE_FEATURE_HTTPD_ACL_IP |
705 | free_Htaccess_IP_list(&G.ip_a_d); | ||
706 | #endif | ||
650 | flg_deny_all = 0; | 707 | flg_deny_all = 0; |
651 | /* retain previous auth and mime config only for subdir parse */ | 708 | /* retain previous auth and mime config only for subdir parse */ |
652 | if (flag != SUBDIR_PARSE) { | 709 | if (flag != SUBDIR_PARSE) { |
@@ -763,6 +820,7 @@ static void parse_conf(const char *path, int flag) | |||
763 | continue; | 820 | continue; |
764 | } | 821 | } |
765 | 822 | ||
823 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
766 | if (ch == 'A' || ch == 'D') { | 824 | if (ch == 'A' || ch == 'D') { |
767 | Htaccess_IP *pip; | 825 | Htaccess_IP *pip; |
768 | 826 | ||
@@ -784,13 +842,13 @@ static void parse_conf(const char *path, int flag) | |||
784 | pip->allow_deny = ch; | 842 | pip->allow_deny = ch; |
785 | if (ch == 'D') { | 843 | if (ch == 'D') { |
786 | /* Deny:from_IP - prepend */ | 844 | /* Deny:from_IP - prepend */ |
787 | pip->next = ip_a_d; | 845 | pip->next = G.ip_a_d; |
788 | ip_a_d = pip; | 846 | G.ip_a_d = pip; |
789 | } else { | 847 | } else { |
790 | /* A:from_IP - append (thus all D's precedes A's) */ | 848 | /* A:from_IP - append (thus all D's precedes A's) */ |
791 | Htaccess_IP *prev_IP = ip_a_d; | 849 | Htaccess_IP *prev_IP = G.ip_a_d; |
792 | if (prev_IP == NULL) { | 850 | if (prev_IP == NULL) { |
793 | ip_a_d = pip; | 851 | G.ip_a_d = pip; |
794 | } else { | 852 | } else { |
795 | while (prev_IP->next) | 853 | while (prev_IP->next) |
796 | prev_IP = prev_IP->next; | 854 | prev_IP = prev_IP->next; |
@@ -799,6 +857,7 @@ static void parse_conf(const char *path, int flag) | |||
799 | } | 857 | } |
800 | continue; | 858 | continue; |
801 | } | 859 | } |
860 | #endif | ||
802 | 861 | ||
803 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES | 862 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES |
804 | if (flag == FIRST_PARSE && ch == 'E') { | 863 | if (flag == FIRST_PARSE && ch == 'E') { |
@@ -1059,11 +1118,12 @@ static void log_and_exit(void) | |||
1059 | */ | 1118 | */ |
1060 | static void send_headers(unsigned responseNum) | 1119 | static void send_headers(unsigned responseNum) |
1061 | { | 1120 | { |
1121 | #if ENABLE_FEATURE_HTTPD_DATE || ENABLE_FEATURE_HTTPD_LAST_MODIFIED | ||
1062 | static const char RFC1123FMT[] ALIGN1 = "%a, %d %b %Y %H:%M:%S GMT"; | 1122 | static const char RFC1123FMT[] ALIGN1 = "%a, %d %b %Y %H:%M:%S GMT"; |
1063 | /* Fixed size 29-byte string. Example: Sun, 06 Nov 1994 08:49:37 GMT */ | 1123 | /* Fixed size 29-byte string. Example: Sun, 06 Nov 1994 08:49:37 GMT */ |
1064 | char date_str[40]; /* using a bit larger buffer to paranoia reasons */ | 1124 | char date_str[40]; /* using a bit larger buffer to paranoia reasons */ |
1065 | |||
1066 | struct tm tm; | 1125 | struct tm tm; |
1126 | #endif | ||
1067 | const char *responseString = ""; | 1127 | const char *responseString = ""; |
1068 | const char *infoString = NULL; | 1128 | const char *infoString = NULL; |
1069 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES | 1129 | #if ENABLE_FEATURE_HTTPD_ERROR_PAGES |
@@ -1071,7 +1131,6 @@ static void send_headers(unsigned responseNum) | |||
1071 | #endif | 1131 | #endif |
1072 | unsigned len; | 1132 | unsigned len; |
1073 | unsigned i; | 1133 | unsigned i; |
1074 | time_t timer = time(NULL); | ||
1075 | 1134 | ||
1076 | for (i = 0; i < ARRAY_SIZE(http_response_type); i++) { | 1135 | for (i = 0; i < ARRAY_SIZE(http_response_type); i++) { |
1077 | if (http_response_type[i] == responseNum) { | 1136 | if (http_response_type[i] == responseNum) { |
@@ -1092,15 +1151,24 @@ static void send_headers(unsigned responseNum) | |||
1092 | * always fit into those kbytes. | 1151 | * always fit into those kbytes. |
1093 | */ | 1152 | */ |
1094 | 1153 | ||
1095 | strftime(date_str, sizeof(date_str), RFC1123FMT, gmtime_r(&timer, &tm)); | 1154 | { |
1096 | /* ^^^ using gmtime_r() instead of gmtime() to not use static data */ | 1155 | #if ENABLE_FEATURE_HTTPD_DATE |
1097 | len = sprintf(iobuf, | 1156 | time_t timer = time(NULL); |
1098 | "HTTP/1.0 %u %s\r\n" | 1157 | strftime(date_str, sizeof(date_str), RFC1123FMT, gmtime_r(&timer, &tm)); |
1158 | /* ^^^ using gmtime_r() instead of gmtime() to not use static data */ | ||
1159 | #endif | ||
1160 | len = sprintf(iobuf, | ||
1161 | "HTTP/1.1 %u %s\r\n" | ||
1162 | #if ENABLE_FEATURE_HTTPD_DATE | ||
1099 | "Date: %s\r\n" | 1163 | "Date: %s\r\n" |
1164 | #endif | ||
1100 | "Connection: close\r\n", | 1165 | "Connection: close\r\n", |
1101 | responseNum, responseString, | 1166 | responseNum, responseString |
1102 | date_str | 1167 | #if ENABLE_FEATURE_HTTPD_DATE |
1103 | ); | 1168 | ,date_str |
1169 | #endif | ||
1170 | ); | ||
1171 | } | ||
1104 | 1172 | ||
1105 | if (responseNum != HTTP_OK || found_mime_type) { | 1173 | if (responseNum != HTTP_OK || found_mime_type) { |
1106 | len += sprintf(iobuf + len, | 1174 | len += sprintf(iobuf + len, |
@@ -1120,7 +1188,7 @@ static void send_headers(unsigned responseNum) | |||
1120 | #endif | 1188 | #endif |
1121 | if (responseNum == HTTP_MOVED_TEMPORARILY) { | 1189 | if (responseNum == HTTP_MOVED_TEMPORARILY) { |
1122 | /* Responding to "GET /dir" with | 1190 | /* Responding to "GET /dir" with |
1123 | * "HTTP/1.0 302 Found" "Location: /dir/" | 1191 | * "HTTP/1.1 302 Found" "Location: /dir/" |
1124 | * - IOW, asking them to repeat with a slash. | 1192 | * - IOW, asking them to repeat with a slash. |
1125 | * Here, overflow IS possible, can't use sprintf: | 1193 | * Here, overflow IS possible, can't use sprintf: |
1126 | * mkdir test | 1194 | * mkdir test |
@@ -1152,7 +1220,9 @@ static void send_headers(unsigned responseNum) | |||
1152 | #endif | 1220 | #endif |
1153 | 1221 | ||
1154 | if (file_size != -1) { /* file */ | 1222 | if (file_size != -1) { /* file */ |
1223 | #if ENABLE_FEATURE_HTTPD_LAST_MODIFIED | ||
1155 | strftime(date_str, sizeof(date_str), RFC1123FMT, gmtime_r(&last_mod, &tm)); | 1224 | strftime(date_str, sizeof(date_str), RFC1123FMT, gmtime_r(&last_mod, &tm)); |
1225 | #endif | ||
1156 | #if ENABLE_FEATURE_HTTPD_RANGES | 1226 | #if ENABLE_FEATURE_HTTPD_RANGES |
1157 | if (responseNum == HTTP_PARTIAL_CONTENT) { | 1227 | if (responseNum == HTTP_PARTIAL_CONTENT) { |
1158 | len += sprintf(iobuf + len, | 1228 | len += sprintf(iobuf + len, |
@@ -1197,7 +1267,13 @@ static void send_headers(unsigned responseNum) | |||
1197 | #if ENABLE_FEATURE_HTTPD_RANGES | 1267 | #if ENABLE_FEATURE_HTTPD_RANGES |
1198 | "Accept-Ranges: bytes\r\n" | 1268 | "Accept-Ranges: bytes\r\n" |
1199 | #endif | 1269 | #endif |
1270 | #if ENABLE_FEATURE_HTTPD_LAST_MODIFIED | ||
1200 | "Last-Modified: %s\r\n" | 1271 | "Last-Modified: %s\r\n" |
1272 | #endif | ||
1273 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
1274 | "ETag: %s\r\n" | ||
1275 | #endif | ||
1276 | |||
1201 | /* Because of 4.4 (5), we can forgo sending of "Content-Length" | 1277 | /* Because of 4.4 (5), we can forgo sending of "Content-Length" |
1202 | * since we close connection afterwards, but it helps clients | 1278 | * since we close connection afterwards, but it helps clients |
1203 | * to e.g. estimate download times, show progress bars etc. | 1279 | * to e.g. estimate download times, show progress bars etc. |
@@ -1205,7 +1281,12 @@ static void send_headers(unsigned responseNum) | |||
1205 | * but de-facto standard is to send it (see comment below). | 1281 | * but de-facto standard is to send it (see comment below). |
1206 | */ | 1282 | */ |
1207 | "Content-Length: %"OFF_FMT"u\r\n", | 1283 | "Content-Length: %"OFF_FMT"u\r\n", |
1284 | #if ENABLE_FEATURE_HTTPD_LAST_MODIFIED | ||
1208 | date_str, | 1285 | date_str, |
1286 | #endif | ||
1287 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
1288 | G.etag, | ||
1289 | #endif | ||
1209 | file_size | 1290 | file_size |
1210 | ); | 1291 | ); |
1211 | } | 1292 | } |
@@ -1444,7 +1525,7 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1444 | count = safe_read(fromCgi_rd, rbuf + out_cnt, IOBUF_SIZE - 8); | 1525 | count = safe_read(fromCgi_rd, rbuf + out_cnt, IOBUF_SIZE - 8); |
1445 | if (count <= 0) { | 1526 | if (count <= 0) { |
1446 | /* eof (or error) and there was no "HTTP", | 1527 | /* eof (or error) and there was no "HTTP", |
1447 | * send "HTTP/1.0 200 OK\r\n", then send received data */ | 1528 | * send "HTTP/1.1 200 OK\r\n", then send received data */ |
1448 | if (out_cnt) { | 1529 | if (out_cnt) { |
1449 | full_write(STDOUT_FILENO, HTTP_200, sizeof(HTTP_200)-1); | 1530 | full_write(STDOUT_FILENO, HTTP_200, sizeof(HTTP_200)-1); |
1450 | full_write(STDOUT_FILENO, rbuf, out_cnt); | 1531 | full_write(STDOUT_FILENO, rbuf, out_cnt); |
@@ -1455,10 +1536,10 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1455 | count = 0; | 1536 | count = 0; |
1456 | /* "Status" header format is: "Status: 302 Redirected\r\n" */ | 1537 | /* "Status" header format is: "Status: 302 Redirected\r\n" */ |
1457 | if (out_cnt >= 8 && memcmp(rbuf, "Status: ", 8) == 0) { | 1538 | if (out_cnt >= 8 && memcmp(rbuf, "Status: ", 8) == 0) { |
1458 | /* send "HTTP/1.0 " */ | 1539 | /* send "HTTP/1.1 " */ |
1459 | if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9) | 1540 | if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9) |
1460 | break; | 1541 | break; |
1461 | /* skip "Status: " (including space, sending "HTTP/1.0 NNN" is wrong) */ | 1542 | /* skip "Status: " (including space, sending "HTTP/1.1 NNN" is wrong) */ |
1462 | rbuf += 8; | 1543 | rbuf += 8; |
1463 | count = out_cnt - 8; | 1544 | count = out_cnt - 8; |
1464 | out_cnt = -1; /* buffering off */ | 1545 | out_cnt = -1; /* buffering off */ |
@@ -1474,7 +1555,7 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post | |||
1474 | full_write(s, "Content-type: text/plain\r\n\r\n", 28); | 1555 | full_write(s, "Content-type: text/plain\r\n\r\n", 28); |
1475 | } | 1556 | } |
1476 | * Counter-example of valid CGI without Content-type: | 1557 | * Counter-example of valid CGI without Content-type: |
1477 | * echo -en "HTTP/1.0 302 Found\r\n" | 1558 | * echo -en "HTTP/1.1 302 Found\r\n" |
1478 | * echo -en "Location: http://www.busybox.net\r\n" | 1559 | * echo -en "Location: http://www.busybox.net\r\n" |
1479 | * echo -en "\r\n" | 1560 | * echo -en "\r\n" |
1480 | */ | 1561 | */ |
@@ -1581,7 +1662,7 @@ static void send_cgi_and_exit( | |||
1581 | /* (Older versions of bbox seem to do some decoding) */ | 1662 | /* (Older versions of bbox seem to do some decoding) */ |
1582 | setenv1("QUERY_STRING", g_query); | 1663 | setenv1("QUERY_STRING", g_query); |
1583 | putenv((char*)"SERVER_SOFTWARE=busybox httpd/"BB_VER); | 1664 | putenv((char*)"SERVER_SOFTWARE=busybox httpd/"BB_VER); |
1584 | putenv((char*)"SERVER_PROTOCOL=HTTP/1.0"); | 1665 | putenv((char*)"SERVER_PROTOCOL=HTTP/1.1"); |
1585 | putenv((char*)"GATEWAY_INTERFACE=CGI/1.1"); | 1666 | putenv((char*)"GATEWAY_INTERFACE=CGI/1.1"); |
1586 | /* Having _separate_ variables for IP and port defeats | 1667 | /* Having _separate_ variables for IP and port defeats |
1587 | * the purpose of having socket abstraction. Which "port" | 1668 | * the purpose of having socket abstraction. Which "port" |
@@ -1732,6 +1813,7 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1732 | } | 1813 | } |
1733 | } else { | 1814 | } else { |
1734 | fd = open(url, O_RDONLY); | 1815 | fd = open(url, O_RDONLY); |
1816 | /* file_size and last_mod are already populated */ | ||
1735 | } | 1817 | } |
1736 | if (fd < 0) { | 1818 | if (fd < 0) { |
1737 | if (DEBUG) | 1819 | if (DEBUG) |
@@ -1743,6 +1825,19 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1743 | send_headers_and_exit(HTTP_NOT_FOUND); | 1825 | send_headers_and_exit(HTTP_NOT_FOUND); |
1744 | log_and_exit(); | 1826 | log_and_exit(); |
1745 | } | 1827 | } |
1828 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
1829 | /* ETag is "hex(last_mod)-hex(file_size)" e.g. "5e132e20-417" */ | ||
1830 | sprintf(G.etag, "\"%llx-%llx\"", (unsigned long long)last_mod, (unsigned long long)file_size); | ||
1831 | |||
1832 | if (G.if_none_match) { | ||
1833 | if (DEBUG) | ||
1834 | bb_perror_msg("If-None-Match and file's ETag are: '%s' '%s'\n", G.if_none_match, G.etag); | ||
1835 | /* Weak ETag comparision. | ||
1836 | * If-None-Match may have many ETags but they are quoted so we can use simple substring search */ | ||
1837 | if (strstr(G.if_none_match, G.etag)) | ||
1838 | send_headers_and_exit(HTTP_NOT_MODIFIED); | ||
1839 | } | ||
1840 | #endif | ||
1746 | /* If you want to know about EPIPE below | 1841 | /* If you want to know about EPIPE below |
1747 | * (happens if you abort downloads from local httpd): */ | 1842 | * (happens if you abort downloads from local httpd): */ |
1748 | signal(SIGPIPE, SIG_IGN); | 1843 | signal(SIGPIPE, SIG_IGN); |
@@ -1878,11 +1973,12 @@ static NOINLINE void send_file_and_exit(const char *url, int what) | |||
1878 | log_and_exit(); | 1973 | log_and_exit(); |
1879 | } | 1974 | } |
1880 | 1975 | ||
1976 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
1881 | static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip) | 1977 | static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip) |
1882 | { | 1978 | { |
1883 | Htaccess_IP *cur; | 1979 | Htaccess_IP *cur; |
1884 | 1980 | ||
1885 | for (cur = ip_a_d; cur; cur = cur->next) { | 1981 | for (cur = G.ip_a_d; cur; cur = cur->next) { |
1886 | #if DEBUG | 1982 | #if DEBUG |
1887 | fprintf(stderr, | 1983 | fprintf(stderr, |
1888 | "checkPermIP: '%s' ? '%u.%u.%u.%u/%u.%u.%u.%u'\n", | 1984 | "checkPermIP: '%s' ? '%u.%u.%u.%u/%u.%u.%u.%u'\n", |
@@ -1907,6 +2003,9 @@ static void if_ip_denied_send_HTTP_FORBIDDEN_and_exit(unsigned remote_ip) | |||
1907 | if (flg_deny_all) /* depends on whether we saw "D:*" */ | 2003 | if (flg_deny_all) /* depends on whether we saw "D:*" */ |
1908 | send_headers_and_exit(HTTP_FORBIDDEN); | 2004 | send_headers_and_exit(HTTP_FORBIDDEN); |
1909 | } | 2005 | } |
2006 | #else | ||
2007 | # define if_ip_denied_send_HTTP_FORBIDDEN_and_exit(arg) ((void)0) | ||
2008 | #endif | ||
1910 | 2009 | ||
1911 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 2010 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
1912 | 2011 | ||
@@ -2160,7 +2259,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2160 | char *urlcopy; | 2259 | char *urlcopy; |
2161 | char *urlp; | 2260 | char *urlp; |
2162 | char *tptr; | 2261 | char *tptr; |
2262 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
2163 | unsigned remote_ip; | 2263 | unsigned remote_ip; |
2264 | #endif | ||
2164 | #if ENABLE_FEATURE_HTTPD_CGI | 2265 | #if ENABLE_FEATURE_HTTPD_CGI |
2165 | unsigned total_headers_len; | 2266 | unsigned total_headers_len; |
2166 | #endif | 2267 | #endif |
@@ -2182,18 +2283,30 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2182 | * (IOW, server process doesn't need to waste 8k) */ | 2283 | * (IOW, server process doesn't need to waste 8k) */ |
2183 | iobuf = xmalloc(IOBUF_SIZE); | 2284 | iobuf = xmalloc(IOBUF_SIZE); |
2184 | 2285 | ||
2286 | if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) { | ||
2287 | /* NB: can be NULL (user runs httpd -i by hand?) */ | ||
2288 | rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr->u.sa); | ||
2289 | } | ||
2290 | if (verbose) { | ||
2291 | /* this trick makes -v logging much simpler */ | ||
2292 | if (rmt_ip_str) | ||
2293 | applet_name = rmt_ip_str; | ||
2294 | if (verbose > 2) | ||
2295 | bb_simple_error_msg("connected"); | ||
2296 | } | ||
2297 | #if ENABLE_FEATURE_HTTPD_ACL_IP | ||
2185 | remote_ip = 0; | 2298 | remote_ip = 0; |
2186 | if (fromAddr->u.sa.sa_family == AF_INET) { | 2299 | if (fromAddr->u.sa.sa_family == AF_INET) { |
2187 | remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr); | 2300 | remote_ip = ntohl(fromAddr->u.sin.sin_addr.s_addr); |
2188 | } | 2301 | } |
2189 | #if ENABLE_FEATURE_IPV6 | 2302 | # if ENABLE_FEATURE_IPV6 |
2190 | # if !ENABLE_PLATFORM_MINGW32 | 2303 | # if !ENABLE_PLATFORM_MINGW32 |
2191 | if (fromAddr->u.sa.sa_family == AF_INET6 | 2304 | if (fromAddr->u.sa.sa_family == AF_INET6 |
2192 | && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0 | 2305 | && fromAddr->u.sin6.sin6_addr.s6_addr32[0] == 0 |
2193 | && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0 | 2306 | && fromAddr->u.sin6.sin6_addr.s6_addr32[1] == 0 |
2194 | && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff) | 2307 | && ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[2]) == 0xffff) |
2195 | remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]); | 2308 | remote_ip = ntohl(fromAddr->u.sin6.sin6_addr.s6_addr32[3]); |
2196 | # else | 2309 | # else |
2197 | if (fromAddr->u.sa.sa_family == AF_INET6 | 2310 | if (fromAddr->u.sa.sa_family == AF_INET6 |
2198 | && fromAddr->u.sin6.sin6_addr.s6_words[0] == 0 | 2311 | && fromAddr->u.sin6.sin6_addr.s6_words[0] == 0 |
2199 | && fromAddr->u.sin6.sin6_addr.s6_words[1] == 0 | 2312 | && fromAddr->u.sin6.sin6_addr.s6_words[1] == 0 |
@@ -2201,20 +2314,10 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2201 | && fromAddr->u.sin6.sin6_addr.s6_words[3] == 0 | 2314 | && fromAddr->u.sin6.sin6_addr.s6_words[3] == 0 |
2202 | && ntohl(*(uint32_t *)(fromAddr->u.sin6.sin6_addr.s6_words+4)) == 0xffff) | 2315 | && ntohl(*(uint32_t *)(fromAddr->u.sin6.sin6_addr.s6_words+4)) == 0xffff) |
2203 | remote_ip = ntohl(*(uint32_t *)(fromAddr->u.sin6.sin6_addr.s6_words+6)); | 2316 | remote_ip = ntohl(*(uint32_t *)(fromAddr->u.sin6.sin6_addr.s6_words+6)); |
2317 | # endif | ||
2204 | # endif | 2318 | # endif |
2205 | #endif | ||
2206 | if (ENABLE_FEATURE_HTTPD_CGI || DEBUG || verbose) { | ||
2207 | /* NB: can be NULL (user runs httpd -i by hand?) */ | ||
2208 | rmt_ip_str = xmalloc_sockaddr2dotted(&fromAddr->u.sa); | ||
2209 | } | ||
2210 | if (verbose) { | ||
2211 | /* this trick makes -v logging much simpler */ | ||
2212 | if (rmt_ip_str) | ||
2213 | applet_name = rmt_ip_str; | ||
2214 | if (verbose > 2) | ||
2215 | bb_simple_error_msg("connected"); | ||
2216 | } | ||
2217 | if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip); | 2319 | if_ip_denied_send_HTTP_FORBIDDEN_and_exit(remote_ip); |
2320 | #endif | ||
2218 | 2321 | ||
2219 | #ifdef SIGALRM | 2322 | #ifdef SIGALRM |
2220 | /* Install timeout handler. get_line() needs it. */ | 2323 | /* Install timeout handler. get_line() needs it. */ |
@@ -2512,6 +2615,13 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2512 | continue; | 2615 | continue; |
2513 | } | 2616 | } |
2514 | #endif | 2617 | #endif |
2618 | #if ENABLE_FEATURE_HTTPD_ETAG | ||
2619 | if (STRNCASECMP(iobuf, "If-None-Match:") == 0) { | ||
2620 | free(G.if_none_match); | ||
2621 | G.if_none_match = xstrdup(skip_whitespace(iobuf + sizeof("If-None-Match:") - 1)); | ||
2622 | continue; | ||
2623 | } | ||
2624 | #endif | ||
2515 | #if ENABLE_FEATURE_HTTPD_CGI | 2625 | #if ENABLE_FEATURE_HTTPD_CGI |
2516 | if (cgi_type != CGI_NONE) { | 2626 | if (cgi_type != CGI_NONE) { |
2517 | bool ct = (STRNCASECMP(iobuf, "Content-Type:") == 0); | 2627 | bool ct = (STRNCASECMP(iobuf, "Content-Type:") == 0); |
diff --git a/networking/httpd_indexcgi.c b/networking/httpd_indexcgi.c index 562cd7fbe..47b1159f4 100644 --- a/networking/httpd_indexcgi.c +++ b/networking/httpd_indexcgi.c | |||
@@ -52,43 +52,42 @@ httpd_indexcgi.c -o index.cgi | |||
52 | * to elements. Edit stylesheet to your liking and recompile. */ | 52 | * to elements. Edit stylesheet to your liking and recompile. */ |
53 | 53 | ||
54 | #define STYLE_STR \ | 54 | #define STYLE_STR \ |
55 | "<style>" "\n"\ | 55 | "<style>" \ |
56 | "table {" "\n"\ | 56 | "table {" \ |
57 | "width:100%;" "\n"\ | 57 | "width:100%;" \ |
58 | "background-color:#fff5ee;" "\n"\ | 58 | "background-color:#fff5ee;" \ |
59 | "border-width:1px;" /* 1px 1px 1px 1px; */ "\n"\ | 59 | "border-width:1px;" /* 1px 1px 1px 1px; */ \ |
60 | "border-spacing:2px;" "\n"\ | 60 | "border-spacing:2px;" \ |
61 | "border-style:solid;" /* solid solid solid solid; */ "\n"\ | 61 | "border-style:solid;" /* solid solid solid solid; */ \ |
62 | "border-color:black;" /* black black black black; */ "\n"\ | 62 | "border-color:black;" /* black black black black; */ \ |
63 | "border-collapse:collapse;" "\n"\ | 63 | "border-collapse:collapse" \ |
64 | "}" "\n"\ | 64 | "}" \ |
65 | "th {" "\n"\ | 65 | "th {" \ |
66 | "border-width:1px;" /* 1px 1px 1px 1px; */ "\n"\ | 66 | "border-width:1px;" /* 1px 1px 1px 1px; */ \ |
67 | "padding:1px;" /* 1px 1px 1px 1px; */ "\n"\ | 67 | "padding:1px;" /* 1px 1px 1px 1px; */ \ |
68 | "border-style:solid;" /* solid solid solid solid; */ "\n"\ | 68 | "border-style:solid;" /* solid solid solid solid; */ \ |
69 | "border-color:black;" /* black black black black; */ "\n"\ | 69 | "border-color:black" /* black black black black; */ \ |
70 | "}" "\n"\ | 70 | "}" \ |
71 | "td {" "\n"\ | 71 | "td {" \ |
72 | /* top right bottom left */ \ | 72 | /* top right bottom left */ \ |
73 | "border-width:0px 1px 0px 1px;" "\n"\ | 73 | "border-width:0 1px 0 1px;" \ |
74 | "padding:1px;" /* 1px 1px 1px 1px; */ "\n"\ | 74 | "padding:1px;" /* 1px 1px 1px 1px; */ \ |
75 | "border-style:solid;" /* solid solid solid solid; */ "\n"\ | 75 | "border-style:solid;" /* solid solid solid solid; */ \ |
76 | "border-color:black;" /* black black black black; */ "\n"\ | 76 | "border-color:black;" /* black black black black; */ \ |
77 | "white-space:nowrap;" "\n"\ | 77 | "white-space:nowrap" \ |
78 | "}" "\n"\ | 78 | "}" \ |
79 | "tr.hdr { background-color:#eee5de; }" "\n"\ | 79 | "tr:nth-child(odd) { background-color:#ffffff }" \ |
80 | "tr.o { background-color:#ffffff; }" "\n"\ | 80 | "tr.hdr { background-color:#eee5de }" \ |
81 | /* tr.e { ... } - for even rows (currently none) */ \ | 81 | "tr.foot { background-color:#eee5de }" \ |
82 | "tr.foot { background-color:#eee5de; }" "\n"\ | 82 | "th.cnt { text-align:left }" \ |
83 | "th.cnt { text-align:left; }" "\n"\ | 83 | "th.sz { text-align:right }" \ |
84 | "th.sz { text-align:right; }" "\n"\ | 84 | "th.dt { text-align:right }" \ |
85 | "th.dt { text-align:right; }" "\n"\ | 85 | "td.sz { text-align:right }" \ |
86 | "td.sz { text-align:right; }" "\n"\ | 86 | "td.dt { text-align:right }" \ |
87 | "td.dt { text-align:right; }" "\n"\ | 87 | "col.nm { width:98% }" \ |
88 | "col.nm { width:98%; }" "\n"\ | 88 | "col.sz { width:1% }" \ |
89 | "col.sz { width:1%; }" "\n"\ | 89 | "col.dt { width:1% }" \ |
90 | "col.dt { width:1%; }" "\n"\ | 90 | "</style>" \ |
91 | "</style>" "\n"\ | ||
92 | 91 | ||
93 | typedef struct dir_list_t { | 92 | typedef struct dir_list_t { |
94 | char *dl_name; | 93 | char *dl_name; |
@@ -220,7 +219,6 @@ int main(int argc, char *argv[]) | |||
220 | unsigned count_dirs; | 219 | unsigned count_dirs; |
221 | unsigned count_files; | 220 | unsigned count_files; |
222 | unsigned long long size_total; | 221 | unsigned long long size_total; |
223 | int odd; | ||
224 | DIR *dirp; | 222 | DIR *dirp; |
225 | char *location; | 223 | char *location; |
226 | 224 | ||
@@ -291,7 +289,6 @@ int main(int argc, char *argv[]) | |||
291 | "<col class=nm><col class=sz><col class=dt>" "\n" | 289 | "<col class=nm><col class=sz><col class=dt>" "\n" |
292 | "<tr class=hdr><th class=cnt>Name<th class=sz>Size<th class=dt>Last modified" "\n"); | 290 | "<tr class=hdr><th class=cnt>Name<th class=sz>Size<th class=dt>Last modified" "\n"); |
293 | 291 | ||
294 | odd = 0; | ||
295 | count_dirs = 0; | 292 | count_dirs = 0; |
296 | count_files = 0; | 293 | count_files = 0; |
297 | size_total = 0; | 294 | size_total = 0; |
@@ -307,9 +304,7 @@ int main(int argc, char *argv[]) | |||
307 | } else | 304 | } else |
308 | goto next; | 305 | goto next; |
309 | 306 | ||
310 | fmt_str("<tr class="); | 307 | fmt_str("<tr><td class=nm><a href='"); |
311 | *dst++ = (odd ? 'o' : 'e'); | ||
312 | fmt_str("><td class=nm><a href='"); | ||
313 | fmt_url(cdir->dl_name); /* %20 etc */ | 308 | fmt_url(cdir->dl_name); /* %20 etc */ |
314 | if (S_ISDIR(cdir->dl_mode)) | 309 | if (S_ISDIR(cdir->dl_mode)) |
315 | *dst++ = '/'; | 310 | *dst++ = '/'; |
@@ -330,7 +325,6 @@ int main(int argc, char *argv[]) | |||
330 | fmt_02u(ptm->tm_sec); | 325 | fmt_02u(ptm->tm_sec); |
331 | *dst++ = '\n'; | 326 | *dst++ = '\n'; |
332 | 327 | ||
333 | odd = 1 - odd; | ||
334 | next: | 328 | next: |
335 | cdir++; | 329 | cdir++; |
336 | } | 330 | } |
diff --git a/networking/ifconfig.c b/networking/ifconfig.c index b566d91a9..3c9a2dfb3 100644 --- a/networking/ifconfig.c +++ b/networking/ifconfig.c | |||
@@ -27,7 +27,6 @@ | |||
27 | //config:config IFCONFIG | 27 | //config:config IFCONFIG |
28 | //config: bool "ifconfig (12 kb)" | 28 | //config: bool "ifconfig (12 kb)" |
29 | //config: default y | 29 | //config: default y |
30 | //config: select PLATFORM_LINUX | ||
31 | //config: help | 30 | //config: help |
32 | //config: Ifconfig is used to configure the kernel-resident network interfaces. | 31 | //config: Ifconfig is used to configure the kernel-resident network interfaces. |
33 | //config: | 32 | //config: |
diff --git a/networking/ifenslave.c b/networking/ifenslave.c index 5e769b61d..bdb9894be 100644 --- a/networking/ifenslave.c +++ b/networking/ifenslave.c | |||
@@ -100,7 +100,6 @@ | |||
100 | //config:config IFENSLAVE | 100 | //config:config IFENSLAVE |
101 | //config: bool "ifenslave (13 kb)" | 101 | //config: bool "ifenslave (13 kb)" |
102 | //config: default y | 102 | //config: default y |
103 | //config: select PLATFORM_LINUX | ||
104 | //config: help | 103 | //config: help |
105 | //config: Userspace application to bind several interfaces | 104 | //config: Userspace application to bind several interfaces |
106 | //config: to a logical interface (use with kernel bonding driver). | 105 | //config: to a logical interface (use with kernel bonding driver). |
diff --git a/networking/ifplugd.c b/networking/ifplugd.c index fa18edd57..0d17b7d8c 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c | |||
@@ -9,7 +9,6 @@ | |||
9 | //config:config IFPLUGD | 9 | //config:config IFPLUGD |
10 | //config: bool "ifplugd (10 kb)" | 10 | //config: bool "ifplugd (10 kb)" |
11 | //config: default y | 11 | //config: default y |
12 | //config: select PLATFORM_LINUX | ||
13 | //config: help | 12 | //config: help |
14 | //config: Network interface plug detection daemon. | 13 | //config: Network interface plug detection daemon. |
15 | 14 | ||
diff --git a/networking/ip.c b/networking/ip.c index 034ee4fc8..7d3faf7f8 100644 --- a/networking/ip.c +++ b/networking/ip.c | |||
@@ -11,7 +11,6 @@ | |||
11 | //config:config IP | 11 | //config:config IP |
12 | //config: bool "ip (35 kb)" | 12 | //config: bool "ip (35 kb)" |
13 | //config: default y | 13 | //config: default y |
14 | //config: select PLATFORM_LINUX | ||
15 | //config: help | 14 | //config: help |
16 | //config: The "ip" applet is a TCP/IP interface configuration and routing | 15 | //config: The "ip" applet is a TCP/IP interface configuration and routing |
17 | //config: utility. | 16 | //config: utility. |
@@ -23,7 +22,6 @@ | |||
23 | //config: bool "ipaddr (14 kb)" | 22 | //config: bool "ipaddr (14 kb)" |
24 | //config: default y | 23 | //config: default y |
25 | //config: select FEATURE_IP_ADDRESS | 24 | //config: select FEATURE_IP_ADDRESS |
26 | //config: select PLATFORM_LINUX | ||
27 | //config: help | 25 | //config: help |
28 | //config: Short form of "ip addr" | 26 | //config: Short form of "ip addr" |
29 | //config: | 27 | //config: |
@@ -31,7 +29,6 @@ | |||
31 | //config: bool "iplink (17 kb)" | 29 | //config: bool "iplink (17 kb)" |
32 | //config: default y | 30 | //config: default y |
33 | //config: select FEATURE_IP_LINK | 31 | //config: select FEATURE_IP_LINK |
34 | //config: select PLATFORM_LINUX | ||
35 | //config: help | 32 | //config: help |
36 | //config: Short form of "ip link" | 33 | //config: Short form of "ip link" |
37 | //config: | 34 | //config: |
@@ -39,7 +36,6 @@ | |||
39 | //config: bool "iproute (15 kb)" | 36 | //config: bool "iproute (15 kb)" |
40 | //config: default y | 37 | //config: default y |
41 | //config: select FEATURE_IP_ROUTE | 38 | //config: select FEATURE_IP_ROUTE |
42 | //config: select PLATFORM_LINUX | ||
43 | //config: help | 39 | //config: help |
44 | //config: Short form of "ip route" | 40 | //config: Short form of "ip route" |
45 | //config: | 41 | //config: |
@@ -47,7 +43,6 @@ | |||
47 | //config: bool "iptunnel (9.6 kb)" | 43 | //config: bool "iptunnel (9.6 kb)" |
48 | //config: default y | 44 | //config: default y |
49 | //config: select FEATURE_IP_TUNNEL | 45 | //config: select FEATURE_IP_TUNNEL |
50 | //config: select PLATFORM_LINUX | ||
51 | //config: help | 46 | //config: help |
52 | //config: Short form of "ip tunnel" | 47 | //config: Short form of "ip tunnel" |
53 | //config: | 48 | //config: |
@@ -55,7 +50,6 @@ | |||
55 | //config: bool "iprule (10 kb)" | 50 | //config: bool "iprule (10 kb)" |
56 | //config: default y | 51 | //config: default y |
57 | //config: select FEATURE_IP_RULE | 52 | //config: select FEATURE_IP_RULE |
58 | //config: select PLATFORM_LINUX | ||
59 | //config: help | 53 | //config: help |
60 | //config: Short form of "ip rule" | 54 | //config: Short form of "ip rule" |
61 | //config: | 55 | //config: |
@@ -63,7 +57,6 @@ | |||
63 | //config: bool "ipneigh (8.3 kb)" | 57 | //config: bool "ipneigh (8.3 kb)" |
64 | //config: default y | 58 | //config: default y |
65 | //config: select FEATURE_IP_NEIGH | 59 | //config: select FEATURE_IP_NEIGH |
66 | //config: select PLATFORM_LINUX | ||
67 | //config: help | 60 | //config: help |
68 | //config: Short form of "ip neigh" | 61 | //config: Short form of "ip neigh" |
69 | //config: | 62 | //config: |
@@ -146,11 +139,13 @@ | |||
146 | //usage:#define ipaddr_trivial_usage | 139 | //usage:#define ipaddr_trivial_usage |
147 | //usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]" | 140 | //usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]" |
148 | //usage:#define ipaddr_full_usage "\n\n" | 141 | //usage:#define ipaddr_full_usage "\n\n" |
149 | //usage: "ipaddr add|change|replace|delete dev IFACE IFADDR\n" | 142 | //usage: "ipaddr add|change|replace|delete dev IFACE [CONFFLAG-LIST] IFADDR\n" |
150 | //usage: " IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n" | 143 | //usage: " IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n" |
151 | //usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n" | 144 | //usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n" |
152 | //usage: " PREFIX := ADDR[/MASK]\n" | 145 | //usage: " PREFIX := ADDR[/MASK]\n" |
153 | //usage: " SCOPE := [host|link|global|NUMBER]\n" | 146 | //usage: " SCOPE := [host|link|global|NUMBER]\n" |
147 | //usage: " CONFFLAG-LIST := [CONFFLAG-LIST] CONFFLAG\n" | ||
148 | //usage: " CONFFLAG := [noprefixroute]\n" | ||
154 | //usage: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]" | 149 | //usage: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]" |
155 | //usage: | 150 | //usage: |
156 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 | 151 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 |
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h index 40171bed9..894e380f8 100644 --- a/networking/libiproute/ip_common.h +++ b/networking/libiproute/ip_common.h | |||
@@ -33,4 +33,8 @@ int FAST_FUNC do_iplink(char **argv); | |||
33 | 33 | ||
34 | POP_SAVED_FUNCTION_VISIBILITY | 34 | POP_SAVED_FUNCTION_VISIBILITY |
35 | 35 | ||
36 | #ifndef INFINITY_LIFE_TIME | ||
37 | #define INFINITY_LIFE_TIME 0xFFFFFFFFU | ||
38 | #endif | ||
39 | |||
36 | #endif | 40 | #endif |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 86cf3beea..71e8fb6a7 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -217,6 +217,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
217 | { | 217 | { |
218 | struct ifaddrmsg *ifa = NLMSG_DATA(n); | 218 | struct ifaddrmsg *ifa = NLMSG_DATA(n); |
219 | int len = n->nlmsg_len; | 219 | int len = n->nlmsg_len; |
220 | unsigned int ifa_flags; | ||
220 | struct rtattr *rta_tb[IFA_MAX+1]; | 221 | struct rtattr *rta_tb[IFA_MAX+1]; |
221 | 222 | ||
222 | if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) | 223 | if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) |
@@ -233,6 +234,8 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
233 | //memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this | 234 | //memset(rta_tb, 0, sizeof(rta_tb)); - parse_rtattr does this |
234 | parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); | 235 | parse_rtattr(rta_tb, IFA_MAX, IFA_RTA(ifa), n->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); |
235 | 236 | ||
237 | ifa_flags = rta_tb[IFA_FLAGS] ? *(__u32*)RTA_DATA(rta_tb[IFA_FLAGS]) : ifa->ifa_flags; | ||
238 | |||
236 | if (!rta_tb[IFA_LOCAL]) | 239 | if (!rta_tb[IFA_LOCAL]) |
237 | rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; | 240 | rta_tb[IFA_LOCAL] = rta_tb[IFA_ADDRESS]; |
238 | if (!rta_tb[IFA_ADDRESS]) | 241 | if (!rta_tb[IFA_ADDRESS]) |
@@ -242,7 +245,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
242 | return 0; | 245 | return 0; |
243 | if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask) | 246 | if ((G_filter.scope ^ ifa->ifa_scope) & G_filter.scopemask) |
244 | return 0; | 247 | return 0; |
245 | if ((G_filter.flags ^ ifa->ifa_flags) & G_filter.flagmask) | 248 | if ((G_filter.flags ^ ifa_flags) & G_filter.flagmask) |
246 | return 0; | 249 | return 0; |
247 | if (G_filter.label) { | 250 | if (G_filter.label) { |
248 | const char *label; | 251 | const char *label; |
@@ -322,28 +325,32 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, | |||
322 | ); | 325 | ); |
323 | } | 326 | } |
324 | printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); | 327 | printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); |
325 | if (ifa->ifa_flags & IFA_F_SECONDARY) { | 328 | if (ifa_flags & IFA_F_SECONDARY) { |
326 | ifa->ifa_flags &= ~IFA_F_SECONDARY; | 329 | ifa_flags &= ~IFA_F_SECONDARY; |
327 | printf("secondary "); | 330 | printf("secondary "); |
328 | } | 331 | } |
329 | if (ifa->ifa_flags & IFA_F_TENTATIVE) { | 332 | if (ifa_flags & IFA_F_TENTATIVE) { |
330 | ifa->ifa_flags &= ~IFA_F_TENTATIVE; | 333 | ifa_flags &= ~IFA_F_TENTATIVE; |
331 | printf("tentative "); | 334 | printf("tentative "); |
332 | } | 335 | } |
333 | if (ifa->ifa_flags & IFA_F_DADFAILED) { | 336 | if (ifa_flags & IFA_F_DADFAILED) { |
334 | ifa->ifa_flags &= ~IFA_F_DADFAILED; | 337 | ifa_flags &= ~IFA_F_DADFAILED; |
335 | printf("dadfailed "); | 338 | printf("dadfailed "); |
336 | } | 339 | } |
337 | if (ifa->ifa_flags & IFA_F_DEPRECATED) { | 340 | if (ifa_flags & IFA_F_DEPRECATED) { |
338 | ifa->ifa_flags &= ~IFA_F_DEPRECATED; | 341 | ifa_flags &= ~IFA_F_DEPRECATED; |
339 | printf("deprecated "); | 342 | printf("deprecated "); |
340 | } | 343 | } |
341 | if (!(ifa->ifa_flags & IFA_F_PERMANENT)) { | 344 | if (!(ifa_flags & IFA_F_PERMANENT)) { |
342 | printf("dynamic "); | 345 | printf("dynamic "); |
343 | } else | 346 | } else |
344 | ifa->ifa_flags &= ~IFA_F_PERMANENT; | 347 | ifa_flags &= ~IFA_F_PERMANENT; |
345 | if (ifa->ifa_flags) | 348 | if (ifa_flags & IFA_F_NOPREFIXROUTE) { |
346 | printf("flags %02x ", ifa->ifa_flags); | 349 | ifa_flags &= ~IFA_F_NOPREFIXROUTE; |
350 | printf("noprefixroute "); | ||
351 | } | ||
352 | if (ifa_flags) | ||
353 | printf("flags %02x ", ifa_flags); | ||
347 | if (rta_tb[IFA_LABEL]) | 354 | if (rta_tb[IFA_LABEL]) |
348 | fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout); | 355 | fputs((char*)RTA_DATA(rta_tb[IFA_LABEL]), stdout); |
349 | if (rta_tb[IFA_CACHEINFO]) { | 356 | if (rta_tb[IFA_CACHEINFO]) { |
@@ -585,6 +592,14 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) | |||
585 | return 0; | 592 | return 0; |
586 | } | 593 | } |
587 | 594 | ||
595 | static void set_lifetime(unsigned int *lifetime, char *argv, const char *errmsg) | ||
596 | { | ||
597 | if (strcmp(argv, "forever") == 0) | ||
598 | *lifetime = INFINITY_LIFE_TIME; | ||
599 | else | ||
600 | *lifetime = get_u32(argv, errmsg); | ||
601 | } | ||
602 | |||
588 | static int default_scope(inet_prefix *lcl) | 603 | static int default_scope(inet_prefix *lcl) |
589 | { | 604 | { |
590 | if (lcl->family == AF_INET) { | 605 | if (lcl->family == AF_INET) { |
@@ -600,10 +615,13 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
600 | /* If you add stuff here, update ipaddr_full_usage */ | 615 | /* If you add stuff here, update ipaddr_full_usage */ |
601 | static const char option[] ALIGN1 = | 616 | static const char option[] ALIGN1 = |
602 | "peer\0""remote\0""broadcast\0""brd\0" | 617 | "peer\0""remote\0""broadcast\0""brd\0" |
603 | "anycast\0""scope\0""dev\0""label\0""local\0"; | 618 | "anycast\0""valid_lft\0""preferred_lft\0" |
619 | "scope\0""dev\0""label\0""noprefixroute\0""local\0"; | ||
604 | #define option_peer option | 620 | #define option_peer option |
605 | #define option_broadcast (option + sizeof("peer") + sizeof("remote")) | 621 | #define option_broadcast (option + sizeof("peer") + sizeof("remote")) |
606 | #define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd")) | 622 | #define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd")) |
623 | #define option_valid_lft (option_anycast + sizeof("anycast")) | ||
624 | #define option_pref_lft (option_valid_lft + sizeof("valid_lft")) | ||
607 | struct rtnl_handle rth; | 625 | struct rtnl_handle rth; |
608 | struct { | 626 | struct { |
609 | struct nlmsghdr n; | 627 | struct nlmsghdr n; |
@@ -612,6 +630,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
612 | } req; | 630 | } req; |
613 | char *d = NULL; | 631 | char *d = NULL; |
614 | char *l = NULL; | 632 | char *l = NULL; |
633 | char *valid_lftp = NULL; | ||
634 | char *preferred_lftp = NULL; | ||
615 | inet_prefix lcl; | 635 | inet_prefix lcl; |
616 | inet_prefix peer; | 636 | inet_prefix peer; |
617 | int local_len = 0; | 637 | int local_len = 0; |
@@ -619,6 +639,9 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
619 | int brd_len = 0; | 639 | int brd_len = 0; |
620 | int any_len = 0; | 640 | int any_len = 0; |
621 | bool scoped = 0; | 641 | bool scoped = 0; |
642 | __u32 valid_lft = INFINITY_LIFE_TIME; | ||
643 | __u32 preferred_lft = INFINITY_LIFE_TIME; | ||
644 | unsigned int ifa_flags = 0; | ||
622 | 645 | ||
623 | memset(&req, 0, sizeof(req)); | 646 | memset(&req, 0, sizeof(req)); |
624 | 647 | ||
@@ -630,10 +653,9 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
630 | while (*argv) { | 653 | while (*argv) { |
631 | unsigned arg = index_in_strings(option, *argv); | 654 | unsigned arg = index_in_strings(option, *argv); |
632 | /* if search fails, "local" is assumed */ | 655 | /* if search fails, "local" is assumed */ |
633 | if ((int)arg >= 0) | ||
634 | NEXT_ARG(); | ||
635 | 656 | ||
636 | if (arg <= 1) { /* peer, remote */ | 657 | if (arg <= 1) { /* peer, remote */ |
658 | NEXT_ARG(); | ||
637 | if (peer_len) { | 659 | if (peer_len) { |
638 | duparg(option_peer, *argv); | 660 | duparg(option_peer, *argv); |
639 | } | 661 | } |
@@ -646,6 +668,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
646 | req.ifa.ifa_prefixlen = peer.bitlen; | 668 | req.ifa.ifa_prefixlen = peer.bitlen; |
647 | } else if (arg <= 3) { /* broadcast, brd */ | 669 | } else if (arg <= 3) { /* broadcast, brd */ |
648 | inet_prefix addr; | 670 | inet_prefix addr; |
671 | NEXT_ARG(); | ||
649 | if (brd_len) { | 672 | if (brd_len) { |
650 | duparg(option_broadcast, *argv); | 673 | duparg(option_broadcast, *argv); |
651 | } | 674 | } |
@@ -662,6 +685,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
662 | } | 685 | } |
663 | } else if (arg == 4) { /* anycast */ | 686 | } else if (arg == 4) { /* anycast */ |
664 | inet_prefix addr; | 687 | inet_prefix addr; |
688 | NEXT_ARG(); | ||
665 | if (any_len) { | 689 | if (any_len) { |
666 | duparg(option_anycast, *argv); | 690 | duparg(option_anycast, *argv); |
667 | } | 691 | } |
@@ -671,20 +695,39 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
671 | } | 695 | } |
672 | addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); | 696 | addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); |
673 | any_len = addr.bytelen; | 697 | any_len = addr.bytelen; |
674 | } else if (arg == 5) { /* scope */ | 698 | } else if (arg == 5) { /* valid_lft */ |
699 | if (valid_lftp) | ||
700 | duparg(option_valid_lft, *argv); | ||
701 | NEXT_ARG(); | ||
702 | valid_lftp = *argv; | ||
703 | set_lifetime(&valid_lft, *argv, option_valid_lft); | ||
704 | } else if (arg == 6) { /* preferred_lft */ | ||
705 | if (preferred_lftp) | ||
706 | duparg(option_pref_lft, *argv); | ||
707 | NEXT_ARG(); | ||
708 | preferred_lftp = *argv; | ||
709 | set_lifetime(&preferred_lft, *argv, option_pref_lft); | ||
710 | } else if (arg == 7) { /* scope */ | ||
675 | uint32_t scope = 0; | 711 | uint32_t scope = 0; |
712 | NEXT_ARG(); | ||
676 | if (rtnl_rtscope_a2n(&scope, *argv)) { | 713 | if (rtnl_rtscope_a2n(&scope, *argv)) { |
677 | invarg_1_to_2(*argv, "scope"); | 714 | invarg_1_to_2(*argv, "scope"); |
678 | } | 715 | } |
679 | req.ifa.ifa_scope = scope; | 716 | req.ifa.ifa_scope = scope; |
680 | scoped = 1; | 717 | scoped = 1; |
681 | } else if (arg == 6) { /* dev */ | 718 | } else if (arg == 8) { /* dev */ |
719 | NEXT_ARG(); | ||
682 | d = *argv; | 720 | d = *argv; |
683 | } else if (arg == 7) { /* label */ | 721 | } else if (arg == 9) { /* label */ |
722 | NEXT_ARG(); | ||
684 | l = *argv; | 723 | l = *argv; |
685 | addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); | 724 | addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); |
725 | } else if (arg == 10) { /* noprefixroute */ | ||
726 | ifa_flags |= IFA_F_NOPREFIXROUTE; | ||
686 | } else { | 727 | } else { |
687 | /* local (specified or assumed) */ | 728 | /* local (specified or assumed) */ |
729 | if ((int)arg >= 0) | ||
730 | NEXT_ARG(); | ||
688 | if (local_len) { | 731 | if (local_len) { |
689 | duparg2("local", *argv); | 732 | duparg2("local", *argv); |
690 | } | 733 | } |
@@ -698,6 +741,11 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
698 | argv++; | 741 | argv++; |
699 | } | 742 | } |
700 | 743 | ||
744 | if (ifa_flags <= 0xff) | ||
745 | req.ifa.ifa_flags = ifa_flags; | ||
746 | else | ||
747 | addattr32(&req.n, sizeof(req), IFA_FLAGS, ifa_flags); | ||
748 | |||
701 | if (!d) { | 749 | if (!d) { |
702 | /* There was no "dev IFACE", but we need that */ | 750 | /* There was no "dev IFACE", but we need that */ |
703 | bb_simple_error_msg_and_die("need \"dev IFACE\""); | 751 | bb_simple_error_msg_and_die("need \"dev IFACE\""); |
@@ -740,6 +788,24 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
740 | 788 | ||
741 | req.ifa.ifa_index = xll_name_to_index(d); | 789 | req.ifa.ifa_index = xll_name_to_index(d); |
742 | 790 | ||
791 | if (valid_lftp || preferred_lftp) { | ||
792 | struct ifa_cacheinfo cinfo = {}; | ||
793 | |||
794 | if (!valid_lft) { | ||
795 | fprintf(stderr, "valid_lft is zero\n"); | ||
796 | return 1; | ||
797 | } | ||
798 | if (valid_lft < preferred_lft) { | ||
799 | fprintf(stderr, "preferred_lft is greater than valid_lft\n"); | ||
800 | return 1; | ||
801 | } | ||
802 | |||
803 | cinfo.ifa_prefered = preferred_lft; | ||
804 | cinfo.ifa_valid = valid_lft; | ||
805 | addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo, | ||
806 | sizeof(cinfo)); | ||
807 | } | ||
808 | |||
743 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) | 809 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) |
744 | return 2; | 810 | return 2; |
745 | 811 | ||
diff --git a/networking/nameif.c b/networking/nameif.c index 91d50536a..854594c83 100644 --- a/networking/nameif.c +++ b/networking/nameif.c | |||
@@ -12,7 +12,6 @@ | |||
12 | //config:config NAMEIF | 12 | //config:config NAMEIF |
13 | //config: bool "nameif (6.6 kb)" | 13 | //config: bool "nameif (6.6 kb)" |
14 | //config: default y | 14 | //config: default y |
15 | //config: select PLATFORM_LINUX | ||
16 | //config: select FEATURE_SYSLOG | 15 | //config: select FEATURE_SYSLOG |
17 | //config: help | 16 | //config: help |
18 | //config: nameif is used to rename network interface by its MAC address. | 17 | //config: nameif is used to rename network interface by its MAC address. |
diff --git a/networking/netstat.c b/networking/netstat.c index c7934423b..936610f89 100644 --- a/networking/netstat.c +++ b/networking/netstat.c | |||
@@ -16,7 +16,6 @@ | |||
16 | //config:config NETSTAT | 16 | //config:config NETSTAT |
17 | //config: bool "netstat (10 kb)" | 17 | //config: bool "netstat (10 kb)" |
18 | //config: default y | 18 | //config: default y |
19 | //config: select PLATFORM_LINUX | ||
20 | //config: help | 19 | //config: help |
21 | //config: netstat prints information about the Linux networking subsystem. | 20 | //config: netstat prints information about the Linux networking subsystem. |
22 | //config: | 21 | //config: |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 0f12409f9..d721fe80c 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -43,7 +43,6 @@ | |||
43 | //config:config NTPD | 43 | //config:config NTPD |
44 | //config: bool "ntpd (22 kb)" | 44 | //config: bool "ntpd (22 kb)" |
45 | //config: default y | 45 | //config: default y |
46 | //config: select PLATFORM_LINUX | ||
47 | //config: help | 46 | //config: help |
48 | //config: The NTP client/server daemon. | 47 | //config: The NTP client/server daemon. |
49 | //config: | 48 | //config: |
@@ -337,6 +336,9 @@ typedef struct { | |||
337 | #endif | 336 | #endif |
338 | int p_fd; | 337 | int p_fd; |
339 | int datapoint_idx; | 338 | int datapoint_idx; |
339 | #if ENABLE_FEATURE_NTPD_SERVER | ||
340 | uint32_t p_refid; | ||
341 | #endif | ||
340 | uint32_t lastpkt_refid; | 342 | uint32_t lastpkt_refid; |
341 | uint8_t lastpkt_status; | 343 | uint8_t lastpkt_status; |
342 | uint8_t lastpkt_stratum; | 344 | uint8_t lastpkt_stratum; |
@@ -413,7 +415,9 @@ struct globals { | |||
413 | * in stratum 2+ packets, it's IPv4 address or 4 first bytes | 415 | * in stratum 2+ packets, it's IPv4 address or 4 first bytes |
414 | * of MD5 hash of IPv6 | 416 | * of MD5 hash of IPv6 |
415 | */ | 417 | */ |
418 | #if ENABLE_FEATURE_NTPD_SERVER | ||
416 | uint32_t refid; | 419 | uint32_t refid; |
420 | #endif | ||
417 | uint8_t ntp_status; | 421 | uint8_t ntp_status; |
418 | /* precision is defined as the larger of the resolution and time to | 422 | /* precision is defined as the larger of the resolution and time to |
419 | * read the clock, in log2 units. For instance, the precision of a | 423 | * read the clock, in log2 units. For instance, the precision of a |
@@ -836,6 +840,24 @@ reset_peer_stats(peer_t *p, double offset) | |||
836 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); | 840 | VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); |
837 | } | 841 | } |
838 | 842 | ||
843 | #if ENABLE_FEATURE_NTPD_SERVER | ||
844 | static uint32_t calculate_refid(len_and_sockaddr *lsa) | ||
845 | { | ||
846 | # if ENABLE_FEATURE_IPV6 | ||
847 | if (lsa->u.sa.sa_family == AF_INET6) { | ||
848 | md5_ctx_t md5; | ||
849 | uint32_t res[MD5_OUTSIZE / 4]; | ||
850 | |||
851 | md5_begin(&md5); | ||
852 | md5_hash(&md5, &lsa->u.sin6.sin6_addr, sizeof(lsa->u.sin6.sin6_addr)); | ||
853 | md5_end(&md5, res); | ||
854 | return res[0]; | ||
855 | } | ||
856 | # endif | ||
857 | return lsa->u.sin.sin_addr.s_addr; | ||
858 | } | ||
859 | #endif | ||
860 | |||
839 | static len_and_sockaddr* | 861 | static len_and_sockaddr* |
840 | resolve_peer_hostname(peer_t *p) | 862 | resolve_peer_hostname(peer_t *p) |
841 | { | 863 | { |
@@ -847,6 +869,9 @@ resolve_peer_hostname(peer_t *p) | |||
847 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | 869 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); |
848 | VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0) | 870 | VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0) |
849 | bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted); | 871 | bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted); |
872 | #if ENABLE_FEATURE_NTPD_SERVER | ||
873 | p->p_refid = calculate_refid(p->p_lsa); | ||
874 | #endif | ||
850 | p->dns_errors = 0; | 875 | p->dns_errors = 0; |
851 | return lsa; | 876 | return lsa; |
852 | } | 877 | } |
@@ -1764,7 +1789,10 @@ update_local_clock(peer_t *p) | |||
1764 | 1789 | ||
1765 | G.reftime = G.cur_time; | 1790 | G.reftime = G.cur_time; |
1766 | G.ntp_status = p->lastpkt_status; | 1791 | G.ntp_status = p->lastpkt_status; |
1767 | G.refid = p->lastpkt_refid; | 1792 | #if ENABLE_FEATURE_NTPD_SERVER |
1793 | /* Our current refid is the IPv4 (or md5-hashed IPv6) address of the peer we took time from: */ | ||
1794 | G.refid = p->p_refid; | ||
1795 | #endif | ||
1768 | G.rootdelay = p->lastpkt_rootdelay + p->lastpkt_delay; | 1796 | G.rootdelay = p->lastpkt_rootdelay + p->lastpkt_delay; |
1769 | dtemp = p->filter_jitter; // SQRT(SQUARE(p->filter_jitter) + SQUARE(G.cluster_jitter)); | 1797 | dtemp = p->filter_jitter; // SQRT(SQUARE(p->filter_jitter) + SQUARE(G.cluster_jitter)); |
1770 | dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP); | 1798 | dtemp += MAXD(p->filter_dispersion + FREQ_TOLERANCE * (G.cur_time - p->lastpkt_recv_time) + abs_offset, MINDISP); |
@@ -2249,11 +2277,11 @@ recv_and_process_client_pkt(void /*int fd*/) | |||
2249 | * We don't support this. | 2277 | * We don't support this. |
2250 | */ | 2278 | */ |
2251 | 2279 | ||
2252 | #if ENABLE_FEATURE_NTP_AUTH | 2280 | # if ENABLE_FEATURE_NTP_AUTH |
2253 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) | 2281 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH && size != NTP_MSGSIZE_SHA1_AUTH) |
2254 | #else | 2282 | # else |
2255 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) | 2283 | if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE_MD5_AUTH) |
2256 | #endif | 2284 | # endif |
2257 | { | 2285 | { |
2258 | char *addr; | 2286 | char *addr; |
2259 | if (size < 0) { | 2287 | if (size < 0) { |
diff --git a/networking/parse_pasv_epsv.c b/networking/parse_pasv_epsv.c index 14f4d4258..314237be6 100644 --- a/networking/parse_pasv_epsv.c +++ b/networking/parse_pasv_epsv.c | |||
@@ -38,6 +38,8 @@ int FAST_FUNC parse_pasv_epsv(char *buf) | |||
38 | * Server's IP is N1.N2.N3.N4 (we ignore it) | 38 | * Server's IP is N1.N2.N3.N4 (we ignore it) |
39 | * Server's port for data connection is P1*256+P2 */ | 39 | * Server's port for data connection is P1*256+P2 */ |
40 | ptr = strrchr(buf, ')'); | 40 | ptr = strrchr(buf, ')'); |
41 | if (!ptr) ptr = strrchr(buf, '\r'); /* for PASV responses not ending with ')' */ | ||
42 | if (!ptr) ptr = strrchr(buf, '\n'); /* for PASV responses not ending with ')' */ | ||
41 | if (ptr) *ptr = '\0'; | 43 | if (ptr) *ptr = '\0'; |
42 | 44 | ||
43 | ptr = strrchr(buf, ','); | 45 | ptr = strrchr(buf, ','); |
diff --git a/networking/ping.c b/networking/ping.c index a47342fee..47b6ab1b2 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -27,7 +27,6 @@ | |||
27 | //config:config PING | 27 | //config:config PING |
28 | //config: bool "ping (10 kb)" | 28 | //config: bool "ping (10 kb)" |
29 | //config: default y | 29 | //config: default y |
30 | //config: select PLATFORM_LINUX | ||
31 | //config: help | 30 | //config: help |
32 | //config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to | 31 | //config: ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to |
33 | //config: elicit an ICMP ECHO_RESPONSE from a host or gateway. | 32 | //config: elicit an ICMP ECHO_RESPONSE from a host or gateway. |
diff --git a/networking/route.c b/networking/route.c index e785b1da6..4d9aad6cc 100644 --- a/networking/route.c +++ b/networking/route.c | |||
@@ -27,7 +27,6 @@ | |||
27 | //config:config ROUTE | 27 | //config:config ROUTE |
28 | //config: bool "route (8.7 kb)" | 28 | //config: bool "route (8.7 kb)" |
29 | //config: default y | 29 | //config: default y |
30 | //config: select PLATFORM_LINUX | ||
31 | //config: help | 30 | //config: help |
32 | //config: Route displays or manipulates the kernel's IP routing tables. | 31 | //config: Route displays or manipulates the kernel's IP routing tables. |
33 | 32 | ||
diff --git a/networking/slattach.c b/networking/slattach.c index 659822a91..51fbc1f49 100644 --- a/networking/slattach.c +++ b/networking/slattach.c | |||
@@ -15,7 +15,6 @@ | |||
15 | //config:config SLATTACH | 15 | //config:config SLATTACH |
16 | //config: bool "slattach (6.2 kb)" | 16 | //config: bool "slattach (6.2 kb)" |
17 | //config: default y | 17 | //config: default y |
18 | //config: select PLATFORM_LINUX | ||
19 | //config: help | 18 | //config: help |
20 | //config: slattach configures serial line as SLIP network interface. | 19 | //config: slattach configures serial line as SLIP network interface. |
21 | 20 | ||
diff --git a/networking/tls.c b/networking/tls.c index 9e81afbad..c00ef5db0 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -212,8 +212,6 @@ | |||
212 | 212 | ||
213 | enum { | 213 | enum { |
214 | SHA_INSIZE = 64, | 214 | SHA_INSIZE = 64, |
215 | SHA1_OUTSIZE = 20, | ||
216 | SHA256_OUTSIZE = 32, | ||
217 | 215 | ||
218 | AES128_KEYSIZE = 16, | 216 | AES128_KEYSIZE = 16, |
219 | AES256_KEYSIZE = 32, | 217 | AES256_KEYSIZE = 32, |
diff --git a/networking/traceroute.c b/networking/traceroute.c index 06d3f19da..5068f654b 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -212,7 +212,6 @@ | |||
212 | //config:config TRACEROUTE | 212 | //config:config TRACEROUTE |
213 | //config: bool "traceroute (11 kb)" | 213 | //config: bool "traceroute (11 kb)" |
214 | //config: default y | 214 | //config: default y |
215 | //config: select PLATFORM_LINUX | ||
216 | //config: help | 215 | //config: help |
217 | //config: Utility to trace the route of IP packets. | 216 | //config: Utility to trace the route of IP packets. |
218 | //config: | 217 | //config: |
diff --git a/networking/tunctl.c b/networking/tunctl.c index a0e3926e9..0f010e196 100644 --- a/networking/tunctl.c +++ b/networking/tunctl.c | |||
@@ -12,7 +12,6 @@ | |||
12 | //config:config TUNCTL | 12 | //config:config TUNCTL |
13 | //config: bool "tunctl (6.2 kb)" | 13 | //config: bool "tunctl (6.2 kb)" |
14 | //config: default y | 14 | //config: default y |
15 | //config: select PLATFORM_LINUX | ||
16 | //config: help | 15 | //config: help |
17 | //config: tunctl creates or deletes tun devices. | 16 | //config: tunctl creates or deletes tun devices. |
18 | //config: | 17 | //config: |
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 8ef24748e..7d04bb246 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -6,7 +6,6 @@ | |||
6 | config UDHCPD | 6 | config UDHCPD |
7 | bool "udhcpd (21 kb)" | 7 | bool "udhcpd (21 kb)" |
8 | default y | 8 | default y |
9 | select PLATFORM_LINUX | ||
10 | help | 9 | help |
11 | udhcpd is a DHCP server geared primarily toward embedded systems, | 10 | udhcpd is a DHCP server geared primarily toward embedded systems, |
12 | while striving to be fully functional and RFC compliant. | 11 | while striving to be fully functional and RFC compliant. |
@@ -62,7 +61,6 @@ config DHCPRELAY | |||
62 | config UDHCPC | 61 | config UDHCPC |
63 | bool "udhcpc (24 kb)" | 62 | bool "udhcpc (24 kb)" |
64 | default y | 63 | default y |
65 | select PLATFORM_LINUX | ||
66 | help | 64 | help |
67 | udhcpc is a DHCP client geared primarily toward embedded systems, | 65 | udhcpc is a DHCP client geared primarily toward embedded systems, |
68 | while striving to be fully functional and RFC compliant. | 66 | while striving to be fully functional and RFC compliant. |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 50dfead63..e13eb3f9f 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -115,6 +115,13 @@ enum { | |||
115 | 115 | ||
116 | 116 | ||
117 | /*** Script execution code ***/ | 117 | /*** Script execution code ***/ |
118 | struct dhcp_optitem { | ||
119 | unsigned len; | ||
120 | uint8_t code; | ||
121 | uint8_t malloced; | ||
122 | uint8_t *data; | ||
123 | char *env; | ||
124 | }; | ||
118 | 125 | ||
119 | /* get a rough idea of how long an option will be (rounding up...) */ | 126 | /* get a rough idea of how long an option will be (rounding up...) */ |
120 | static const uint8_t len_of_option_as_string[] ALIGN1 = { | 127 | static const uint8_t len_of_option_as_string[] ALIGN1 = { |
@@ -186,15 +193,15 @@ static int good_hostname(const char *name) | |||
186 | #endif | 193 | #endif |
187 | 194 | ||
188 | /* Create "opt_name=opt_value" string */ | 195 | /* Create "opt_name=opt_value" string */ |
189 | static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name) | 196 | static NOINLINE char *xmalloc_optname_optval(const struct dhcp_optitem *opt_item, const struct dhcp_optflag *optflag, const char *opt_name) |
190 | { | 197 | { |
191 | unsigned upper_length; | 198 | unsigned upper_length; |
192 | int len, type, optlen; | 199 | int len, type, optlen; |
193 | char *dest, *ret; | 200 | char *dest, *ret; |
201 | uint8_t *option; | ||
194 | 202 | ||
195 | /* option points to OPT_DATA, need to go back to get OPT_LEN */ | 203 | option = opt_item->data; |
196 | len = option[-OPT_DATA + OPT_LEN]; | 204 | len = opt_item->len; |
197 | |||
198 | type = optflag->flags & OPTION_TYPE_MASK; | 205 | type = optflag->flags & OPTION_TYPE_MASK; |
199 | optlen = dhcp_option_lengths[type]; | 206 | optlen = dhcp_option_lengths[type]; |
200 | upper_length = len_of_option_as_string[type] | 207 | upper_length = len_of_option_as_string[type] |
@@ -386,11 +393,70 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ | |||
386 | return ret; | 393 | return ret; |
387 | } | 394 | } |
388 | 395 | ||
389 | static void putenvp(llist_t **envp, char *new_opt) | 396 | static void optitem_unset_env_and_free(void *item) |
390 | { | 397 | { |
391 | putenv(new_opt); | 398 | struct dhcp_optitem *opt_item = item; |
399 | bb_unsetenv_and_free(opt_item->env); | ||
400 | if (opt_item->malloced) | ||
401 | free(opt_item->data); | ||
402 | free(opt_item); | ||
403 | } | ||
404 | |||
405 | /* Used by static options (interface, siaddr, etc) */ | ||
406 | static void putenvp(char *new_opt) | ||
407 | { | ||
408 | struct dhcp_optitem *opt_item; | ||
409 | |||
410 | opt_item = xzalloc(sizeof(*opt_item)); | ||
411 | /* opt_item->code = 0, so it won't appear in concat_option's lookup */ | ||
412 | /* opt_item->malloced = 0 */ | ||
413 | /* opt_item->data = NULL */ | ||
414 | opt_item->env = new_opt; | ||
415 | llist_add_to(&client_data.envp, opt_item); | ||
392 | log2(" %s", new_opt); | 416 | log2(" %s", new_opt); |
393 | llist_add_to(envp, new_opt); | 417 | putenv(new_opt); |
418 | } | ||
419 | |||
420 | /* Support RFC3396 Long Encoded Options */ | ||
421 | static struct dhcp_optitem *concat_option(uint8_t *data, uint8_t len, uint8_t code) | ||
422 | { | ||
423 | llist_t *item; | ||
424 | struct dhcp_optitem *opt_item; | ||
425 | |||
426 | /* Check if an option with the code already exists. | ||
427 | * A possible optimization is to create a bitmap of all existing options in the packet, | ||
428 | * and iterate over the option list only if they exist. | ||
429 | * This will result in bigger code, and because dhcp packets don't have too many options it | ||
430 | * shouldn't have a big impact on performance. | ||
431 | */ | ||
432 | for (item = client_data.envp; item != NULL; item = item->link) { | ||
433 | opt_item = (struct dhcp_optitem *)item->data; | ||
434 | if (opt_item->code == code) { | ||
435 | /* This option was seen already, concatenate */ | ||
436 | uint8_t *new_data; | ||
437 | |||
438 | new_data = xmalloc(len + opt_item->len); | ||
439 | memcpy( | ||
440 | mempcpy(new_data, opt_item->data, opt_item->len), | ||
441 | data, len | ||
442 | ); | ||
443 | opt_item->len += len; | ||
444 | if (opt_item->malloced) | ||
445 | free(opt_item->data); | ||
446 | opt_item->malloced = 1; | ||
447 | opt_item->data = new_data; | ||
448 | return opt_item; | ||
449 | } | ||
450 | } | ||
451 | |||
452 | /* This is a new option, add a new dhcp_optitem to the list */ | ||
453 | opt_item = xzalloc(sizeof(*opt_item)); | ||
454 | opt_item->code = code; | ||
455 | /* opt_item->malloced = 0 */ | ||
456 | opt_item->data = data; | ||
457 | opt_item->len = len; | ||
458 | llist_add_to(&client_data.envp, opt_item); | ||
459 | return opt_item; | ||
394 | } | 460 | } |
395 | 461 | ||
396 | static const char* get_optname(uint8_t code, const struct dhcp_optflag **dh) | 462 | static const char* get_optname(uint8_t code, const struct dhcp_optflag **dh) |
@@ -403,7 +469,7 @@ static const char* get_optname(uint8_t code, const struct dhcp_optflag **dh) | |||
403 | * and they'll count as unknown options. | 469 | * and they'll count as unknown options. |
404 | */ | 470 | */ |
405 | for (*dh = dhcp_optflags; (*dh)->code && (*dh)->code < code; (*dh)++) | 471 | for (*dh = dhcp_optflags; (*dh)->code && (*dh)->code < code; (*dh)++) |
406 | continue; | 472 | continue; |
407 | 473 | ||
408 | if ((*dh)->code == code) | 474 | if ((*dh)->code == code) |
409 | return nth_string(dhcp_option_strings, (*dh - dhcp_optflags)); | 475 | return nth_string(dhcp_option_strings, (*dh - dhcp_optflags)); |
@@ -412,50 +478,54 @@ static const char* get_optname(uint8_t code, const struct dhcp_optflag **dh) | |||
412 | } | 478 | } |
413 | 479 | ||
414 | /* put all the parameters into the environment */ | 480 | /* put all the parameters into the environment */ |
415 | static llist_t *fill_envp(struct dhcp_packet *packet) | 481 | static void fill_envp(struct dhcp_packet *packet) |
416 | { | 482 | { |
417 | uint8_t *optptr; | 483 | uint8_t *optptr; |
418 | struct dhcp_scan_state scan_state; | 484 | struct dhcp_scan_state scan_state; |
419 | char *new_opt; | 485 | char *new_opt; |
420 | llist_t *envp = NULL; | ||
421 | 486 | ||
422 | putenvp(&envp, xasprintf("interface=%s", client_data.interface)); | 487 | putenvp(xasprintf("interface=%s", client_data.interface)); |
423 | 488 | ||
424 | if (!packet) | 489 | if (!packet) |
425 | return envp; | 490 | return; |
426 | 491 | ||
427 | init_scan_state(packet, &scan_state); | 492 | init_scan_state(packet, &scan_state); |
428 | 493 | ||
429 | /* Iterate over the packet options. | 494 | /* Iterate over the packet options. |
430 | * Handle each option based on whether it's an unknown / known option. | 495 | * Handle each option based on whether it's an unknown / known option. |
431 | * There may be (although unlikely) duplicate options. For now, only the last | 496 | * Long options are supported in compliance with RFC 3396. |
432 | * appearing option will be stored in the environment, and all duplicates | ||
433 | * are freed properly. | ||
434 | * Long options may be implemented in the future (see RFC 3396) if needed. | ||
435 | */ | 497 | */ |
436 | while ((optptr = udhcp_scan_options(packet, &scan_state)) != NULL) { | 498 | while ((optptr = udhcp_scan_options(packet, &scan_state)) != NULL) { |
437 | const struct dhcp_optflag *dh; | 499 | const struct dhcp_optflag *dh; |
438 | const char *opt_name; | 500 | const char *opt_name; |
501 | struct dhcp_optitem *opt_item; | ||
439 | uint8_t code = optptr[OPT_CODE]; | 502 | uint8_t code = optptr[OPT_CODE]; |
440 | uint8_t len = optptr[OPT_LEN]; | 503 | uint8_t len = optptr[OPT_LEN]; |
441 | uint8_t *data = optptr + OPT_DATA; | 504 | uint8_t *data = optptr + OPT_DATA; |
442 | 505 | ||
506 | opt_item = concat_option(data, len, code); | ||
443 | opt_name = get_optname(code, &dh); | 507 | opt_name = get_optname(code, &dh); |
444 | if (opt_name) { | 508 | if (opt_name) { |
445 | new_opt = xmalloc_optname_optval(data, dh, opt_name); | 509 | new_opt = xmalloc_optname_optval(opt_item, dh, opt_name); |
446 | if (code == DHCP_SUBNET && len == 4) { | 510 | if (opt_item->code == DHCP_SUBNET && opt_item->len == 4) { |
511 | /* Generate extra envvar for DHCP_SUBNET, $mask */ | ||
447 | uint32_t subnet; | 512 | uint32_t subnet; |
448 | putenvp(&envp, new_opt); | 513 | move_from_unaligned32(subnet, opt_item->data); |
449 | move_from_unaligned32(subnet, data); | 514 | putenvp(xasprintf("mask=%u", mton(subnet))); |
450 | new_opt = xasprintf("mask=%u", mton(subnet)); | ||
451 | } | 515 | } |
452 | } else { | 516 | } else { |
453 | unsigned ofs; | 517 | unsigned ofs; |
454 | new_opt = xmalloc(sizeof("optNNN=") + 1 + len*2); | 518 | new_opt = xmalloc(sizeof("optNNN=") + 1 + opt_item->len*2); |
455 | ofs = sprintf(new_opt, "opt%u=", code); | 519 | ofs = sprintf(new_opt, "opt%u=", opt_item->code); |
456 | bin2hex(new_opt + ofs, (char *)data, len)[0] = '\0'; | 520 | bin2hex(new_opt + ofs, (char *)opt_item->data, opt_item->len)[0] = '\0'; |
457 | } | 521 | } |
458 | putenvp(&envp, new_opt); | 522 | log2(" %s", new_opt); |
523 | putenv(new_opt); | ||
524 | /* putenv will replace the existing environment variable in case of a duplicate. | ||
525 | * Free the previous occurrence (NULL if it's the first one). | ||
526 | */ | ||
527 | free(opt_item->env); | ||
528 | opt_item->env = new_opt; | ||
459 | } | 529 | } |
460 | 530 | ||
461 | /* Export BOOTP fields. Fields we don't (yet?) export: | 531 | /* Export BOOTP fields. Fields we don't (yet?) export: |
@@ -473,41 +543,38 @@ static llist_t *fill_envp(struct dhcp_packet *packet) | |||
473 | /* Most important one: yiaddr as $ip */ | 543 | /* Most important one: yiaddr as $ip */ |
474 | new_opt = xmalloc(sizeof("ip=255.255.255.255")); | 544 | new_opt = xmalloc(sizeof("ip=255.255.255.255")); |
475 | sprint_nip(new_opt, "ip=", (uint8_t *) &packet->yiaddr); | 545 | sprint_nip(new_opt, "ip=", (uint8_t *) &packet->yiaddr); |
476 | putenvp(&envp, new_opt); | 546 | putenvp(new_opt); |
477 | 547 | ||
478 | if (packet->siaddr_nip) { | 548 | if (packet->siaddr_nip) { |
479 | /* IP address of next server to use in bootstrap */ | 549 | /* IP address of next server to use in bootstrap */ |
480 | new_opt = xmalloc(sizeof("siaddr=255.255.255.255")); | 550 | new_opt = xmalloc(sizeof("siaddr=255.255.255.255")); |
481 | sprint_nip(new_opt, "siaddr=", (uint8_t *) &packet->siaddr_nip); | 551 | sprint_nip(new_opt, "siaddr=", (uint8_t *) &packet->siaddr_nip); |
482 | putenvp(&envp, new_opt); | 552 | putenvp(new_opt); |
483 | } | 553 | } |
484 | if (packet->gateway_nip) { | 554 | if (packet->gateway_nip) { |
485 | /* IP address of DHCP relay agent */ | 555 | /* IP address of DHCP relay agent */ |
486 | new_opt = xmalloc(sizeof("giaddr=255.255.255.255")); | 556 | new_opt = xmalloc(sizeof("giaddr=255.255.255.255")); |
487 | sprint_nip(new_opt, "giaddr=", (uint8_t *) &packet->gateway_nip); | 557 | sprint_nip(new_opt, "giaddr=", (uint8_t *) &packet->gateway_nip); |
488 | putenvp(&envp, new_opt); | 558 | putenvp(new_opt); |
489 | } | 559 | } |
490 | if (!(scan_state.overload & FILE_FIELD) && packet->file[0]) { | 560 | if (!(scan_state.overload & FILE_FIELD) && packet->file[0]) { |
491 | /* watch out for invalid packets */ | 561 | /* watch out for invalid packets */ |
492 | new_opt = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); | 562 | new_opt = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); |
493 | putenvp(&envp, new_opt); | 563 | putenvp(new_opt); |
494 | } | 564 | } |
495 | if (!(scan_state.overload & SNAME_FIELD) && packet->sname[0]) { | 565 | if (!(scan_state.overload & SNAME_FIELD) && packet->sname[0]) { |
496 | /* watch out for invalid packets */ | 566 | /* watch out for invalid packets */ |
497 | new_opt = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); | 567 | new_opt = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); |
498 | putenvp(&envp, new_opt); | 568 | putenvp(new_opt); |
499 | } | 569 | } |
500 | |||
501 | return envp; | ||
502 | } | 570 | } |
503 | 571 | ||
504 | /* Call a script with a par file and env vars */ | 572 | /* Call a script with a par file and env vars */ |
505 | static void udhcp_run_script(struct dhcp_packet *packet, const char *name) | 573 | static void udhcp_run_script(struct dhcp_packet *packet, const char *name) |
506 | { | 574 | { |
507 | llist_t *envp; | ||
508 | char *argv[3]; | 575 | char *argv[3]; |
509 | 576 | ||
510 | envp = fill_envp(packet); | 577 | fill_envp(packet); |
511 | 578 | ||
512 | /* call script */ | 579 | /* call script */ |
513 | log1("executing %s %s", client_data.script, name); | 580 | log1("executing %s %s", client_data.script, name); |
@@ -517,7 +584,8 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name) | |||
517 | spawn_and_wait(argv); | 584 | spawn_and_wait(argv); |
518 | 585 | ||
519 | /* Free all allocated environment variables */ | 586 | /* Free all allocated environment variables */ |
520 | llist_free(envp, (void (*)(void *))bb_unsetenv_and_free); | 587 | llist_free(client_data.envp, optitem_unset_env_and_free); |
588 | client_data.envp = NULL; | ||
521 | } | 589 | } |
522 | 590 | ||
523 | 591 | ||
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index b407a6cdb..7ad01ea8f 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h | |||
@@ -21,6 +21,7 @@ struct client_data_t { | |||
21 | uint8_t *vendorclass; /* Optional vendor class-id to use */ | 21 | uint8_t *vendorclass; /* Optional vendor class-id to use */ |
22 | uint8_t *hostname; /* Optional hostname to use */ | 22 | uint8_t *hostname; /* Optional hostname to use */ |
23 | uint8_t *fqdn; /* Optional fully qualified domain name to use */ | 23 | uint8_t *fqdn; /* Optional fully qualified domain name to use */ |
24 | llist_t *envp; /* list of DHCP options used for env vars */ | ||
24 | 25 | ||
25 | unsigned first_secs; | 26 | unsigned first_secs; |
26 | unsigned last_secs; | 27 | unsigned last_secs; |
diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c index 752c0a863..eab4da68b 100644 --- a/networking/udhcp/domain_codec.c +++ b/networking/udhcp/domain_codec.c | |||
@@ -10,10 +10,14 @@ | |||
10 | # define _GNU_SOURCE | 10 | # define _GNU_SOURCE |
11 | # define FAST_FUNC /* nothing */ | 11 | # define FAST_FUNC /* nothing */ |
12 | # define xmalloc malloc | 12 | # define xmalloc malloc |
13 | # define xzalloc(s) calloc(s, 1) | ||
14 | # define xstrdup strdup | ||
15 | # define xrealloc realloc | ||
13 | # include <stdlib.h> | 16 | # include <stdlib.h> |
14 | # include <stdint.h> | 17 | # include <stdint.h> |
15 | # include <string.h> | 18 | # include <string.h> |
16 | # include <stdio.h> | 19 | # include <stdio.h> |
20 | # include <ctype.h> | ||
17 | #else | 21 | #else |
18 | # include "common.h" | 22 | # include "common.h" |
19 | #endif | 23 | #endif |
@@ -26,86 +30,77 @@ | |||
26 | 30 | ||
27 | 31 | ||
28 | /* Expand a RFC1035-compressed list of domain names "cstr", of length "clen"; | 32 | /* Expand a RFC1035-compressed list of domain names "cstr", of length "clen"; |
29 | * returns a newly allocated string containing the space-separated domains, | 33 | * return a newly allocated string containing the space-separated domains, |
30 | * prefixed with the contents of string pre, or NULL if an error occurs. | 34 | * prefixed with the contents of string pre, or NULL if an error occurs. |
31 | */ | 35 | */ |
32 | char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) | 36 | char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) |
33 | { | 37 | { |
34 | char *ret = ret; /* for compiler */ | 38 | char *ret, *end; |
35 | char *dst = NULL; | 39 | unsigned len, crtpos, retpos, depth; |
36 | 40 | ||
37 | /* We make two passes over the cstr string. First, we compute | 41 | crtpos = retpos = depth = 0; |
38 | * how long the resulting string would be. Then we allocate a | 42 | len = strlen(pre); |
39 | * new buffer of the required length, and fill it in with the | 43 | end = ret = xstrdup(pre); |
40 | * expanded content. The advantage of this approach is not | 44 | |
41 | * having to deal with requiring callers to supply their own | 45 | /* Scan the string once, allocating new memory as needed */ |
42 | * buffer, then having to check if it's sufficiently large, etc. | 46 | while (crtpos < clen) { |
43 | */ | ||
44 | while (1) { | ||
45 | /* note: "return NULL" below are leak-safe since | ||
46 | * dst isn't allocated yet */ | ||
47 | const uint8_t *c; | 47 | const uint8_t *c; |
48 | unsigned crtpos, retpos, depth, len; | 48 | c = cstr + crtpos; |
49 | 49 | ||
50 | crtpos = retpos = depth = len = 0; | 50 | if ((*c & NS_CMPRSFLGS) == NS_CMPRSFLGS) { |
51 | while (crtpos < clen) { | 51 | /* pointer */ |
52 | c = cstr + crtpos; | 52 | if (crtpos + 2 > clen) /* no offset to jump to? abort */ |
53 | goto error; | ||
54 | if (retpos == 0) /* toplevel? save return spot */ | ||
55 | retpos = crtpos + 2; | ||
56 | depth++; | ||
57 | crtpos = ((c[0] << 8) | c[1]) & 0x3fff; /* jump */ | ||
58 | } else if (*c) { | ||
59 | unsigned label_len; | ||
60 | /* label */ | ||
61 | if (crtpos + *c + 1 > clen) /* label too long? abort */ | ||
62 | goto error; | ||
63 | ret = xrealloc(ret, len + *c + 1); | ||
64 | /* \3com ---> "com." */ | ||
65 | end = (char *)mempcpy(ret + len, c + 1, *c); | ||
66 | *end = '.'; | ||
53 | 67 | ||
54 | if ((*c & NS_CMPRSFLGS) == NS_CMPRSFLGS) { | 68 | label_len = *c + 1; |
55 | /* pointer */ | 69 | len += label_len; |
56 | if (crtpos + 2 > clen) /* no offset to jump to? abort */ | 70 | crtpos += label_len; |
57 | return NULL; | 71 | } else { |
58 | if (retpos == 0) /* toplevel? save return spot */ | 72 | /* NUL: end of current domain name */ |
59 | retpos = crtpos + 2; | 73 | if (retpos == 0) { |
60 | depth++; | 74 | /* toplevel? keep going */ |
61 | crtpos = ((c[0] & 0x3f) << 8) | c[1]; /* jump */ | 75 | crtpos++; |
62 | } else if (*c) { | ||
63 | /* label */ | ||
64 | if (crtpos + *c + 1 > clen) /* label too long? abort */ | ||
65 | return NULL; | ||
66 | if (dst) | ||
67 | /* \3com ---> "com." */ | ||
68 | ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.'; | ||
69 | len += *c + 1; | ||
70 | crtpos += *c + 1; | ||
71 | } else { | 76 | } else { |
72 | /* NUL: end of current domain name */ | 77 | /* return to toplevel saved spot */ |
73 | if (retpos == 0) { | 78 | crtpos = retpos; |
74 | /* toplevel? keep going */ | 79 | retpos = depth = 0; |
75 | crtpos++; | ||
76 | } else { | ||
77 | /* return to toplevel saved spot */ | ||
78 | crtpos = retpos; | ||
79 | retpos = depth = 0; | ||
80 | } | ||
81 | if (dst && len != 0) | ||
82 | /* \4host\3com\0\4host and we are at \0: | ||
83 | * \3com was converted to "com.", change dot to space. | ||
84 | */ | ||
85 | dst[len - 1] = ' '; | ||
86 | } | 80 | } |
87 | 81 | ||
88 | if (depth > NS_MAXDNSRCH /* too many jumps? abort, it's a loop */ | 82 | if (len != 0) { |
89 | || len > NS_MAXDNAME * NS_MAXDNSRCH /* result too long? abort */ | 83 | /* \4host\3com\0\4host and we are at \0: |
90 | ) { | 84 | * \3com was converted to "com.", change dot to space. |
91 | return NULL; | 85 | */ |
86 | ret[len - 1] = ' '; | ||
92 | } | 87 | } |
93 | } | 88 | } |
94 | 89 | ||
95 | if (!len) /* expanded string has 0 length? abort */ | 90 | if (depth > NS_MAXDNSRCH /* too many jumps? abort, it's a loop */ |
96 | return NULL; | 91 | || len > NS_MAXDNAME * NS_MAXDNSRCH /* result too long? abort */ |
97 | 92 | ) { | |
98 | if (!dst) { /* first pass? */ | 93 | goto error; |
99 | /* allocate dst buffer and copy pre */ | ||
100 | unsigned plen = strlen(pre); | ||
101 | ret = xmalloc(plen + len); | ||
102 | dst = stpcpy(ret, pre); | ||
103 | } else { | ||
104 | dst[len - 1] = '\0'; | ||
105 | break; | ||
106 | } | 94 | } |
107 | } | 95 | } |
108 | 96 | ||
97 | if (ret == end) { /* expanded string is empty? abort */ | ||
98 | error: | ||
99 | free(ret); | ||
100 | return NULL; | ||
101 | } | ||
102 | |||
103 | *end = '\0'; | ||
109 | return ret; | 104 | return ret; |
110 | } | 105 | } |
111 | 106 | ||
@@ -115,42 +110,40 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) | |||
115 | */ | 110 | */ |
116 | static uint8_t *convert_dname(const char *src, int *retlen) | 111 | static uint8_t *convert_dname(const char *src, int *retlen) |
117 | { | 112 | { |
118 | uint8_t c, *res, *lenptr, *dst; | 113 | uint8_t *res, *lenptr, *dst; |
119 | int len; | ||
120 | 114 | ||
121 | res = xmalloc(strlen(src) + 2); | 115 | res = xzalloc(strlen(src) + 2); |
122 | dst = lenptr = res; | 116 | dst = lenptr = res; |
123 | dst++; | 117 | dst++; |
124 | 118 | ||
125 | for (;;) { | 119 | for (;;) { |
120 | uint8_t c; | ||
121 | int len; | ||
122 | |||
126 | c = (uint8_t)*src++; | 123 | c = (uint8_t)*src++; |
127 | if (c == '.' || c == '\0') { /* end of label */ | 124 | if (c == '.' || c == '\0') { /* end of label */ |
128 | len = dst - lenptr - 1; | 125 | len = dst - lenptr - 1; |
129 | /* label too long, too short, or two '.'s in a row? abort */ | 126 | /* label too long, too short, or two '.'s in a row (len will be 0) */ |
130 | if (len > NS_MAXLABEL || len == 0 || (c == '.' && *src == '.')) { | 127 | if (len > NS_MAXLABEL || len == 0) |
131 | free(res); | 128 | goto error; |
132 | *retlen = 0; | 129 | |
133 | return NULL; | ||
134 | } | ||
135 | *lenptr = len; | 130 | *lenptr = len; |
136 | if (c == '\0' || *src == '\0') /* "" or ".": end of src */ | 131 | if (c == '\0' || *src == '\0') /* "" or ".": end of src */ |
137 | break; | 132 | break; |
138 | lenptr = dst++; | 133 | lenptr = dst++; |
139 | continue; | 134 | continue; |
140 | } | 135 | } |
141 | if (c >= 'A' && c <= 'Z') /* uppercase? convert to lower */ | 136 | *dst++ = tolower(c); |
142 | c += ('a' - 'A'); | ||
143 | *dst++ = c; | ||
144 | } | 137 | } |
145 | 138 | ||
146 | if (dst - res >= NS_MAXCDNAME) { /* dname too long? abort */ | 139 | *retlen = dst + 1 - res; |
140 | if (*retlen > NS_MAXCDNAME) { /* dname too long? abort */ | ||
141 | error: | ||
147 | free(res); | 142 | free(res); |
148 | *retlen = 0; | 143 | *retlen = 0; |
149 | return NULL; | 144 | return NULL; |
150 | } | 145 | } |
151 | 146 | ||
152 | *dst++ = 0; | ||
153 | *retlen = dst - res; | ||
154 | return res; | 147 | return res; |
155 | } | 148 | } |
156 | 149 | ||
@@ -245,6 +238,7 @@ int main(int argc, char **argv) | |||
245 | printf("test4:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\5", "")); | 238 | printf("test4:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\5", "")); |
246 | printf("test5:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\5\1z\xC0\xA", "")); | 239 | printf("test5:'%s'\n", DNAME_DEC("\4host\3com\0\xC0\5\1z\xC0\xA", "")); |
247 | 240 | ||
241 | #if 0 | ||
248 | #define DNAME_ENC(cache,source,lenp) dname_enc((uint8_t*)(cache), sizeof(cache), (source), (lenp)) | 242 | #define DNAME_ENC(cache,source,lenp) dname_enc((uint8_t*)(cache), sizeof(cache), (source), (lenp)) |
249 | encoded = dname_enc(NULL, 0, "test.net", &len); | 243 | encoded = dname_enc(NULL, 0, "test.net", &len); |
250 | printf("test6:'%s' len:%d\n", dname_dec(encoded, len, ""), len); | 244 | printf("test6:'%s' len:%d\n", dname_dec(encoded, len, ""), len); |
@@ -252,6 +246,13 @@ int main(int argc, char **argv) | |||
252 | printf("test7:'%s' len:%d\n", dname_dec(encoded, len, ""), len); | 246 | printf("test7:'%s' len:%d\n", dname_dec(encoded, len, ""), len); |
253 | encoded = DNAME_ENC("\4test\3net\0", "test.net", &len); | 247 | encoded = DNAME_ENC("\4test\3net\0", "test.net", &len); |
254 | printf("test8:'%s' len:%d\n", dname_dec(encoded, len, ""), len); | 248 | printf("test8:'%s' len:%d\n", dname_dec(encoded, len, ""), len); |
249 | #endif | ||
250 | |||
251 | encoded = dname_enc("test.net", &len); | ||
252 | printf("test6:'%s' len:%d\n", dname_dec(encoded, len, ""), len); | ||
253 | encoded = dname_enc("test.host.com", &len); | ||
254 | printf("test7:'%s' len:%d\n", dname_dec(encoded, len, ""), len); | ||
255 | |||
255 | return 0; | 256 | return 0; |
256 | } | 257 | } |
257 | #endif | 258 | #endif |
diff --git a/networking/vconfig.c b/networking/vconfig.c index 3cc5f2460..4f1fbe280 100644 --- a/networking/vconfig.c +++ b/networking/vconfig.c | |||
@@ -9,7 +9,6 @@ | |||
9 | //config:config VCONFIG | 9 | //config:config VCONFIG |
10 | //config: bool "vconfig (2.3 kb)" | 10 | //config: bool "vconfig (2.3 kb)" |
11 | //config: default y | 11 | //config: default y |
12 | //config: select PLATFORM_LINUX | ||
13 | //config: help | 12 | //config: help |
14 | //config: Creates, removes, and configures VLAN interfaces | 13 | //config: Creates, removes, and configures VLAN interfaces |
15 | 14 | ||
diff --git a/networking/zcip.c b/networking/zcip.c index 134dfb2df..311dfbe4c 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -16,7 +16,6 @@ | |||
16 | //config:config ZCIP | 16 | //config:config ZCIP |
17 | //config: bool "zcip (8.4 kb)" | 17 | //config: bool "zcip (8.4 kb)" |
18 | //config: default y | 18 | //config: default y |
19 | //config: select PLATFORM_LINUX | ||
20 | //config: select FEATURE_SYSLOG | 19 | //config: select FEATURE_SYSLOG |
21 | //config: help | 20 | //config: help |
22 | //config: ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. | 21 | //config: ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. |