aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/dhcpd.c')
-rw-r--r--networking/udhcp/dhcpd.c78
1 files changed, 46 insertions, 32 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 90d8f0d17..ef9aa584e 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -10,6 +10,7 @@
10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
11 */ 11 */
12 12
13#include <syslog.h>
13#include "common.h" 14#include "common.h"
14#include "dhcpd.h" 15#include "dhcpd.h"
15#include "options.h" 16#include "options.h"
@@ -33,16 +34,30 @@ int udhcpd_main(int argc, char *argv[])
33 struct option_set *option; 34 struct option_set *option;
34 struct dhcpOfferedAddr *lease, static_lease; 35 struct dhcpOfferedAddr *lease, static_lease;
35 36
37//Huh, dhcpd don't have --foreground, --syslog options?? TODO
38
39 if (!ENABLE_FEATURE_UDHCP_DEBUG) {
40 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
41 logmode &= ~LOGMODE_STDIO;
42 }
43
44 if (ENABLE_FEATURE_UDHCP_SYSLOG) {
45 openlog(applet_name, LOG_PID, LOG_LOCAL0);
46 logmode |= LOGMODE_SYSLOG;
47 }
48
49 /* Would rather not do read_config before daemonization -
50 * otherwise NOMMU machines will parse config twice */
36 read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]); 51 read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]);
37 52
38 /* Start the log, sanitize fd's, and write a pid file */ 53 udhcp_make_pidfile(server_config.pidfile);
39 udhcp_start_log_and_pid(server_config.pidfile);
40 54
41 if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) { 55 option = find_option(server_config.options, DHCP_LEASE_TIME);
56 if (option) {
42 memcpy(&server_config.lease, option->data + 2, 4); 57 memcpy(&server_config.lease, option->data + 2, 4);
43 server_config.lease = ntohl(server_config.lease); 58 server_config.lease = ntohl(server_config.lease);
44 } 59 } else
45 else server_config.lease = LEASE_TIME; 60 server_config.lease = LEASE_TIME;
46 61
47 /* Sanity check */ 62 /* Sanity check */
48 num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1; 63 num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1;
@@ -60,9 +75,6 @@ int udhcpd_main(int argc, char *argv[])
60 &server_config.server, server_config.arp) < 0) 75 &server_config.server, server_config.arp) < 0)
61 return 1; 76 return 1;
62 77
63 if (!ENABLE_FEATURE_UDHCP_DEBUG)
64 udhcp_background(server_config.pidfile); /* hold lock during fork. */
65
66 /* Setup the signal pipe */ 78 /* Setup the signal pipe */
67 udhcp_sp_setup(); 79 udhcp_sp_setup();
68 80
@@ -106,7 +118,8 @@ int udhcpd_main(int argc, char *argv[])
106 default: continue; /* signal or error (probably EINTR) */ 118 default: continue; /* signal or error (probably EINTR) */
107 } 119 }
108 120
109 if ((bytes = udhcp_get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */ 121 bytes = udhcp_get_packet(&packet, server_socket); /* this waits for a packet - idle */
122 if (bytes < 0) {
110 if (bytes == -1 && errno != EINTR) { 123 if (bytes == -1 && errno != EINTR) {
111 DEBUG("error on read, %s, reopening socket", strerror(errno)); 124 DEBUG("error on read, %s, reopening socket", strerror(errno));
112 close(server_socket); 125 close(server_socket);
@@ -115,7 +128,8 @@ int udhcpd_main(int argc, char *argv[])
115 continue; 128 continue;
116 } 129 }
117 130
118 if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { 131 state = get_option(&packet, DHCP_MESSAGE_TYPE);
132 if (state == NULL) {
119 bb_error_msg("cannot get option from packet, ignoring"); 133 bb_error_msg("cannot get option from packet, ignoring");
120 continue; 134 continue;
121 } 135 }
@@ -131,7 +145,6 @@ int udhcpd_main(int argc, char *argv[])
131 static_lease.expires = 0; 145 static_lease.expires = 0;
132 146
133 lease = &static_lease; 147 lease = &static_lease;
134
135 } else { 148 } else {
136 lease = find_lease_by_chaddr(packet.chaddr); 149 lease = find_lease_by_chaddr(packet.chaddr);
137 } 150 }
@@ -157,25 +170,23 @@ int udhcpd_main(int argc, char *argv[])
157 if (server_id) { 170 if (server_id) {
158 /* SELECTING State */ 171 /* SELECTING State */
159 DEBUG("server_id = %08x", ntohl(server_id_align)); 172 DEBUG("server_id = %08x", ntohl(server_id_align));
160 if (server_id_align == server_config.server && requested && 173 if (server_id_align == server_config.server && requested
161 requested_align == lease->yiaddr) { 174 && requested_align == lease->yiaddr
175 ) {
162 sendACK(&packet, lease->yiaddr); 176 sendACK(&packet, lease->yiaddr);
163 } 177 }
178 } else if (requested) {
179 /* INIT-REBOOT State */
180 if (lease->yiaddr == requested_align)
181 sendACK(&packet, lease->yiaddr);
182 else
183 sendNAK(&packet);
184 } else if (lease->yiaddr == packet.ciaddr) {
185 /* RENEWING or REBINDING State */
186 sendACK(&packet, lease->yiaddr);
164 } else { 187 } else {
165 if (requested) { 188 /* don't know what to do!!!! */
166 /* INIT-REBOOT State */ 189 sendNAK(&packet);
167 if (lease->yiaddr == requested_align)
168 sendACK(&packet, lease->yiaddr);
169 else sendNAK(&packet);
170 } else {
171 /* RENEWING or REBINDING State */
172 if (lease->yiaddr == packet.ciaddr)
173 sendACK(&packet, lease->yiaddr);
174 else {
175 /* don't know what to do!!!! */
176 sendNAK(&packet);
177 }
178 }
179 } 190 }
180 191
181 /* what to do if we have no record of the client */ 192 /* what to do if we have no record of the client */
@@ -184,19 +195,22 @@ int udhcpd_main(int argc, char *argv[])
184 195
185 } else if (requested) { 196 } else if (requested) {
186 /* INIT-REBOOT State */ 197 /* INIT-REBOOT State */
187 if ((lease = find_lease_by_yiaddr(requested_align))) { 198 lease = find_lease_by_yiaddr(requested_align);
199 if (lease) {
188 if (lease_expired(lease)) { 200 if (lease_expired(lease)) {
189 /* probably best if we drop this lease */ 201 /* probably best if we drop this lease */
190 memset(lease->chaddr, 0, 16); 202 memset(lease->chaddr, 0, 16);
191 /* make some contention for this address */ 203 /* make some contention for this address */
192 } else sendNAK(&packet); 204 } else
193 } else if (requested_align < server_config.start || 205 sendNAK(&packet);
194 requested_align > server_config.end) { 206 } else if (requested_align < server_config.start
207 || requested_align > server_config.end
208 ) {
195 sendNAK(&packet); 209 sendNAK(&packet);
196 } /* else remain silent */ 210 } /* else remain silent */
197 211
198 } else { 212 } else {
199 /* RENEWING or REBINDING State */ 213 /* RENEWING or REBINDING State */
200 } 214 }
201 break; 215 break;
202 case DHCPDECLINE: 216 case DHCPDECLINE: