aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2012-03-22 15:21:20 +0000
committerRon Yorston <rmy@pobox.com>2012-03-22 15:21:20 +0000
commit0d8b2c4a929ea9d3ac37499319fe0d8e7941a0c2 (patch)
tree6709ddd6071a9c238ba69233540bbcfe560c6a44 /networking
parent67758035a4fe040c6ac69b39d61bcd6bddd7b827 (diff)
parent56a3b82e9692a25ef9c9269e88feac0d579ce8e8 (diff)
downloadbusybox-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.c7
-rw-r--r--networking/httpd.c2
-rw-r--r--networking/inetd.c5
-rw-r--r--networking/ntpd.c4
-rw-r--r--networking/traceroute.c61
-rw-r--r--networking/udhcp/Config.src8
-rw-r--r--networking/udhcp/common.c8
-rw-r--r--networking/udhcp/common.h2
-rw-r--r--networking/udhcp/dhcpc.c57
-rw-r--r--networking/udhcp/files.c6
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)
66enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; 66enum { 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 =
316int ftpgetput_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 316int ftpgetput_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
317int ftpgetput_main(int argc UNUSED_PARAM, char **argv) 317int 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
1745recv_and_process_client_pkt(void /*int fd*/) 1745recv_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
400static int 400static int
401wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to) 401wait_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)
819static int 824static int
820common_traceroute_main(int op, char **argv) 825common_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
116config 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
116config UDHCPC_DEFAULT_SCRIPT 124config 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};
88enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; 88enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 };