summaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-07 01:05:47 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-07 01:05:47 +0000
commitfbd2918f5c91723063ed698026217a77a0fe565b (patch)
treecddfe351592f4a876232cf4c67c23df25bf0563c /networking
parentbb5b01c7c711dd9ffc2abf23a05ccdfbf7fc0325 (diff)
downloadbusybox-w32-fbd2918f5c91723063ed698026217a77a0fe565b.tar.gz
busybox-w32-fbd2918f5c91723063ed698026217a77a0fe565b.tar.bz2
busybox-w32-fbd2918f5c91723063ed698026217a77a0fe565b.zip
udhcp: MAC_BCAST_ADDR and blank_chaddr are in fact constant, move to rodata.
a few global variables reduced to smallints function old new delta add_lease 75 227 +152 static.blank_chaddr - 16 +16 MAC_BCAST_ADDR - 6 +6 sockfd 4 8 +4 udhcp_run_script 1153 1155 +2 state 8 5 -3 listen_mode 4 1 -3 perform_release 152 148 -4 fd 8 4 -4 blank_chaddr 16 - -16 udhcpc_main 2518 2497 -21 .rodata 131864 131832 -32 oldest_expired_lease 61 - -61 clear_lease 127 - -127 ------------------------------------------------------------------------------ (add/remove: 2/3 grow/shrink: 3/6 up/down: 180/-271) Total: -91 bytes
Diffstat (limited to 'networking')
-rw-r--r--networking/udhcp/common.c2
-rw-r--r--networking/udhcp/common.h6
-rw-r--r--networking/udhcp/dhcpc.c36
-rw-r--r--networking/udhcp/dhcpd.h83
-rw-r--r--networking/udhcp/leases.c68
-rw-r--r--networking/udhcp/options.h74
-rw-r--r--networking/udhcp/packet.c2
-rw-r--r--networking/udhcp/script.c52
-rw-r--r--networking/udhcp/serverpacket.c2
9 files changed, 169 insertions, 156 deletions
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c
index 46cc0348f..721888f6d 100644
--- a/networking/udhcp/common.c
+++ b/networking/udhcp/common.c
@@ -15,6 +15,8 @@
15#include "common.h" 15#include "common.h"
16 16
17 17
18const uint8_t MAC_BCAST_ADDR[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
19
18long uptime(void) 20long uptime(void)
19{ 21{
20 struct sysinfo info; 22 struct sysinfo info;
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h
index 00890ac1c..6c0db5b4c 100644
--- a/networking/udhcp/common.h
+++ b/networking/udhcp/common.h
@@ -14,8 +14,7 @@
14 14
15#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script" 15#define DEFAULT_SCRIPT "/usr/share/udhcpc/default.script"
16 16
17#define COMBINED_BINARY 17extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */
18
19 18
20/*** packet.h ***/ 19/*** packet.h ***/
21 20
@@ -52,7 +51,8 @@ int udhcp_get_packet(struct dhcpMessage *packet, int fd);
52uint16_t udhcp_checksum(void *addr, int count); 51uint16_t udhcp_checksum(void *addr, int count);
53int udhcp_raw_packet(struct dhcpMessage *payload, 52int udhcp_raw_packet(struct dhcpMessage *payload,
54 uint32_t source_ip, int source_port, 53 uint32_t source_ip, int source_port,
55 uint32_t dest_ip, int dest_port, uint8_t *dest_arp, int ifindex); 54 uint32_t dest_ip, int dest_port,
55 const uint8_t *dest_arp, int ifindex);
56int udhcp_kernel_packet(struct dhcpMessage *payload, 56int udhcp_kernel_packet(struct dhcpMessage *payload,
57 uint32_t source_ip, int source_port, 57 uint32_t source_ip, int source_port,
58 uint32_t dest_ip, int dest_port); 58 uint32_t dest_ip, int dest_port);
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index e8cdd79df..362e70169 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -17,22 +17,23 @@
17#include "options.h" 17#include "options.h"
18 18
19 19
20static int state;
21/* Something is definitely wrong here. IPv4 addresses 20/* Something is definitely wrong here. IPv4 addresses
22 * in variables of type long?? BTW, we use inet_ntoa() 21 * in variables of type long?? BTW, we use inet_ntoa()
23 * in the code. Manpage says that struct in_addr has a member of type long (!) 22 * in the code. Manpage says that struct in_addr has a member of type long (!)
24 * which holds IPv4 address, and the struct is passed by value (!!) 23 * which holds IPv4 address, and the struct is passed by value (!!)
25 */ 24 */
25static unsigned long timeout;
26static unsigned long requested_ip; /* = 0 */ 26static unsigned long requested_ip; /* = 0 */
27static uint32_t server_addr; 27static uint32_t server_addr;
28static unsigned long timeout;
29static int packet_num; /* = 0 */ 28static int packet_num; /* = 0 */
30static int fd = -1; 29static int sockfd = -1;
31 30
32#define LISTEN_NONE 0 31#define LISTEN_NONE 0
33#define LISTEN_KERNEL 1 32#define LISTEN_KERNEL 1
34#define LISTEN_RAW 2 33#define LISTEN_RAW 2
35static int listen_mode; 34static smallint listen_mode;
35
36static smallint state;
36 37
37struct client_config_t client_config; 38struct client_config_t client_config;
38 39
@@ -42,8 +43,10 @@ static void change_mode(int new_mode)
42{ 43{
43 DEBUG("entering %s listen mode", 44 DEBUG("entering %s listen mode",
44 new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none"); 45 new_mode ? (new_mode == 1 ? "kernel" : "raw") : "none");
45 if (fd >= 0) close(fd); 46 if (sockfd >= 0) {
46 fd = -1; 47 close(sockfd);
48 sockfd = -1;
49 }
47 listen_mode = new_mode; 50 listen_mode = new_mode;
48} 51}
49 52
@@ -111,6 +114,7 @@ static void client_background(void)
111 * If that will be properly disabled for NOMMU, client_background() 114 * If that will be properly disabled for NOMMU, client_background()
112 * will work on NOMMU too */ 115 * will work on NOMMU too */
113#else 116#else
117// chdir(/) is problematic. Imagine that e.g. pidfile name is RELATIVE! what will unlink do then, eh?
114 bb_daemonize(DAEMON_CHDIR_ROOT); 118 bb_daemonize(DAEMON_CHDIR_ROOT);
115 logmode &= ~LOGMODE_STDIO; 119 logmode &= ~LOGMODE_STDIO;
116#endif 120#endif
@@ -289,13 +293,13 @@ int udhcpc_main(int argc, char **argv)
289 tv.tv_sec = timeout - uptime(); 293 tv.tv_sec = timeout - uptime();
290 tv.tv_usec = 0; 294 tv.tv_usec = 0;
291 295
292 if (listen_mode != LISTEN_NONE && fd < 0) { 296 if (listen_mode != LISTEN_NONE && sockfd < 0) {
293 if (listen_mode == LISTEN_KERNEL) 297 if (listen_mode == LISTEN_KERNEL)
294 fd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface); 298 sockfd = listen_socket(INADDR_ANY, CLIENT_PORT, client_config.interface);
295 else 299 else
296 fd = raw_socket(client_config.ifindex); 300 sockfd = raw_socket(client_config.ifindex);
297 } 301 }
298 max_fd = udhcp_sp_fd_set(&rfds, fd); 302 max_fd = udhcp_sp_fd_set(&rfds, sockfd);
299 303
300 if (tv.tv_sec > 0) { 304 if (tv.tv_sec > 0) {
301 DEBUG("Waiting on select..."); 305 DEBUG("Waiting on select...");
@@ -342,7 +346,8 @@ int udhcpc_main(int argc, char **argv)
342 packet_num++; 346 packet_num++;
343 } else { 347 } else {
344 /* timed out, go back to init state */ 348 /* timed out, go back to init state */
345 if (state == RENEW_REQUESTED) udhcp_run_script(NULL, "deconfig"); 349 if (state == RENEW_REQUESTED)
350 udhcp_run_script(NULL, "deconfig");
346 state = INIT_SELECTING; 351 state = INIT_SELECTING;
347 timeout = now; 352 timeout = now;
348 packet_num = 0; 353 packet_num = 0;
@@ -393,12 +398,12 @@ int udhcpc_main(int argc, char **argv)
393 timeout = 0x7fffffff; 398 timeout = 0x7fffffff;
394 break; 399 break;
395 } 400 }
396 } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(fd, &rfds)) { 401 } else if (retval > 0 && listen_mode != LISTEN_NONE && FD_ISSET(sockfd, &rfds)) {
397 /* a packet is ready, read it */ 402 /* a packet is ready, read it */
398 403
399 if (listen_mode == LISTEN_KERNEL) 404 if (listen_mode == LISTEN_KERNEL)
400 len = udhcp_get_packet(&packet, fd); 405 len = udhcp_get_packet(&packet, sockfd);
401 else len = get_raw_packet(&packet, fd); 406 else len = get_raw_packet(&packet, sockfd);
402 407
403 if (len == -1 && errno != EINTR) { 408 if (len == -1 && errno != EINTR) {
404 DEBUG("error on read, %s, reopening socket", strerror(errno)); 409 DEBUG("error on read, %s, reopening socket", strerror(errno));
@@ -418,7 +423,8 @@ int udhcpc_main(int argc, char **argv)
418 continue; 423 continue;
419 } 424 }
420 425
421 if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { 426 message = get_option(&packet, DHCP_MESSAGE_TYPE);
427 if (message == NULL) {
422 bb_error_msg("cannot get option from packet - ignoring"); 428 bb_error_msg("cannot get option from packet - ignoring");
423 continue; 429 continue;
424 } 430 }
diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h
index 40959e4ae..7c4fe695a 100644
--- a/networking/udhcp/dhcpd.h
+++ b/networking/udhcp/dhcpd.h
@@ -14,81 +14,6 @@
14/* where to find the DHCP server configuration file */ 14/* where to find the DHCP server configuration file */
15#define DHCPD_CONF_FILE "/etc/udhcpd.conf" 15#define DHCPD_CONF_FILE "/etc/udhcpd.conf"
16 16
17/*****************************************************************/
18/* Do not modify below here unless you know what you are doing!! */
19/*****************************************************************/
20
21/* DHCP protocol -- see RFC 2131 */
22#define SERVER_PORT 67
23#define CLIENT_PORT 68
24
25#define DHCP_MAGIC 0x63825363
26
27/* DHCP option codes (partial list) */
28#define DHCP_PADDING 0x00
29#define DHCP_SUBNET 0x01
30#define DHCP_TIME_OFFSET 0x02
31#define DHCP_ROUTER 0x03
32#define DHCP_TIME_SERVER 0x04
33#define DHCP_NAME_SERVER 0x05
34#define DHCP_DNS_SERVER 0x06
35#define DHCP_LOG_SERVER 0x07
36#define DHCP_COOKIE_SERVER 0x08
37#define DHCP_LPR_SERVER 0x09
38#define DHCP_HOST_NAME 0x0c
39#define DHCP_BOOT_SIZE 0x0d
40#define DHCP_DOMAIN_NAME 0x0f
41#define DHCP_SWAP_SERVER 0x10
42#define DHCP_ROOT_PATH 0x11
43#define DHCP_IP_TTL 0x17
44#define DHCP_MTU 0x1a
45#define DHCP_BROADCAST 0x1c
46#define DHCP_NTP_SERVER 0x2a
47#define DHCP_WINS_SERVER 0x2c
48#define DHCP_REQUESTED_IP 0x32
49#define DHCP_LEASE_TIME 0x33
50#define DHCP_OPTION_OVER 0x34
51#define DHCP_MESSAGE_TYPE 0x35
52#define DHCP_SERVER_ID 0x36
53#define DHCP_PARAM_REQ 0x37
54#define DHCP_MESSAGE 0x38
55#define DHCP_MAX_SIZE 0x39
56#define DHCP_T1 0x3a
57#define DHCP_T2 0x3b
58#define DHCP_VENDOR 0x3c
59#define DHCP_CLIENT_ID 0x3d
60#define DHCP_FQDN 0x51
61
62#define DHCP_END 0xFF
63
64
65#define BOOTREQUEST 1
66#define BOOTREPLY 2
67
68#define ETH_10MB 1
69#define ETH_10MB_LEN 6
70
71#define DHCPDISCOVER 1
72#define DHCPOFFER 2
73#define DHCPREQUEST 3
74#define DHCPDECLINE 4
75#define DHCPACK 5
76#define DHCPNAK 6
77#define DHCPRELEASE 7
78#define DHCPINFORM 8
79
80#define BROADCAST_FLAG 0x8000
81
82#define OPTION_FIELD 0
83#define FILE_FIELD 1
84#define SNAME_FIELD 2
85
86/* miscellaneous defines */
87#define MAC_BCAST_ADDR (uint8_t *) "\xff\xff\xff\xff\xff\xff"
88#define OPT_CODE 0
89#define OPT_LEN 1
90#define OPT_DATA 2
91
92struct option_set { 17struct option_set {
93 uint8_t *data; 18 uint8_t *data;
94 struct option_set *next; 19 struct option_set *next;
@@ -140,13 +65,9 @@ struct dhcpOfferedAddr {
140 uint32_t expires; /* host order */ 65 uint32_t expires; /* host order */
141}; 66};
142 67
143extern uint8_t blank_chaddr[]; 68struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease);
144
145void clear_lease(uint8_t *chaddr, uint32_t yiaddr);
146struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease);
147int lease_expired(struct dhcpOfferedAddr *lease); 69int lease_expired(struct dhcpOfferedAddr *lease);
148struct dhcpOfferedAddr *oldest_expired_lease(void); 70struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr);
149struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr);
150struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr); 71struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr);
151uint32_t find_address(int check_expired); 72uint32_t find_address(int check_expired);
152 73
diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c
index 2f7847d74..5d8775f63 100644
--- a/networking/udhcp/leases.c
+++ b/networking/udhcp/leases.c
@@ -8,25 +8,41 @@
8#include "dhcpd.h" 8#include "dhcpd.h"
9 9
10 10
11uint8_t blank_chaddr[] = {[0 ... 15] = 0}; 11/* Find the oldest expired lease, NULL if there are no expired leases */
12static struct dhcpOfferedAddr *oldest_expired_lease(void)
13{
14 struct dhcpOfferedAddr *oldest = NULL;
15 unsigned long oldest_lease = time(0);
16 unsigned i;
17
18
19 for (i = 0; i < server_config.max_leases; i++)
20 if (oldest_lease > leases[i].expires) {
21 oldest_lease = leases[i].expires;
22 oldest = &(leases[i]);
23 }
24 return oldest;
25}
26
12 27
13/* clear every lease out that chaddr OR yiaddr matches and is nonzero */ 28/* clear every lease out that chaddr OR yiaddr matches and is nonzero */
14void clear_lease(uint8_t *chaddr, uint32_t yiaddr) 29static void clear_lease(const uint8_t *chaddr, uint32_t yiaddr)
15{ 30{
16 unsigned int i, j; 31 unsigned i, j;
17 32
18 for (j = 0; j < 16 && !chaddr[j]; j++); 33 for (j = 0; j < 16 && !chaddr[j]; j++);
19 34
20 for (i = 0; i < server_config.max_leases; i++) 35 for (i = 0; i < server_config.max_leases; i++)
21 if ((j != 16 && !memcmp(leases[i].chaddr, chaddr, 16)) || 36 if ((j != 16 && memcmp(leases[i].chaddr, chaddr, 16) != 0)
22 (yiaddr && leases[i].yiaddr == yiaddr)) { 37 || (yiaddr && leases[i].yiaddr == yiaddr)
38 ) {
23 memset(&(leases[i]), 0, sizeof(struct dhcpOfferedAddr)); 39 memset(&(leases[i]), 0, sizeof(struct dhcpOfferedAddr));
24 } 40 }
25} 41}
26 42
27 43
28/* add a lease into the table, clearing out any old ones */ 44/* add a lease into the table, clearing out any old ones */
29struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) 45struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease)
30{ 46{
31 struct dhcpOfferedAddr *oldest; 47 struct dhcpOfferedAddr *oldest;
32 48
@@ -52,31 +68,14 @@ int lease_expired(struct dhcpOfferedAddr *lease)
52} 68}
53 69
54 70
55/* Find the oldest expired lease, NULL if there are no expired leases */
56struct dhcpOfferedAddr *oldest_expired_lease(void)
57{
58 struct dhcpOfferedAddr *oldest = NULL;
59 unsigned long oldest_lease = time(0);
60 unsigned int i;
61
62
63 for (i = 0; i < server_config.max_leases; i++)
64 if (oldest_lease > leases[i].expires) {
65 oldest_lease = leases[i].expires;
66 oldest = &(leases[i]);
67 }
68 return oldest;
69
70}
71
72
73/* Find the first lease that matches chaddr, NULL if no match */ 71/* Find the first lease that matches chaddr, NULL if no match */
74struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr) 72struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr)
75{ 73{
76 unsigned int i; 74 unsigned i;
77 75
78 for (i = 0; i < server_config.max_leases; i++) 76 for (i = 0; i < server_config.max_leases; i++)
79 if (!memcmp(leases[i].chaddr, chaddr, 16)) return &(leases[i]); 77 if (!memcmp(leases[i].chaddr, chaddr, 16))
78 return &(leases[i]);
80 79
81 return NULL; 80 return NULL;
82} 81}
@@ -85,10 +84,11 @@ struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr)
85/* Find the first lease that matches yiaddr, NULL is no match */ 84/* Find the first lease that matches yiaddr, NULL is no match */
86struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) 85struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr)
87{ 86{
88 unsigned int i; 87 unsigned i;
89 88
90 for (i = 0; i < server_config.max_leases; i++) 89 for (i = 0; i < server_config.max_leases; i++)
91 if (leases[i].yiaddr == yiaddr) return &(leases[i]); 90 if (leases[i].yiaddr == yiaddr)
91 return &(leases[i]);
92 92
93 return NULL; 93 return NULL;
94} 94}
@@ -97,6 +97,8 @@ struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr)
97/* check is an IP is taken, if it is, add it to the lease table */ 97/* check is an IP is taken, if it is, add it to the lease table */
98static int check_ip(uint32_t addr) 98static int check_ip(uint32_t addr)
99{ 99{
100 static const uint8_t blank_chaddr[16]; /* 16 zero bytes */
101
100 struct in_addr temp; 102 struct in_addr temp;
101 103
102 if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) { 104 if (arpping(addr, server_config.server, server_config.arp, server_config.interface) == 0) {
@@ -105,7 +107,8 @@ static int check_ip(uint32_t addr)
105 inet_ntoa(temp), server_config.conflict_time); 107 inet_ntoa(temp), server_config.conflict_time);
106 add_lease(blank_chaddr, addr, server_config.conflict_time); 108 add_lease(blank_chaddr, addr, server_config.conflict_time);
107 return 1; 109 return 1;
108 } else return 0; 110 }
111 return 0;
109} 112}
110 113
111 114
@@ -125,7 +128,7 @@ uint32_t find_address(int check_expired)
125 /* ie, 192.168.55.255 */ 128 /* ie, 192.168.55.255 */
126 if ((addr & 0xFF) == 0xFF) continue; 129 if ((addr & 0xFF) == 0xFF) continue;
127 130
128 /* Only do if it isn't an assigned as a static lease */ 131 /* Only do if it isn't assigned as a static lease */
129 if (!reservedIp(server_config.static_leases, htonl(addr))) { 132 if (!reservedIp(server_config.static_leases, htonl(addr))) {
130 133
131 /* lease is not taken */ 134 /* lease is not taken */
@@ -133,11 +136,10 @@ uint32_t find_address(int check_expired)
133 lease = find_lease_by_yiaddr(ret); 136 lease = find_lease_by_yiaddr(ret);
134 137
135 /* no lease or it expired and we are checking for expired leases */ 138 /* no lease or it expired and we are checking for expired leases */
136 if ( (!lease || (check_expired && lease_expired(lease))) 139 if ((!lease || (check_expired && lease_expired(lease)))
137 && /* and it isn't on the network */ !check_ip(ret) 140 && /* and it isn't on the network */ !check_ip(ret)
138 ) { 141 ) {
139 return ret; 142 return ret;
140 break;
141 } 143 }
142 } 144 }
143 } 145 }
diff --git a/networking/udhcp/options.h b/networking/udhcp/options.h
index 11f013fd4..5e9adf881 100644
--- a/networking/udhcp/options.h
+++ b/networking/udhcp/options.h
@@ -23,6 +23,80 @@ enum {
23#define OPTION_REQ 0x10 /* have the client request this option */ 23#define OPTION_REQ 0x10 /* have the client request this option */
24#define OPTION_LIST 0x20 /* There can be a list of 1 or more of these */ 24#define OPTION_LIST 0x20 /* There can be a list of 1 or more of these */
25 25
26/*****************************************************************/
27/* Do not modify below here unless you know what you are doing!! */
28/*****************************************************************/
29
30/* DHCP protocol -- see RFC 2131 */
31#define SERVER_PORT 67
32#define CLIENT_PORT 68
33
34#define DHCP_MAGIC 0x63825363
35
36/* DHCP option codes (partial list) */
37#define DHCP_PADDING 0x00
38#define DHCP_SUBNET 0x01
39#define DHCP_TIME_OFFSET 0x02
40#define DHCP_ROUTER 0x03
41#define DHCP_TIME_SERVER 0x04
42#define DHCP_NAME_SERVER 0x05
43#define DHCP_DNS_SERVER 0x06
44#define DHCP_LOG_SERVER 0x07
45#define DHCP_COOKIE_SERVER 0x08
46#define DHCP_LPR_SERVER 0x09
47#define DHCP_HOST_NAME 0x0c
48#define DHCP_BOOT_SIZE 0x0d
49#define DHCP_DOMAIN_NAME 0x0f
50#define DHCP_SWAP_SERVER 0x10
51#define DHCP_ROOT_PATH 0x11
52#define DHCP_IP_TTL 0x17
53#define DHCP_MTU 0x1a
54#define DHCP_BROADCAST 0x1c
55#define DHCP_NTP_SERVER 0x2a
56#define DHCP_WINS_SERVER 0x2c
57#define DHCP_REQUESTED_IP 0x32
58#define DHCP_LEASE_TIME 0x33
59#define DHCP_OPTION_OVER 0x34
60#define DHCP_MESSAGE_TYPE 0x35
61#define DHCP_SERVER_ID 0x36
62#define DHCP_PARAM_REQ 0x37
63#define DHCP_MESSAGE 0x38
64#define DHCP_MAX_SIZE 0x39
65#define DHCP_T1 0x3a
66#define DHCP_T2 0x3b
67#define DHCP_VENDOR 0x3c
68#define DHCP_CLIENT_ID 0x3d
69#define DHCP_FQDN 0x51
70
71#define DHCP_END 0xFF
72
73
74#define BOOTREQUEST 1
75#define BOOTREPLY 2
76
77#define ETH_10MB 1
78#define ETH_10MB_LEN 6
79
80#define DHCPDISCOVER 1
81#define DHCPOFFER 2
82#define DHCPREQUEST 3
83#define DHCPDECLINE 4
84#define DHCPACK 5
85#define DHCPNAK 6
86#define DHCPRELEASE 7
87#define DHCPINFORM 8
88
89#define BROADCAST_FLAG 0x8000
90
91#define OPTION_FIELD 0
92#define FILE_FIELD 1
93#define SNAME_FIELD 2
94
95/* miscellaneous defines */
96#define OPT_CODE 0
97#define OPT_LEN 1
98#define OPT_DATA 2
99
26struct dhcp_option { 100struct dhcp_option {
27 char name[12]; 101 char name[12];
28 char flags; 102 char flags;
diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c
index 25c55faab..da3807773 100644
--- a/networking/udhcp/packet.c
+++ b/networking/udhcp/packet.c
@@ -112,7 +112,7 @@ uint16_t udhcp_checksum(void *addr, int count)
112void BUG_sizeof_struct_udp_dhcp_packet_must_be_576(void); 112void BUG_sizeof_struct_udp_dhcp_packet_must_be_576(void);
113int udhcp_raw_packet(struct dhcpMessage *payload, 113int udhcp_raw_packet(struct dhcpMessage *payload,
114 uint32_t source_ip, int source_port, 114 uint32_t source_ip, int source_port,
115 uint32_t dest_ip, int dest_port, uint8_t *dest_arp, int ifindex) 115 uint32_t dest_ip, int dest_port, const uint8_t *dest_arp, int ifindex)
116{ 116{
117 int fd; 117 int fd;
118 int result; 118 int result;
diff --git a/networking/udhcp/script.c b/networking/udhcp/script.c
index dc8ff7a1c..98706a592 100644
--- a/networking/udhcp/script.c
+++ b/networking/udhcp/script.c
@@ -9,7 +9,6 @@
9 */ 9 */
10 10
11#include "common.h" 11#include "common.h"
12#include "dhcpd.h"
13#include "dhcpc.h" 12#include "dhcpc.h"
14#include "options.h" 13#include "options.h"
15 14
@@ -77,7 +76,7 @@ static char *alloc_fill_opts(uint8_t *option, const struct dhcp_option *type_p)
77 switch (type) { 76 switch (type) {
78 case OPTION_IP_PAIR: 77 case OPTION_IP_PAIR:
79 dest += sprintip(dest, "", option); 78 dest += sprintip(dest, "", option);
80 *(dest++) = '/'; 79 *dest++ = '/';
81 option += 4; 80 option += 4;
82 optlen = 4; 81 optlen = 4;
83 case OPTION_IP: /* Works regardless of host byte order. */ 82 case OPTION_IP: /* Works regardless of host byte order. */
@@ -132,34 +131,42 @@ static char **fill_envp(struct dhcpMessage *packet)
132 int num_options = 0; 131 int num_options = 0;
133 int i, j; 132 int i, j;
134 char **envp; 133 char **envp;
134 char *var;
135 uint8_t *temp; 135 uint8_t *temp;
136 struct in_addr subnet; 136 struct in_addr subnet;
137 char over = 0; 137 char over = 0;
138 138
139 if (packet == NULL) 139 if (packet) {
140 num_options = 0; 140 for (i = 0; dhcp_options[i].code; i++) {
141 else {
142 for (i = 0; dhcp_options[i].code; i++)
143 if (get_option(packet, dhcp_options[i].code)) { 141 if (get_option(packet, dhcp_options[i].code)) {
144 num_options++; 142 num_options++;
145 if (dhcp_options[i].code == DHCP_SUBNET) 143 if (dhcp_options[i].code == DHCP_SUBNET)
146 num_options++; /* for mton */ 144 num_options++; /* for mton */
147 } 145 }
148 if (packet->siaddr) num_options++; 146 }
149 if ((temp = get_option(packet, DHCP_OPTION_OVER))) 147 if (packet->siaddr)
148 num_options++;
149 temp = get_option(packet, DHCP_OPTION_OVER);
150 if (temp)
150 over = *temp; 151 over = *temp;
151 if (!(over & FILE_FIELD) && packet->file[0]) num_options++; 152 if (!(over & FILE_FIELD) && packet->file[0])
152 if (!(over & SNAME_FIELD) && packet->sname[0]) num_options++; 153 num_options++;
154 if (!(over & SNAME_FIELD) && packet->sname[0])
155 num_options++;
153 } 156 }
154 157
155 envp = xzalloc(sizeof(char *) * (num_options + 5)); 158 envp = xzalloc(sizeof(char *) * (num_options + 5));
156 j = 0; 159 j = 0;
157 envp[j++] = xasprintf("interface=%s", client_config.interface); 160 envp[j++] = xasprintf("interface=%s", client_config.interface);
158 envp[j++] = xasprintf("PATH=%s", 161 var = getenv("PATH");
159 getenv("PATH") ? : "/bin:/usr/bin:/sbin:/usr/sbin"); 162 if (var)
160 envp[j++] = xasprintf("HOME=%s", getenv("HOME") ? : "/"); 163 envp[j++] = xasprintf("PATH=%s", var);
164 var = getenv("HOME");
165 if (var)
166 envp[j++] = xasprintf("HOME=%s", var);
161 167
162 if (packet == NULL) return envp; 168 if (packet == NULL)
169 return envp;
163 170
164 envp[j] = xmalloc(sizeof("ip=255.255.255.255")); 171 envp[j] = xmalloc(sizeof("ip=255.255.255.255"));
165 sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr); 172 sprintip(envp[j++], "ip=", (uint8_t *) &packet->yiaddr);
@@ -206,19 +213,20 @@ void udhcp_run_script(struct dhcpMessage *packet, const char *name)
206 DEBUG("vfork'ing and execle'ing %s", client_config.script); 213 DEBUG("vfork'ing and execle'ing %s", client_config.script);
207 214
208 envp = fill_envp(packet); 215 envp = fill_envp(packet);
216
209 /* call script */ 217 /* call script */
218// can we use wait4pid(spawn(...)) here?
210 pid = vfork(); 219 pid = vfork();
211 if (pid) { 220 if (pid < 0) return;
212 waitpid(pid, NULL, 0); 221 if (pid == 0) {
213 for (curr = envp; *curr; curr++) free(*curr);
214 free(envp);
215 return;
216 } else if (pid == 0) {
217 /* close fd's? */ 222 /* close fd's? */
218 /* exec script */ 223 /* exec script */
219 execle(client_config.script, client_config.script, 224 execle(client_config.script, client_config.script,
220 name, NULL, envp); 225 name, NULL, envp);
221 bb_perror_msg("script %s failed", client_config.script); 226 bb_perror_msg_and_die("script %s failed", client_config.script);
222 exit(1);
223 } 227 }
228 waitpid(pid, NULL, 0);
229 for (curr = envp; *curr; curr++)
230 free(*curr);
231 free(envp);
224} 232}
diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c
index 8889fda86..e1a88addd 100644
--- a/networking/udhcp/serverpacket.c
+++ b/networking/udhcp/serverpacket.c
@@ -38,7 +38,7 @@ static int send_packet_to_relay(struct dhcpMessage *payload)
38/* send a packet to a specific arp address and ip address by creating our own ip packet */ 38/* send a packet to a specific arp address and ip address by creating our own ip packet */
39static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcast) 39static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcast)
40{ 40{
41 uint8_t *chaddr; 41 const uint8_t *chaddr;
42 uint32_t ciaddr; 42 uint32_t ciaddr;
43 43
44 if (force_broadcast) { 44 if (force_broadcast) {