diff options
author | Ron Yorston <rmy@pobox.com> | 2012-03-22 15:21:20 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2012-03-22 15:21:20 +0000 |
commit | 0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2 (patch) | |
tree | 6709ddd6071a9c238ba69233540bbcfe560c6a44 /networking | |
parent | 67758035a4fe040c6ac69b39d61bcd6bddd7b827 (diff) | |
parent | 56a3b82e9692a25ef9c9269e88feac0d579ce8e8 (diff) | |
download | busybox-w32-0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2.tar.gz busybox-w32-0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2.tar.bz2 busybox-w32-0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2.zip |
Merge commit '56a3b82e9692a25ef9c9269e88feac0d579ce8e8' into merge
Conflicts:
coreutils/ls.c
include/platform.h
libbb/bb_basename.c
Diffstat (limited to 'networking')
-rw-r--r-- | networking/ftpgetput.c | 7 | ||||
-rw-r--r-- | networking/httpd.c | 2 | ||||
-rw-r--r-- | networking/inetd.c | 5 | ||||
-rw-r--r-- | networking/ntpd.c | 4 | ||||
-rw-r--r-- | networking/traceroute.c | 61 | ||||
-rw-r--r-- | networking/udhcp/Config.src | 8 | ||||
-rw-r--r-- | networking/udhcp/common.c | 8 | ||||
-rw-r--r-- | networking/udhcp/common.h | 2 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 57 | ||||
-rw-r--r-- | networking/udhcp/files.c | 6 |
10 files changed, 116 insertions, 44 deletions
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index 66316e21f..f63df55f4 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c | |||
@@ -60,7 +60,7 @@ struct globals { | |||
60 | FILE *control_stream; | 60 | FILE *control_stream; |
61 | int verbose_flag; | 61 | int verbose_flag; |
62 | int do_continue; | 62 | int do_continue; |
63 | char buf[1]; /* actually [BUFSZ] */ | 63 | char buf[4]; /* actually [BUFSZ] */ |
64 | } FIX_ALIASING; | 64 | } FIX_ALIASING; |
65 | #define G (*(struct globals*)&bb_common_bufsiz1) | 65 | #define G (*(struct globals*)&bb_common_bufsiz1) |
66 | enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; | 66 | enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; |
@@ -105,7 +105,7 @@ static int ftpcmd(const char *s1, const char *s2) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | do { | 107 | do { |
108 | strcpy(buf, "EOF"); | 108 | strcpy(buf, "EOF"); /* for ftp_die */ |
109 | if (fgets(buf, BUFSZ - 2, control_stream) == NULL) { | 109 | if (fgets(buf, BUFSZ - 2, control_stream) == NULL) { |
110 | ftp_die(NULL); | 110 | ftp_die(NULL); |
111 | } | 111 | } |
@@ -316,7 +316,6 @@ static const char ftpgetput_longopts[] ALIGN1 = | |||
316 | int ftpgetput_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 316 | int ftpgetput_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
317 | int ftpgetput_main(int argc UNUSED_PARAM, char **argv) | 317 | int ftpgetput_main(int argc UNUSED_PARAM, char **argv) |
318 | { | 318 | { |
319 | unsigned opt; | ||
320 | const char *port = "ftp"; | 319 | const char *port = "ftp"; |
321 | /* socket to ftp server */ | 320 | /* socket to ftp server */ |
322 | 321 | ||
@@ -345,7 +344,7 @@ int ftpgetput_main(int argc UNUSED_PARAM, char **argv) | |||
345 | applet_long_options = ftpgetput_longopts; | 344 | applet_long_options = ftpgetput_longopts; |
346 | #endif | 345 | #endif |
347 | opt_complementary = "-2:vv:cc"; /* must have 2 to 3 params; -v and -c count */ | 346 | opt_complementary = "-2:vv:cc"; /* must have 2 to 3 params; -v and -c count */ |
348 | opt = getopt32(argv, "cvu:p:P:", &user, &password, &port, | 347 | getopt32(argv, "cvu:p:P:", &user, &password, &port, |
349 | &verbose_flag, &do_continue); | 348 | &verbose_flag, &do_continue); |
350 | argv += optind; | 349 | argv += optind; |
351 | 350 | ||
diff --git a/networking/httpd.c b/networking/httpd.c index d6157aca2..d77342a2a 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -2424,7 +2424,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) | |||
2424 | salt[0] = '$'; | 2424 | salt[0] = '$'; |
2425 | salt[1] = '1'; | 2425 | salt[1] = '1'; |
2426 | salt[2] = '$'; | 2426 | salt[2] = '$'; |
2427 | crypt_make_salt(salt + 3, 4, 0); | 2427 | crypt_make_salt(salt + 3, 4); |
2428 | puts(pw_encrypt(pass, salt, 1)); | 2428 | puts(pw_encrypt(pass, salt, 1)); |
2429 | return 0; | 2429 | return 0; |
2430 | } | 2430 | } |
diff --git a/networking/inetd.c b/networking/inetd.c index 226a6491c..58ae089d1 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -1164,12 +1164,17 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) | |||
1164 | sigaddset(&sa.sa_mask, SIGALRM); | 1164 | sigaddset(&sa.sa_mask, SIGALRM); |
1165 | sigaddset(&sa.sa_mask, SIGCHLD); | 1165 | sigaddset(&sa.sa_mask, SIGCHLD); |
1166 | sigaddset(&sa.sa_mask, SIGHUP); | 1166 | sigaddset(&sa.sa_mask, SIGHUP); |
1167 | //FIXME: explain why no SA_RESTART | ||
1168 | //FIXME: retry_network_setup is unsafe to run in signal handler (many reasons)! | ||
1167 | sa.sa_handler = retry_network_setup; | 1169 | sa.sa_handler = retry_network_setup; |
1168 | sigaction_set(SIGALRM, &sa); | 1170 | sigaction_set(SIGALRM, &sa); |
1171 | //FIXME: reread_config_file is unsafe to run in signal handler(many reasons)! | ||
1169 | sa.sa_handler = reread_config_file; | 1172 | sa.sa_handler = reread_config_file; |
1170 | sigaction_set(SIGHUP, &sa); | 1173 | sigaction_set(SIGHUP, &sa); |
1174 | //FIXME: reap_child is unsafe to run in signal handler (uses stdio)! | ||
1171 | sa.sa_handler = reap_child; | 1175 | sa.sa_handler = reap_child; |
1172 | sigaction_set(SIGCHLD, &sa); | 1176 | sigaction_set(SIGCHLD, &sa); |
1177 | //FIXME: clean_up_and_exit is unsafe to run in signal handler (uses stdio)! | ||
1173 | sa.sa_handler = clean_up_and_exit; | 1178 | sa.sa_handler = clean_up_and_exit; |
1174 | sigaction_set(SIGTERM, &sa); | 1179 | sigaction_set(SIGTERM, &sa); |
1175 | sa.sa_handler = clean_up_and_exit; | 1180 | sa.sa_handler = clean_up_and_exit; |
diff --git a/networking/ntpd.c b/networking/ntpd.c index e27dbaa6b..165673a1e 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -1745,7 +1745,7 @@ static NOINLINE void | |||
1745 | recv_and_process_client_pkt(void /*int fd*/) | 1745 | recv_and_process_client_pkt(void /*int fd*/) |
1746 | { | 1746 | { |
1747 | ssize_t size; | 1747 | ssize_t size; |
1748 | uint8_t version; | 1748 | //uint8_t version; |
1749 | len_and_sockaddr *to; | 1749 | len_and_sockaddr *to; |
1750 | struct sockaddr *from; | 1750 | struct sockaddr *from; |
1751 | msg_t msg; | 1751 | msg_t msg; |
@@ -1793,7 +1793,7 @@ recv_and_process_client_pkt(void /*int fd*/) | |||
1793 | msg.m_rootdelay = d_to_sfp(G.rootdelay); | 1793 | msg.m_rootdelay = d_to_sfp(G.rootdelay); |
1794 | //simple code does not do this, fix simple code! | 1794 | //simple code does not do this, fix simple code! |
1795 | msg.m_rootdisp = d_to_sfp(G.rootdisp); | 1795 | msg.m_rootdisp = d_to_sfp(G.rootdisp); |
1796 | version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */ | 1796 | //version = (query_status & VERSION_MASK); /* ... >> VERSION_SHIFT - done below instead */ |
1797 | msg.m_refid = G.refid; // (version > (3 << VERSION_SHIFT)) ? G.refid : G.refid3; | 1797 | msg.m_refid = G.refid; // (version > (3 << VERSION_SHIFT)) ? G.refid : G.refid3; |
1798 | 1798 | ||
1799 | /* We reply from the local address packet was sent to, | 1799 | /* We reply from the local address packet was sent to, |
diff --git a/networking/traceroute.c b/networking/traceroute.c index 96f9d3472..85181ab8d 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -398,18 +398,23 @@ static len_and_sockaddr* dup_sockaddr(const len_and_sockaddr *lsa) | |||
398 | 398 | ||
399 | 399 | ||
400 | static int | 400 | static int |
401 | wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to) | 401 | wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timestamp_us, int *left_ms) |
402 | { | 402 | { |
403 | struct pollfd pfd[1]; | 403 | struct pollfd pfd[1]; |
404 | int read_len = 0; | 404 | int read_len = 0; |
405 | 405 | ||
406 | pfd[0].fd = rcvsock; | 406 | pfd[0].fd = rcvsock; |
407 | pfd[0].events = POLLIN; | 407 | pfd[0].events = POLLIN; |
408 | if (safe_poll(pfd, 1, waittime * 1000) > 0) { | 408 | if (*left_ms >= 0 && safe_poll(pfd, 1, *left_ms) > 0) { |
409 | unsigned t; | ||
410 | |||
409 | read_len = recv_from_to(rcvsock, | 411 | read_len = recv_from_to(rcvsock, |
410 | recv_pkt, sizeof(recv_pkt), | 412 | recv_pkt, sizeof(recv_pkt), |
411 | /*flags:*/ 0, | 413 | /*flags:*/ MSG_DONTWAIT, |
412 | &from_lsa->u.sa, to, from_lsa->len); | 414 | &from_lsa->u.sa, to, from_lsa->len); |
415 | t = monotonic_us(); | ||
416 | *left_ms -= (t - *timestamp_us) / 1000; | ||
417 | *timestamp_us = t; | ||
413 | } | 418 | } |
414 | 419 | ||
415 | return read_len; | 420 | return read_len; |
@@ -730,7 +735,7 @@ packet_ok(int read_len, len_and_sockaddr *from_lsa, | |||
730 | type, pr_type(type), icp->icmp6_code); | 735 | type, pr_type(type), icp->icmp6_code); |
731 | 736 | ||
732 | read_len -= sizeof(struct icmp6_hdr); | 737 | read_len -= sizeof(struct icmp6_hdr); |
733 | for (i = 0; i < read_len ; i++) { | 738 | for (i = 0; i < read_len; i++) { |
734 | if (i % 16 == 0) | 739 | if (i % 16 == 0) |
735 | printf("%04x:", i); | 740 | printf("%04x:", i); |
736 | if (i % 4 == 0) | 741 | if (i % 4 == 0) |
@@ -819,7 +824,6 @@ print_delta_ms(unsigned t1p, unsigned t2p) | |||
819 | static int | 824 | static int |
820 | common_traceroute_main(int op, char **argv) | 825 | common_traceroute_main(int op, char **argv) |
821 | { | 826 | { |
822 | int i; | ||
823 | int minpacket; | 827 | int minpacket; |
824 | int tos = 0; | 828 | int tos = 0; |
825 | int max_ttl = 30; | 829 | int max_ttl = 30; |
@@ -973,6 +977,7 @@ common_traceroute_main(int op, char **argv) | |||
973 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS | 977 | #if ENABLE_FEATURE_TRACEROUTE_SOURCE_ROUTE && defined IP_OPTIONS |
974 | if (lsrr > 0) { | 978 | if (lsrr > 0) { |
975 | unsigned char optlist[MAX_IPOPTLEN]; | 979 | unsigned char optlist[MAX_IPOPTLEN]; |
980 | unsigned size; | ||
976 | 981 | ||
977 | /* final hop */ | 982 | /* final hop */ |
978 | gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr; | 983 | gwlist[lsrr] = dest_lsa->u.sin.sin_addr.s_addr; |
@@ -982,14 +987,14 @@ common_traceroute_main(int op, char **argv) | |||
982 | optlist[0] = IPOPT_NOP; | 987 | optlist[0] = IPOPT_NOP; |
983 | /* loose source route option */ | 988 | /* loose source route option */ |
984 | optlist[1] = IPOPT_LSRR; | 989 | optlist[1] = IPOPT_LSRR; |
985 | i = lsrr * sizeof(gwlist[0]); | 990 | size = lsrr * sizeof(gwlist[0]); |
986 | optlist[2] = i + 3; | 991 | optlist[2] = size + 3; |
987 | /* pointer to LSRR addresses */ | 992 | /* pointer to LSRR addresses */ |
988 | optlist[3] = IPOPT_MINOFF; | 993 | optlist[3] = IPOPT_MINOFF; |
989 | memcpy(optlist + 4, gwlist, i); | 994 | memcpy(optlist + 4, gwlist, size); |
990 | 995 | ||
991 | if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, | 996 | if (setsockopt(sndsock, IPPROTO_IP, IP_OPTIONS, |
992 | (char *)optlist, i + sizeof(gwlist[0])) < 0) { | 997 | (char *)optlist, size + sizeof(gwlist[0])) < 0) { |
993 | bb_perror_msg_and_die("IP_OPTIONS"); | 998 | bb_perror_msg_and_die("IP_OPTIONS"); |
994 | } | 999 | } |
995 | } | 1000 | } |
@@ -1103,28 +1108,34 @@ common_traceroute_main(int op, char **argv) | |||
1103 | int unreachable = 0; /* counter */ | 1108 | int unreachable = 0; /* counter */ |
1104 | int gotlastaddr = 0; /* flags */ | 1109 | int gotlastaddr = 0; /* flags */ |
1105 | int got_there = 0; | 1110 | int got_there = 0; |
1106 | int first = 1; | ||
1107 | 1111 | ||
1108 | printf("%2d", ttl); | 1112 | printf("%2d", ttl); |
1109 | for (probe = 0; probe < nprobes; ++probe) { | 1113 | for (probe = 0; probe < nprobes; ++probe) { |
1110 | int read_len; | 1114 | int read_len; |
1111 | unsigned t1; | 1115 | unsigned t1; |
1112 | unsigned t2; | 1116 | unsigned t2; |
1117 | int left_ms; | ||
1113 | struct ip *ip; | 1118 | struct ip *ip; |
1114 | 1119 | ||
1115 | if (!first && pausemsecs > 0) | ||
1116 | usleep(pausemsecs * 1000); | ||
1117 | fflush_all(); | 1120 | fflush_all(); |
1121 | if (probe != 0 && pausemsecs > 0) | ||
1122 | usleep(pausemsecs * 1000); | ||
1118 | 1123 | ||
1119 | t1 = monotonic_us(); | ||
1120 | send_probe(++seq, ttl); | 1124 | send_probe(++seq, ttl); |
1125 | t2 = t1 = monotonic_us(); | ||
1126 | |||
1127 | left_ms = waittime * 1000; | ||
1128 | while ((read_len = wait_for_reply(from_lsa, to, &t2, &left_ms)) != 0) { | ||
1129 | int icmp_code; | ||
1130 | |||
1131 | /* Recv'ed a packet, or read error */ | ||
1132 | /* t2 = monotonic_us() - set by wait_for_reply */ | ||
1121 | 1133 | ||
1122 | first = 0; | 1134 | if (read_len < 0) |
1123 | while ((read_len = wait_for_reply(from_lsa, to)) != 0) { | 1135 | continue; |
1124 | t2 = monotonic_us(); | 1136 | icmp_code = packet_ok(read_len, from_lsa, to, seq); |
1125 | i = packet_ok(read_len, from_lsa, to, seq); | ||
1126 | /* Skip short packet */ | 1137 | /* Skip short packet */ |
1127 | if (i == 0) | 1138 | if (icmp_code == 0) |
1128 | continue; | 1139 | continue; |
1129 | 1140 | ||
1130 | if (!gotlastaddr | 1141 | if (!gotlastaddr |
@@ -1143,10 +1154,10 @@ common_traceroute_main(int op, char **argv) | |||
1143 | printf(" (%d)", ip->ip_ttl); | 1154 | printf(" (%d)", ip->ip_ttl); |
1144 | 1155 | ||
1145 | /* time exceeded in transit */ | 1156 | /* time exceeded in transit */ |
1146 | if (i == -1) | 1157 | if (icmp_code == -1) |
1147 | break; | 1158 | break; |
1148 | i--; | 1159 | icmp_code--; |
1149 | switch (i) { | 1160 | switch (icmp_code) { |
1150 | #if ENABLE_TRACEROUTE6 | 1161 | #if ENABLE_TRACEROUTE6 |
1151 | case ICMP6_DST_UNREACH_NOPORT << 8: | 1162 | case ICMP6_DST_UNREACH_NOPORT << 8: |
1152 | got_there = 1; | 1163 | got_there = 1; |
@@ -1219,16 +1230,18 @@ common_traceroute_main(int op, char **argv) | |||
1219 | ++unreachable; | 1230 | ++unreachable; |
1220 | break; | 1231 | break; |
1221 | default: | 1232 | default: |
1222 | printf(" !<%d>", i); | 1233 | printf(" !<%d>", icmp_code); |
1223 | ++unreachable; | 1234 | ++unreachable; |
1224 | break; | 1235 | break; |
1225 | } | 1236 | } |
1226 | break; | 1237 | break; |
1227 | } | 1238 | } /* while (wait and read a packet) */ |
1239 | |||
1228 | /* there was no packet at all? */ | 1240 | /* there was no packet at all? */ |
1229 | if (read_len == 0) | 1241 | if (read_len == 0) |
1230 | printf(" *"); | 1242 | printf(" *"); |
1231 | } | 1243 | } /* for (nprobes) */ |
1244 | |||
1232 | bb_putchar('\n'); | 1245 | bb_putchar('\n'); |
1233 | if (got_there | 1246 | if (got_there |
1234 | || (unreachable > 0 && unreachable >= nprobes - 1) | 1247 | || (unreachable > 0 && unreachable >= nprobes - 1) |
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 9cd8cbbae..6bfa398ea 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -113,6 +113,14 @@ config FEATURE_UDHCP_RFC3397 | |||
113 | search lists via option 119, specified in RFC 3397, | 113 | search lists via option 119, specified in RFC 3397, |
114 | and SIP servers option 120, specified in RFC 3361. | 114 | and SIP servers option 120, specified in RFC 3361. |
115 | 115 | ||
116 | config FEATURE_UDHCP_8021Q | ||
117 | bool "Support for 802.1Q VLAN parameters" | ||
118 | default y | ||
119 | depends on UDHCPD || UDHCPC | ||
120 | help | ||
121 | If selected, both client and server will support passing of VLAN | ||
122 | ID and priority via options 132 and 133 as per 802.1Q. | ||
123 | |||
116 | config UDHCPC_DEFAULT_SCRIPT | 124 | config UDHCPC_DEFAULT_SCRIPT |
117 | string "Absolute path to config script" | 125 | string "Absolute path to config script" |
118 | default "/usr/share/udhcpc/default.script" | 126 | default "/usr/share/udhcpc/default.script" |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 0a60261ab..70e34614c 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -55,6 +55,10 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
55 | { OPTION_SIP_SERVERS , 0x78 }, /* DHCP_SIP_SERVERS */ | 55 | { OPTION_SIP_SERVERS , 0x78 }, /* DHCP_SIP_SERVERS */ |
56 | #endif | 56 | #endif |
57 | { OPTION_STATIC_ROUTES , 0x79 }, /* DHCP_STATIC_ROUTES */ | 57 | { OPTION_STATIC_ROUTES , 0x79 }, /* DHCP_STATIC_ROUTES */ |
58 | #if ENABLE_FEATURE_UDHCP_8021Q | ||
59 | { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ | ||
60 | { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ | ||
61 | #endif | ||
58 | { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ | 62 | { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ |
59 | { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ | 63 | { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ |
60 | 64 | ||
@@ -118,6 +122,10 @@ const char dhcp_option_strings[] ALIGN1 = | |||
118 | // doesn't work in udhcpd.conf since OPTION_STATIC_ROUTES | 122 | // doesn't work in udhcpd.conf since OPTION_STATIC_ROUTES |
119 | // is not handled yet by "string->option" conversion code: | 123 | // is not handled yet by "string->option" conversion code: |
120 | "staticroutes" "\0"/* DHCP_STATIC_ROUTES */ | 124 | "staticroutes" "\0"/* DHCP_STATIC_ROUTES */ |
125 | #if ENABLE_FEATURE_UDHCP_8021Q | ||
126 | "vlanid" "\0" /* DHCP_VLAN_ID */ | ||
127 | "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ | ||
128 | #endif | ||
121 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ | 129 | "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ |
122 | "wpad" "\0" /* DHCP_WPAD */ | 130 | "wpad" "\0" /* DHCP_WPAD */ |
123 | ; | 131 | ; |
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index f8f18ff01..ad6991c94 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -145,6 +145,8 @@ enum { | |||
145 | //#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ | 145 | //#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ |
146 | //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ | 146 | //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ |
147 | //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ | 147 | //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ |
148 | #define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ | ||
149 | #define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ | ||
148 | //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ | 150 | //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ |
149 | //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ | 151 | //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ |
150 | #define DHCP_END 0xff | 152 | #define DHCP_END 0xff |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index ca82d37e6..510c3a1d0 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -300,6 +300,14 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
300 | uint8_t *temp; | 300 | uint8_t *temp; |
301 | uint8_t overload = 0; | 301 | uint8_t overload = 0; |
302 | 302 | ||
303 | #define BITMAP unsigned | ||
304 | #define BBITS (sizeof(BITMAP) * 8) | ||
305 | #define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1))) | ||
306 | #define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS]) | ||
307 | BITMAP found_opts[256 / BBITS]; | ||
308 | |||
309 | memset(found_opts, 0, sizeof(found_opts)); | ||
310 | |||
303 | /* We need 6 elements for: | 311 | /* We need 6 elements for: |
304 | * "interface=IFACE" | 312 | * "interface=IFACE" |
305 | * "ip=N.N.N.N" from packet->yiaddr | 313 | * "ip=N.N.N.N" from packet->yiaddr |
@@ -311,18 +319,21 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
311 | envc = 6; | 319 | envc = 6; |
312 | /* +1 element for each option, +2 for subnet option: */ | 320 | /* +1 element for each option, +2 for subnet option: */ |
313 | if (packet) { | 321 | if (packet) { |
314 | for (i = 0; dhcp_optflags[i].code; i++) { | 322 | /* note: do not search for "pad" (0) and "end" (255) options */ |
315 | if (udhcp_get_option(packet, dhcp_optflags[i].code)) { | 323 | for (i = 1; i < 255; i++) { |
316 | if (dhcp_optflags[i].code == DHCP_SUBNET) | 324 | temp = udhcp_get_option(packet, i); |
325 | if (temp) { | ||
326 | if (i == DHCP_OPTION_OVERLOAD) | ||
327 | overload = *temp; | ||
328 | else if (i == DHCP_SUBNET) | ||
317 | envc++; /* for mton */ | 329 | envc++; /* for mton */ |
318 | envc++; | 330 | envc++; |
331 | /*if (i != DHCP_MESSAGE_TYPE)*/ | ||
332 | FOUND_OPTS(i) |= BMASK(i); | ||
319 | } | 333 | } |
320 | } | 334 | } |
321 | temp = udhcp_get_option(packet, DHCP_OPTION_OVERLOAD); | ||
322 | if (temp) | ||
323 | overload = *temp; | ||
324 | } | 335 | } |
325 | curr = envp = xzalloc(sizeof(char *) * envc); | 336 | curr = envp = xzalloc(sizeof(envp[0]) * envc); |
326 | 337 | ||
327 | *curr = xasprintf("interface=%s", client_config.interface); | 338 | *curr = xasprintf("interface=%s", client_config.interface); |
328 | putenv(*curr++); | 339 | putenv(*curr++); |
@@ -337,12 +348,16 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
337 | opt_name = dhcp_option_strings; | 348 | opt_name = dhcp_option_strings; |
338 | i = 0; | 349 | i = 0; |
339 | while (*opt_name) { | 350 | while (*opt_name) { |
340 | temp = udhcp_get_option(packet, dhcp_optflags[i].code); | 351 | uint8_t code = dhcp_optflags[i].code; |
341 | if (!temp) | 352 | BITMAP *found_ptr = &FOUND_OPTS(code); |
353 | BITMAP found_mask = BMASK(code); | ||
354 | if (!(*found_ptr & found_mask)) | ||
342 | goto next; | 355 | goto next; |
356 | *found_ptr &= ~found_mask; /* leave only unknown options */ | ||
357 | temp = udhcp_get_option(packet, code); | ||
343 | *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name); | 358 | *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name); |
344 | putenv(*curr++); | 359 | putenv(*curr++); |
345 | if (dhcp_optflags[i].code == DHCP_SUBNET) { | 360 | if (code == DHCP_SUBNET) { |
346 | /* Subnet option: make things like "$ip/$mask" possible */ | 361 | /* Subnet option: make things like "$ip/$mask" possible */ |
347 | uint32_t subnet; | 362 | uint32_t subnet; |
348 | move_from_unaligned32(subnet, temp); | 363 | move_from_unaligned32(subnet, temp); |
@@ -368,6 +383,28 @@ static char **fill_envp(struct dhcp_packet *packet) | |||
368 | *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); | 383 | *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); |
369 | putenv(*curr++); | 384 | putenv(*curr++); |
370 | } | 385 | } |
386 | /* Handle unknown options */ | ||
387 | for (i = 0; i < 256;) { | ||
388 | BITMAP bitmap = FOUND_OPTS(i); | ||
389 | if (!bitmap) { | ||
390 | i += BBITS; | ||
391 | continue; | ||
392 | } | ||
393 | if (bitmap & BMASK(i)) { | ||
394 | unsigned len, ofs; | ||
395 | |||
396 | temp = udhcp_get_option(packet, i); | ||
397 | /* udhcp_get_option returns ptr to data portion, | ||
398 | * need to go back to get len | ||
399 | */ | ||
400 | len = temp[-OPT_DATA + OPT_LEN]; | ||
401 | *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); | ||
402 | ofs = sprintf(*curr, "opt%u=", i); | ||
403 | bin2hex(*curr + ofs, (void*) temp, len)[0] = '\0'; | ||
404 | putenv(*curr++); | ||
405 | } | ||
406 | i++; | ||
407 | } | ||
371 | return envp; | 408 | return envp; |
372 | } | 409 | } |
373 | 410 | ||
diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 49bcafb9c..6840f3c25 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c | |||
@@ -80,9 +80,9 @@ static const struct config_keyword keywords[] = { | |||
80 | /* keywords with no defaults must be last! */ | 80 | /* keywords with no defaults must be last! */ |
81 | {"option" , udhcp_str2optset, &server_config.options , ""}, | 81 | {"option" , udhcp_str2optset, &server_config.options , ""}, |
82 | {"opt" , udhcp_str2optset, &server_config.options , ""}, | 82 | {"opt" , udhcp_str2optset, &server_config.options , ""}, |
83 | {"notify_file" , read_str , &server_config.notify_file , ""}, | 83 | {"notify_file" , read_str , &server_config.notify_file , NULL}, |
84 | {"sname" , read_str , &server_config.sname , ""}, | 84 | {"sname" , read_str , &server_config.sname , NULL}, |
85 | {"boot_file" , read_str , &server_config.boot_file , ""}, | 85 | {"boot_file" , read_str , &server_config.boot_file , NULL}, |
86 | {"static_lease" , read_staticlease, &server_config.static_leases, ""}, | 86 | {"static_lease" , read_staticlease, &server_config.static_leases, ""}, |
87 | }; | 87 | }; |
88 | enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; | 88 | enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; |