diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-07 01:05:47 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-07 01:05:47 +0000 |
commit | fbd2918f5c91723063ed698026217a77a0fe565b (patch) | |
tree | cddfe351592f4a876232cf4c67c23df25bf0563c /networking | |
parent | bb5b01c7c711dd9ffc2abf23a05ccdfbf7fc0325 (diff) | |
download | busybox-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.c | 2 | ||||
-rw-r--r-- | networking/udhcp/common.h | 6 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 36 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.h | 83 | ||||
-rw-r--r-- | networking/udhcp/leases.c | 68 | ||||
-rw-r--r-- | networking/udhcp/options.h | 74 | ||||
-rw-r--r-- | networking/udhcp/packet.c | 2 | ||||
-rw-r--r-- | networking/udhcp/script.c | 52 | ||||
-rw-r--r-- | networking/udhcp/serverpacket.c | 2 |
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 | ||
18 | const uint8_t MAC_BCAST_ADDR[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | ||
19 | |||
18 | long uptime(void) | 20 | long 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 | 17 | extern 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); | |||
52 | uint16_t udhcp_checksum(void *addr, int count); | 51 | uint16_t udhcp_checksum(void *addr, int count); |
53 | int udhcp_raw_packet(struct dhcpMessage *payload, | 52 | int 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); | ||
56 | int udhcp_kernel_packet(struct dhcpMessage *payload, | 56 | int 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 | ||
20 | static 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 | */ |
25 | static unsigned long timeout; | ||
26 | static unsigned long requested_ip; /* = 0 */ | 26 | static unsigned long requested_ip; /* = 0 */ |
27 | static uint32_t server_addr; | 27 | static uint32_t server_addr; |
28 | static unsigned long timeout; | ||
29 | static int packet_num; /* = 0 */ | 28 | static int packet_num; /* = 0 */ |
30 | static int fd = -1; | 29 | static 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 |
35 | static int listen_mode; | 34 | static smallint listen_mode; |
35 | |||
36 | static smallint state; | ||
36 | 37 | ||
37 | struct client_config_t client_config; | 38 | struct 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 | |||
92 | struct option_set { | 17 | struct 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 | ||
143 | extern uint8_t blank_chaddr[]; | 68 | struct dhcpOfferedAddr *add_lease(const uint8_t *chaddr, uint32_t yiaddr, unsigned long lease); |
144 | |||
145 | void clear_lease(uint8_t *chaddr, uint32_t yiaddr); | ||
146 | struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease); | ||
147 | int lease_expired(struct dhcpOfferedAddr *lease); | 69 | int lease_expired(struct dhcpOfferedAddr *lease); |
148 | struct dhcpOfferedAddr *oldest_expired_lease(void); | 70 | struct dhcpOfferedAddr *find_lease_by_chaddr(const uint8_t *chaddr); |
149 | struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr); | ||
150 | struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr); | 71 | struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr); |
151 | uint32_t find_address(int check_expired); | 72 | uint32_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 | ||
11 | uint8_t blank_chaddr[] = {[0 ... 15] = 0}; | 11 | /* Find the oldest expired lease, NULL if there are no expired leases */ |
12 | static 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 */ |
14 | void clear_lease(uint8_t *chaddr, uint32_t yiaddr) | 29 | static 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 */ |
29 | struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) | 45 | struct 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 */ | ||
56 | struct 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 */ |
74 | struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr) | 72 | struct 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 */ |
86 | struct dhcpOfferedAddr *find_lease_by_yiaddr(uint32_t yiaddr) | 85 | struct 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 */ |
98 | static int check_ip(uint32_t addr) | 98 | static 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 | |||
26 | struct dhcp_option { | 100 | struct 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) | |||
112 | void BUG_sizeof_struct_udp_dhcp_packet_must_be_576(void); | 112 | void BUG_sizeof_struct_udp_dhcp_packet_must_be_576(void); |
113 | int udhcp_raw_packet(struct dhcpMessage *payload, | 113 | int 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 */ |
39 | static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcast) | 39 | static 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) { |