diff options
Diffstat (limited to 'networking/udhcp/dhcpd.c')
-rw-r--r-- | networking/udhcp/dhcpd.c | 264 |
1 files changed, 138 insertions, 126 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index f594bad66..a529e1b58 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -28,18 +28,8 @@ | |||
28 | #include "options.h" | 28 | #include "options.h" |
29 | 29 | ||
30 | 30 | ||
31 | /* send a packet to gateway_nip using the kernel ip stack */ | 31 | /* Send a packet to a specific mac address and ip address by creating our own ip packet */ |
32 | static int send_packet_to_relay(struct dhcp_packet *dhcp_pkt) | 32 | static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadcast) |
33 | { | ||
34 | log1("Forwarding packet to relay"); | ||
35 | |||
36 | return udhcp_send_kernel_packet(dhcp_pkt, | ||
37 | server_config.server_nip, SERVER_PORT, | ||
38 | dhcp_pkt->gateway_nip, SERVER_PORT); | ||
39 | } | ||
40 | |||
41 | /* send a packet to a specific mac address and ip address by creating our own ip packet */ | ||
42 | static int send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadcast) | ||
43 | { | 33 | { |
44 | const uint8_t *chaddr; | 34 | const uint8_t *chaddr; |
45 | uint32_t ciaddr; | 35 | uint32_t ciaddr; |
@@ -69,25 +59,36 @@ static int send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadca | |||
69 | chaddr = dhcp_pkt->chaddr; | 59 | chaddr = dhcp_pkt->chaddr; |
70 | } | 60 | } |
71 | 61 | ||
72 | return udhcp_send_raw_packet(dhcp_pkt, | 62 | udhcp_send_raw_packet(dhcp_pkt, |
73 | /*src*/ server_config.server_nip, SERVER_PORT, | 63 | /*src*/ server_config.server_nip, SERVER_PORT, |
74 | /*dst*/ ciaddr, CLIENT_PORT, chaddr, | 64 | /*dst*/ ciaddr, CLIENT_PORT, chaddr, |
75 | server_config.ifindex); | 65 | server_config.ifindex); |
76 | } | 66 | } |
77 | 67 | ||
78 | /* Send the dhcp packet. | 68 | /* Send a packet to gateway_nip using the kernel ip stack */ |
79 | * If force broadcast is set, the packet will be broadcast. | 69 | static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) |
80 | */ | 70 | { |
81 | static int send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast) | 71 | log1("Forwarding packet to relay"); |
72 | |||
73 | udhcp_send_kernel_packet(dhcp_pkt, | ||
74 | server_config.server_nip, SERVER_PORT, | ||
75 | dhcp_pkt->gateway_nip, SERVER_PORT); | ||
76 | } | ||
77 | |||
78 | static void send_packet(struct dhcp_packet *dhcp_pkt, int force_broadcast) | ||
82 | { | 79 | { |
83 | if (dhcp_pkt->gateway_nip) | 80 | if (dhcp_pkt->gateway_nip) |
84 | return send_packet_to_relay(dhcp_pkt); | 81 | send_packet_to_relay(dhcp_pkt); |
85 | return send_packet_to_client(dhcp_pkt, force_broadcast); | 82 | else |
83 | send_packet_to_client(dhcp_pkt, force_broadcast); | ||
86 | } | 84 | } |
87 | 85 | ||
88 | static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacket, char type) | 86 | static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacket, char type) |
89 | { | 87 | { |
88 | /* Sets op, htype, hlen, cookie fields | ||
89 | * and adds DHCP_MESSAGE_TYPE option */ | ||
90 | udhcp_init_header(packet, type); | 90 | udhcp_init_header(packet, type); |
91 | |||
91 | packet->xid = oldpacket->xid; | 92 | packet->xid = oldpacket->xid; |
92 | memcpy(packet->chaddr, oldpacket->chaddr, sizeof(oldpacket->chaddr)); | 93 | memcpy(packet->chaddr, oldpacket->chaddr, sizeof(oldpacket->chaddr)); |
93 | packet->flags = oldpacket->flags; | 94 | packet->flags = oldpacket->flags; |
@@ -132,26 +133,32 @@ static uint32_t select_lease_time(struct dhcp_packet *packet) | |||
132 | return lease_time_sec; | 133 | return lease_time_sec; |
133 | } | 134 | } |
134 | 135 | ||
135 | /* send a DHCP OFFER to a DHCP DISCOVER */ | 136 | /* We got a DHCP DISCOVER. Send an OFFER. */ |
136 | static int send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease) | 137 | static void send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, struct dyn_lease *lease) |
137 | { | 138 | { |
138 | struct dhcp_packet packet; | 139 | struct dhcp_packet packet; |
139 | uint32_t lease_time_sec = server_config.max_lease_sec; | 140 | uint32_t lease_time_sec; |
140 | const char *p_host_name; | ||
141 | struct in_addr addr; | 141 | struct in_addr addr; |
142 | 142 | ||
143 | init_packet(&packet, oldpacket, DHCPOFFER); | 143 | init_packet(&packet, oldpacket, DHCPOFFER); |
144 | 144 | ||
145 | /* ADDME: if static, short circuit */ | 145 | /* If it is a static lease, use its IP */ |
146 | packet.yiaddr = static_lease_nip; | ||
147 | /* Else: */ | ||
146 | if (!static_lease_nip) { | 148 | if (!static_lease_nip) { |
149 | /* We have no static lease for client's chaddr */ | ||
147 | uint32_t req_nip; | 150 | uint32_t req_nip; |
148 | uint8_t *req_ip_opt; | 151 | uint8_t *req_ip_opt; |
152 | const char *p_host_name; | ||
149 | 153 | ||
150 | /* The client is in our lease/offered table */ | ||
151 | if (lease) { | 154 | if (lease) { |
155 | /* We have a dynamic lease for client's chaddr. | ||
156 | * Reuse its IP (even if lease is expired). | ||
157 | * Note that we ignore requested IP in this case. | ||
158 | */ | ||
152 | packet.yiaddr = lease->lease_nip; | 159 | packet.yiaddr = lease->lease_nip; |
153 | } | 160 | } |
154 | /* Or the client has requested an IP */ | 161 | /* Or: if client has requested an IP */ |
155 | else if ((req_ip_opt = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL | 162 | else if ((req_ip_opt = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL |
156 | /* (read IP) */ | 163 | /* (read IP) */ |
157 | && (move_from_unaligned32(req_nip, req_ip_opt), 1) | 164 | && (move_from_unaligned32(req_nip, req_ip_opt), 1) |
@@ -165,50 +172,49 @@ static int send_offer(struct dhcp_packet *oldpacket, uint32_t static_lease_nip, | |||
165 | ) { | 172 | ) { |
166 | packet.yiaddr = req_nip; | 173 | packet.yiaddr = req_nip; |
167 | } | 174 | } |
168 | /* Otherwise, find a free IP */ | ||
169 | else { | 175 | else { |
176 | /* Otherwise, find a free IP */ | ||
170 | packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr); | 177 | packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr); |
171 | } | 178 | } |
172 | 179 | ||
173 | if (!packet.yiaddr) { | 180 | if (!packet.yiaddr) { |
174 | bb_error_msg("no IP addresses to give - OFFER abandoned"); | 181 | bb_error_msg("no free IP addresses. OFFER abandoned"); |
175 | return -1; | 182 | return; |
176 | } | 183 | } |
184 | /* Reserve the IP for a short time hoping to get DHCPREQUEST soon */ | ||
177 | p_host_name = (const char*) get_option(oldpacket, DHCP_HOST_NAME); | 185 | p_host_name = (const char*) get_option(oldpacket, DHCP_HOST_NAME); |
178 | if (add_lease(packet.chaddr, packet.yiaddr, | 186 | lease = add_lease(packet.chaddr, packet.yiaddr, |
179 | server_config.offer_time, | 187 | server_config.offer_time, |
180 | p_host_name, | 188 | p_host_name, |
181 | p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0 | 189 | p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0 |
182 | ) == 0 | 190 | ); |
183 | ) { | 191 | if (!lease) { |
184 | bb_error_msg("lease pool is full - OFFER abandoned"); | 192 | bb_error_msg("no free IP addresses. OFFER abandoned"); |
185 | return -1; | 193 | return; |
186 | } | 194 | } |
187 | lease_time_sec = select_lease_time(oldpacket); | ||
188 | } else { | ||
189 | /* It is a static lease... use it */ | ||
190 | packet.yiaddr = static_lease_nip; | ||
191 | } | 195 | } |
192 | 196 | ||
197 | lease_time_sec = select_lease_time(oldpacket); | ||
193 | add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); | 198 | add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); |
194 | add_server_options(&packet); | 199 | add_server_options(&packet); |
195 | 200 | ||
196 | addr.s_addr = packet.yiaddr; | 201 | addr.s_addr = packet.yiaddr; |
197 | bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); | 202 | bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); |
198 | return send_packet(&packet, /*force_bcast:*/ 0); | 203 | /* send_packet emits error message itself if it detects failure */ |
204 | send_packet(&packet, /*force_bcast:*/ 0); | ||
199 | } | 205 | } |
200 | 206 | ||
201 | static int send_NAK(struct dhcp_packet *oldpacket) | 207 | static void send_NAK(struct dhcp_packet *oldpacket) |
202 | { | 208 | { |
203 | struct dhcp_packet packet; | 209 | struct dhcp_packet packet; |
204 | 210 | ||
205 | init_packet(&packet, oldpacket, DHCPNAK); | 211 | init_packet(&packet, oldpacket, DHCPNAK); |
206 | 212 | ||
207 | log1("Sending NAK"); | 213 | log1("Sending NAK"); |
208 | return send_packet(&packet, /*force_bcast:*/ 1); | 214 | send_packet(&packet, /*force_bcast:*/ 1); |
209 | } | 215 | } |
210 | 216 | ||
211 | static int send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | 217 | static void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) |
212 | { | 218 | { |
213 | struct dhcp_packet packet; | 219 | struct dhcp_packet packet; |
214 | uint32_t lease_time_sec; | 220 | uint32_t lease_time_sec; |
@@ -219,15 +225,13 @@ static int send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | |||
219 | packet.yiaddr = yiaddr; | 225 | packet.yiaddr = yiaddr; |
220 | 226 | ||
221 | lease_time_sec = select_lease_time(oldpacket); | 227 | lease_time_sec = select_lease_time(oldpacket); |
222 | |||
223 | add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); | 228 | add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_sec)); |
229 | |||
224 | add_server_options(&packet); | 230 | add_server_options(&packet); |
225 | 231 | ||
226 | addr.s_addr = packet.yiaddr; | 232 | addr.s_addr = yiaddr; |
227 | bb_info_msg("Sending ACK to %s", inet_ntoa(addr)); | 233 | bb_info_msg("Sending ACK to %s", inet_ntoa(addr)); |
228 | 234 | send_packet(&packet, /*force_bcast:*/ 0); | |
229 | if (send_packet(&packet, /*force_bcast:*/ 0) < 0) | ||
230 | return -1; | ||
231 | 235 | ||
232 | p_host_name = (const char*) get_option(oldpacket, DHCP_HOST_NAME); | 236 | p_host_name = (const char*) get_option(oldpacket, DHCP_HOST_NAME); |
233 | add_lease(packet.chaddr, packet.yiaddr, | 237 | add_lease(packet.chaddr, packet.yiaddr, |
@@ -239,18 +243,21 @@ static int send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) | |||
239 | /* rewrite the file with leases at every new acceptance */ | 243 | /* rewrite the file with leases at every new acceptance */ |
240 | write_leases(); | 244 | write_leases(); |
241 | } | 245 | } |
242 | |||
243 | return 0; | ||
244 | } | 246 | } |
245 | 247 | ||
246 | static int send_inform(struct dhcp_packet *oldpacket) | 248 | static void send_inform(struct dhcp_packet *oldpacket) |
247 | { | 249 | { |
248 | struct dhcp_packet packet; | 250 | struct dhcp_packet packet; |
249 | 251 | ||
252 | /* "The server responds to a DHCPINFORM message by sending a DHCPACK | ||
253 | * message directly to the address given in the 'ciaddr' field | ||
254 | * of the DHCPINFORM message. The server MUST NOT send a lease | ||
255 | * expiration time to the client and SHOULD NOT fill in 'yiaddr'." | ||
256 | */ | ||
250 | init_packet(&packet, oldpacket, DHCPACK); | 257 | init_packet(&packet, oldpacket, DHCPACK); |
251 | add_server_options(&packet); | 258 | add_server_options(&packet); |
252 | 259 | ||
253 | return send_packet(&packet, /*force_bcast:*/ 0); | 260 | send_packet(&packet, /*force_bcast:*/ 0); |
254 | } | 261 | } |
255 | 262 | ||
256 | 263 | ||
@@ -352,6 +359,9 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
352 | while (1) { /* loop until universe collapses */ | 359 | while (1) { /* loop until universe collapses */ |
353 | int bytes; | 360 | int bytes; |
354 | struct timeval tv; | 361 | struct timeval tv; |
362 | uint8_t *server_id_opt; | ||
363 | uint8_t *requested_opt; | ||
364 | uint32_t requested_nip = requested_nip; /* for compiler */ | ||
355 | 365 | ||
356 | if (server_socket < 0) { | 366 | if (server_socket < 0) { |
357 | server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT, | 367 | server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT, |
@@ -404,124 +414,126 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
404 | } | 414 | } |
405 | continue; | 415 | continue; |
406 | } | 416 | } |
407 | |||
408 | if (packet.hlen != 6) { | 417 | if (packet.hlen != 6) { |
409 | bb_error_msg("MAC length != 6, ignoring packet"); | 418 | bb_error_msg("MAC length != 6, ignoring packet"); |
410 | continue; | 419 | continue; |
411 | } | 420 | } |
412 | 421 | if (packet.op != BOOTREQUEST) { | |
422 | bb_error_msg("not a REQUEST, ignoring packet"); | ||
423 | continue; | ||
424 | } | ||
413 | state = get_option(&packet, DHCP_MESSAGE_TYPE); | 425 | state = get_option(&packet, DHCP_MESSAGE_TYPE); |
414 | if (state == NULL) { | 426 | if (state == NULL || state[0] < DHCP_MINTYPE || state[0] > DHCP_MAXTYPE) { |
415 | bb_error_msg("no message type option, ignoring packet"); | 427 | bb_error_msg("no or bad message type option, ignoring packet"); |
416 | continue; | 428 | continue; |
417 | } | 429 | } |
418 | 430 | ||
419 | /* Look for a static lease */ | 431 | /* Look for a static/dynamic lease */ |
420 | static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); | 432 | static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); |
421 | if (static_lease_nip) { | 433 | if (static_lease_nip) { |
422 | bb_info_msg("Found static lease: %x", static_lease_nip); | 434 | bb_info_msg("Found static lease: %x", static_lease_nip); |
423 | |||
424 | memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); | 435 | memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); |
425 | fake_lease.lease_nip = static_lease_nip; | 436 | fake_lease.lease_nip = static_lease_nip; |
426 | fake_lease.expires = 0; | 437 | fake_lease.expires = 0; |
427 | |||
428 | lease = &fake_lease; | 438 | lease = &fake_lease; |
429 | } else { | 439 | } else { |
430 | lease = find_lease_by_mac(packet.chaddr); | 440 | lease = find_lease_by_mac(packet.chaddr); |
431 | } | 441 | } |
432 | 442 | ||
443 | /* Get REQUESTED_IP and SERVER_ID if present */ | ||
444 | server_id_opt = get_option(&packet, DHCP_SERVER_ID); | ||
445 | if (server_id_opt) { | ||
446 | uint32_t server_id_net; | ||
447 | move_from_unaligned32(server_id_net, server_id_opt); | ||
448 | if (server_id_net != server_config.server_nip) { | ||
449 | /* client talks to somebody else */ | ||
450 | log1("server ID doesn't match, ignoring"); | ||
451 | continue; | ||
452 | } | ||
453 | } | ||
454 | requested_opt = get_option(&packet, DHCP_REQUESTED_IP); | ||
455 | if (requested_opt) { | ||
456 | move_from_unaligned32(requested_nip, requested_opt); | ||
457 | } | ||
458 | |||
433 | switch (state[0]) { | 459 | switch (state[0]) { |
460 | |||
434 | case DHCPDISCOVER: | 461 | case DHCPDISCOVER: |
435 | log1("Received DISCOVER"); | 462 | log1("Received DISCOVER"); |
436 | 463 | ||
437 | if (send_offer(&packet, static_lease_nip, lease) < 0) { | 464 | send_offer(&packet, static_lease_nip, lease); |
438 | bb_error_msg("send OFFER failed"); | ||
439 | } | ||
440 | break; | 465 | break; |
441 | case DHCPREQUEST: { | ||
442 | uint8_t *server_id_opt, *requested_opt; | ||
443 | uint32_t server_id_net = server_id_net; /* for compiler */ | ||
444 | uint32_t requested_nip = requested_nip; /* for compiler */ | ||
445 | 466 | ||
467 | case DHCPREQUEST: | ||
446 | log1("Received REQUEST"); | 468 | log1("Received REQUEST"); |
447 | 469 | ||
448 | requested_opt = get_option(&packet, DHCP_REQUESTED_IP); | 470 | /* RFC 2131: "The REQUESTED_IP option MUST be set |
449 | server_id_opt = get_option(&packet, DHCP_SERVER_ID); | 471 | * to the value of 'yiaddr' in the DHCPOFFER message |
450 | if (requested_opt) | 472 | * from the server." */ |
451 | move_from_unaligned32(requested_nip, requested_opt); | 473 | if (!requested_opt) { |
452 | if (server_id_opt) | 474 | log1("no requested IP, ignoring"); |
453 | move_from_unaligned32(server_id_net, server_id_opt); | 475 | break; |
454 | 476 | } | |
455 | if (lease) { | 477 | if (lease && requested_nip == lease->lease_nip) { |
456 | if (server_id_opt) { | 478 | /* client requests IP which matches the lease. |
457 | /* SELECTING State */ | 479 | * ACK it, and bump lease expiration time. */ |
458 | if (server_id_net == server_config.server_nip | 480 | send_ACK(&packet, lease->lease_nip); |
459 | && requested_opt | 481 | break; |
460 | && requested_nip == lease->lease_nip | 482 | } |
461 | ) { | 483 | if (server_id_opt) { |
462 | send_ACK(&packet, lease->lease_nip); | 484 | /* client was talking specifically to us. |
463 | } | 485 | * "No, we don't have this IP for you". */ |
464 | } else if (requested_opt) { | 486 | send_NAK(&packet); |
465 | /* INIT-REBOOT State */ | ||
466 | if (lease->lease_nip == requested_nip) | ||
467 | send_ACK(&packet, lease->lease_nip); | ||
468 | else | ||
469 | send_NAK(&packet); | ||
470 | } else if (lease->lease_nip == packet.ciaddr) { | ||
471 | /* RENEWING or REBINDING State */ | ||
472 | send_ACK(&packet, lease->lease_nip); | ||
473 | } else { /* don't know what to do!!!! */ | ||
474 | send_NAK(&packet); | ||
475 | } | ||
476 | |||
477 | /* what to do if we have no record of the client */ | ||
478 | } else if (server_id_opt) { | ||
479 | /* SELECTING State */ | ||
480 | |||
481 | } else if (requested_opt) { | ||
482 | /* INIT-REBOOT State */ | ||
483 | lease = find_lease_by_nip(requested_nip); | ||
484 | if (lease) { | ||
485 | if (is_expired_lease(lease)) { | ||
486 | /* probably best if we drop this lease */ | ||
487 | memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); | ||
488 | } else { | ||
489 | /* make some contention for this address */ | ||
490 | send_NAK(&packet); | ||
491 | } | ||
492 | } else { | ||
493 | uint32_t r = ntohl(requested_nip); | ||
494 | if (r < server_config.start_ip | ||
495 | || r > server_config.end_ip | ||
496 | ) { | ||
497 | send_NAK(&packet); | ||
498 | } | ||
499 | /* else remain silent */ | ||
500 | } | ||
501 | |||
502 | } else { | ||
503 | /* RENEWING or REBINDING State */ | ||
504 | } | 487 | } |
505 | break; | 488 | break; |
506 | } | 489 | |
507 | case DHCPDECLINE: | 490 | case DHCPDECLINE: |
491 | /* RFC 2131: | ||
492 | * "If the server receives a DHCPDECLINE message, | ||
493 | * the client has discovered through some other means | ||
494 | * that the suggested network address is already | ||
495 | * in use. The server MUST mark the network address | ||
496 | * as not available and SHOULD notify the local | ||
497 | * sysadmin of a possible configuration problem." | ||
498 | * | ||
499 | * SERVER_ID must be present, | ||
500 | * REQUESTED_IP must be present, | ||
501 | * chaddr must be filled in, | ||
502 | * ciaddr must be 0 (we do not check this) | ||
503 | */ | ||
508 | log1("Received DECLINE"); | 504 | log1("Received DECLINE"); |
509 | if (lease) { | 505 | if (server_id_opt |
506 | && requested_opt | ||
507 | && lease /* chaddr matches this lease */ | ||
508 | && requested_nip == lease->lease_nip | ||
509 | ) { | ||
510 | memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); | 510 | memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); |
511 | lease->expires = time(NULL) + server_config.decline_time; | 511 | lease->expires = time(NULL) + server_config.decline_time; |
512 | } | 512 | } |
513 | break; | 513 | break; |
514 | |||
514 | case DHCPRELEASE: | 515 | case DHCPRELEASE: |
516 | /* "Upon receipt of a DHCPRELEASE message, the server | ||
517 | * marks the network address as not allocated." | ||
518 | * | ||
519 | * SERVER_ID must be present, | ||
520 | * REQUESTED_IP must not be present (we do not check this), | ||
521 | * chaddr must be filled in, | ||
522 | * ciaddr must be filled in | ||
523 | */ | ||
515 | log1("Received RELEASE"); | 524 | log1("Received RELEASE"); |
516 | if (lease) | 525 | if (server_id_opt |
526 | && lease /* chaddr matches this lease */ | ||
527 | && packet.ciaddr == lease->lease_nip | ||
528 | ) { | ||
517 | lease->expires = time(NULL); | 529 | lease->expires = time(NULL); |
530 | } | ||
518 | break; | 531 | break; |
532 | |||
519 | case DHCPINFORM: | 533 | case DHCPINFORM: |
520 | log1("Received INFORM"); | 534 | log1("Received INFORM"); |
521 | send_inform(&packet); | 535 | send_inform(&packet); |
522 | break; | 536 | break; |
523 | default: | ||
524 | bb_info_msg("Unsupported DHCP message (%02x) - ignoring", state[0]); | ||
525 | } | 537 | } |
526 | } | 538 | } |
527 | ret0: | 539 | ret0: |