aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-03-21 06:46:09 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2010-03-21 06:46:09 +0100
commit53f72bb3f0bd81b1d3af8939a16ec730c7e750c3 (patch)
tree0d3f302f7692b5cbd473a76eeb28a506c5d9cf5f
parentc7dc79e71ddbc1498736a2bbf65a3da179557f83 (diff)
downloadbusybox-w32-53f72bb3f0bd81b1d3af8939a16ec730c7e750c3.tar.gz
busybox-w32-53f72bb3f0bd81b1d3af8939a16ec730c7e750c3.tar.bz2
busybox-w32-53f72bb3f0bd81b1d3af8939a16ec730c7e750c3.zip
dhcpd: apparently, sometimes IP is in ciaddr, not requested_ip...
also revert the part which appempted to "fix" that in client function old new delta udhcpd_main 1949 1964 +15 send_renew 142 105 -37 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/1 up/down: 15/-37) Total: -22 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/udhcp/clientpacket.c13
-rw-r--r--networking/udhcp/dhcpd.c101
2 files changed, 93 insertions, 21 deletions
diff --git a/networking/udhcp/clientpacket.c b/networking/udhcp/clientpacket.c
index a0be42885..b4a75be02 100644
--- a/networking/udhcp/clientpacket.c
+++ b/networking/udhcp/clientpacket.c
@@ -156,20 +156,7 @@ int FAST_FUNC send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr)
156 156
157 init_packet(&packet, DHCPREQUEST); 157 init_packet(&packet, DHCPREQUEST);
158 packet.xid = xid; 158 packet.xid = xid;
159 /* RFC 2131:
160 * "3.2 Client-server interaction - reusing a previously
161 * allocated network address"...
162 * The client broadcasts a DHCPREQUEST message on its local subnet.
163 * The message includes the client's network address in the
164 * REQUESTED_IP option. As the client has not received its
165 * network address, it MUST NOT fill in the 'ciaddr' field."
166 *
167 * FIXME: we seem to not follow this, we do set ciaddr.
168 */
169 packet.ciaddr = ciaddr; 159 packet.ciaddr = ciaddr;
170 add_simple_option(packet.options, DHCP_REQUESTED_IP, ciaddr);
171 if (server)
172 add_simple_option(packet.options, DHCP_SERVER_ID, server);
173 add_param_req_option(&packet); 160 add_param_req_option(&packet);
174 161
175 bb_info_msg("Sending renew..."); 162 bb_info_msg("Sending renew...");
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index a529e1b58..d6e90cd03 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -48,7 +48,7 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc
48 48
49 if (force_broadcast 49 if (force_broadcast
50 || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) 50 || (dhcp_pkt->flags & htons(BROADCAST_FLAG))
51 || !dhcp_pkt->ciaddr 51 || dhcp_pkt->ciaddr == 0
52 ) { 52 ) {
53 log1("Broadcasting packet to client"); 53 log1("Broadcasting packet to client");
54 ciaddr = INADDR_BROADCAST; 54 ciaddr = INADDR_BROADCAST;
@@ -466,16 +466,101 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
466 466
467 case DHCPREQUEST: 467 case DHCPREQUEST:
468 log1("Received REQUEST"); 468 log1("Received REQUEST");
469 469/* RFC 2131:
470 /* RFC 2131: "The REQUESTED_IP option MUST be set 470
471 * to the value of 'yiaddr' in the DHCPOFFER message 471o DHCPREQUEST generated during SELECTING state:
472 * from the server." */ 472
473 Client inserts the address of the selected server in 'server
474 identifier', 'ciaddr' MUST be zero, 'requested IP address' MUST be
475 filled in with the yiaddr value from the chosen DHCPOFFER.
476
477 Note that the client may choose to collect several DHCPOFFER
478 messages and select the "best" offer. The client indicates its
479 selection by identifying the offering server in the DHCPREQUEST
480 message. If the client receives no acceptable offers, the client
481 may choose to try another DHCPDISCOVER message. Therefore, the
482 servers may not receive a specific DHCPREQUEST from which they can
483 decide whether or not the client has accepted the offer.
484
485o DHCPREQUEST generated during INIT-REBOOT state:
486
487 'server identifier' MUST NOT be filled in, 'requested IP address'
488 option MUST be filled in with client's notion of its previously
489 assigned address. 'ciaddr' MUST be zero. The client is seeking to
490 verify a previously allocated, cached configuration. Server SHOULD
491 send a DHCPNAK message to the client if the 'requested IP address'
492 is incorrect, or is on the wrong network.
493
494 Determining whether a client in the INIT-REBOOT state is on the
495 correct network is done by examining the contents of 'giaddr', the
496 'requested IP address' option, and a database lookup. If the DHCP
497 server detects that the client is on the wrong net (i.e., the
498 result of applying the local subnet mask or remote subnet mask (if
499 'giaddr' is not zero) to 'requested IP address' option value
500 doesn't match reality), then the server SHOULD send a DHCPNAK
501 message to the client.
502
503 If the network is correct, then the DHCP server should check if
504 the client's notion of its IP address is correct. If not, then the
505 server SHOULD send a DHCPNAK message to the client. If the DHCP
506 server has no record of this client, then it MUST remain silent,
507 and MAY output a warning to the network administrator. This
508 behavior is necessary for peaceful coexistence of non-
509 communicating DHCP servers on the same wire.
510
511 If 'giaddr' is 0x0 in the DHCPREQUEST message, the client is on
512 the same subnet as the server. The server MUST broadcast the
513 DHCPNAK message to the 0xffffffff broadcast address because the
514 client may not have a correct network address or subnet mask, and
515 the client may not be answering ARP requests.
516
517 If 'giaddr' is set in the DHCPREQUEST message, the client is on a
518 different subnet. The server MUST set the broadcast bit in the
519 DHCPNAK, so that the relay agent will broadcast the DHCPNAK to the
520 client, because the client may not have a correct network address
521 or subnet mask, and the client may not be answering ARP requests.
522
523o DHCPREQUEST generated during RENEWING state:
524
525 'server identifier' MUST NOT be filled in, 'requested IP address'
526 option MUST NOT be filled in, 'ciaddr' MUST be filled in with
527 client's IP address. In this situation, the client is completely
528 configured, and is trying to extend its lease. This message will
529 be unicast, so no relay agents will be involved in its
530 transmission. Because 'giaddr' is therefore not filled in, the
531 DHCP server will trust the value in 'ciaddr', and use it when
532 replying to the client.
533
534 A client MAY choose to renew or extend its lease prior to T1. The
535 server may choose not to extend the lease (as a policy decision by
536 the network administrator), but should return a DHCPACK message
537 regardless.
538
539o DHCPREQUEST generated during REBINDING state:
540
541 'server identifier' MUST NOT be filled in, 'requested IP address'
542 option MUST NOT be filled in, 'ciaddr' MUST be filled in with
543 client's IP address. In this situation, the client is completely
544 configured, and is trying to extend its lease. This message MUST
545 be broadcast to the 0xffffffff IP broadcast address. The DHCP
546 server SHOULD check 'ciaddr' for correctness before replying to
547 the DHCPREQUEST.
548
549 The DHCPREQUEST from a REBINDING client is intended to accommodate
550 sites that have multiple DHCP servers and a mechanism for
551 maintaining consistency among leases managed by multiple servers.
552 A DHCP server MAY extend a client's lease only if it has local
553 administrative authority to do so.
554*/
473 if (!requested_opt) { 555 if (!requested_opt) {
474 log1("no requested IP, ignoring"); 556 requested_nip = packet.ciaddr;
475 break; 557 if (requested_nip == 0) {
558 log1("no requested IP and no ciaddr, ignoring");
559 break;
560 }
476 } 561 }
477 if (lease && requested_nip == lease->lease_nip) { 562 if (lease && requested_nip == lease->lease_nip) {
478 /* client requests IP which matches the lease. 563 /* client requested or configured IP matches the lease.
479 * ACK it, and bump lease expiration time. */ 564 * ACK it, and bump lease expiration time. */
480 send_ACK(&packet, lease->lease_nip); 565 send_ACK(&packet, lease->lease_nip);
481 break; 566 break;