aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/serverpacket.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-06-16 10:20:27 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-06-16 10:20:27 +0200
commit47f2d7ef7d4dbeea19a55f9d73ef826f9d06650f (patch)
treea84db8f0215526b9728f2f2b94214100e853a98c /networking/udhcp/serverpacket.c
parent1f363a086779152ab04067e81484b8bb69e4af72 (diff)
downloadbusybox-w32-47f2d7ef7d4dbeea19a55f9d73ef826f9d06650f.tar.gz
busybox-w32-47f2d7ef7d4dbeea19a55f9d73ef826f9d06650f.tar.bz2
busybox-w32-47f2d7ef7d4dbeea19a55f9d73ef826f9d06650f.zip
udhcpd: don't fail ARP check if returned MAC matches client's one
Also, do not unicast replies to yiaddr. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'networking/udhcp/serverpacket.c')
-rw-r--r--networking/udhcp/serverpacket.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/networking/udhcp/serverpacket.c b/networking/udhcp/serverpacket.c
index 8b0f1856b..157d157ba 100644
--- a/networking/udhcp/serverpacket.c
+++ b/networking/udhcp/serverpacket.c
@@ -31,7 +31,8 @@ static int send_packet_to_relay(struct dhcpMessage *payload)
31{ 31{
32 DEBUG("Forwarding packet to relay"); 32 DEBUG("Forwarding packet to relay");
33 33
34 return udhcp_send_kernel_packet(payload, server_config.server, SERVER_PORT, 34 return udhcp_send_kernel_packet(payload,
35 server_config.server, SERVER_PORT,
35 payload->giaddr, SERVER_PORT); 36 payload->giaddr, SERVER_PORT);
36} 37}
37 38
@@ -42,23 +43,31 @@ static int send_packet_to_client(struct dhcpMessage *payload, int force_broadcas
42 const uint8_t *chaddr; 43 const uint8_t *chaddr;
43 uint32_t ciaddr; 44 uint32_t ciaddr;
44 45
45 if (force_broadcast) { 46 // Was:
46 DEBUG("broadcasting packet to client (NAK)"); 47 //if (force_broadcast) { /* broadcast */ }
48 //else if (payload->ciaddr) { /* unicast to payload->ciaddr */ }
49 //else if (payload->flags & htons(BROADCAST_FLAG)) { /* broadcast */ }
50 //else { /* unicast to payload->yiaddr */ }
51 // But this is wrong: yiaddr is _our_ idea what client's IP is
52 // (for example, from lease file). Client may not know that,
53 // and may not have UDP socket listening on that IP!
54 // We should never unicast to payload->yiaddr!
55 // payload->ciaddr, OTOH, comes from client's request packet,
56 // and can be used.
57
58 if (force_broadcast
59 || (payload->flags & htons(BROADCAST_FLAG))
60 || !payload->ciaddr
61 ) {
62 DEBUG("broadcasting packet to client");
47 ciaddr = INADDR_BROADCAST; 63 ciaddr = INADDR_BROADCAST;
48 chaddr = MAC_BCAST_ADDR; 64 chaddr = MAC_BCAST_ADDR;
49 } else if (payload->ciaddr) { 65 } else {
50 DEBUG("unicasting packet to client ciaddr"); 66 DEBUG("unicasting packet to client ciaddr");
51 ciaddr = payload->ciaddr; 67 ciaddr = payload->ciaddr;
52 chaddr = payload->chaddr; 68 chaddr = payload->chaddr;
53 } else if (payload->flags & htons(BROADCAST_FLAG)) {
54 DEBUG("broadcasting packet to client (requested)");
55 ciaddr = INADDR_BROADCAST;
56 chaddr = MAC_BCAST_ADDR;
57 } else {
58 DEBUG("unicasting packet to client yiaddr");
59 ciaddr = payload->yiaddr;
60 chaddr = payload->chaddr;
61 } 69 }
70
62 return udhcp_send_raw_packet(payload, 71 return udhcp_send_raw_packet(payload,
63 /*src*/ server_config.server, SERVER_PORT, 72 /*src*/ server_config.server, SERVER_PORT,
64 /*dst*/ ciaddr, CLIENT_PORT, chaddr, 73 /*dst*/ ciaddr, CLIENT_PORT, chaddr,
@@ -118,17 +127,18 @@ int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
118 struct dhcpOfferedAddr *lease; 127 struct dhcpOfferedAddr *lease;
119 128
120 lease = find_lease_by_chaddr(oldpacket->chaddr); 129 lease = find_lease_by_chaddr(oldpacket->chaddr);
121 /* the client is in our lease/offered table */ 130 /* The client is in our lease/offered table */
122 if (lease) { 131 if (lease) {
123 signed_leasetime_t tmp = lease->expires - time(NULL); 132 signed_leasetime_t tmp = lease->expires - time(NULL);
124 if (tmp >= 0) 133 if (tmp >= 0)
125 lease_time_aligned = tmp; 134 lease_time_aligned = tmp;
126 packet.yiaddr = lease->yiaddr; 135 packet.yiaddr = lease->yiaddr;
127 /* Or the client has requested an ip */ 136 }
128 } else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL 137 /* Or the client has requested an IP */
129 /* Don't look here (ugly hackish thing to do) */ 138 else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) != NULL
139 /* (read IP) */
130 && (move_from_unaligned32(req_align, req), 1) 140 && (move_from_unaligned32(req_align, req), 1)
131 /* and the ip is in the lease range */ 141 /* and the IP is in the lease range */
132 && ntohl(req_align) >= server_config.start_ip 142 && ntohl(req_align) >= server_config.start_ip
133 && ntohl(req_align) <= server_config.end_ip 143 && ntohl(req_align) <= server_config.end_ip
134 /* and is not already taken/offered */ 144 /* and is not already taken/offered */
@@ -137,9 +147,10 @@ int FAST_FUNC send_offer(struct dhcpMessage *oldpacket)
137 || lease_expired(lease)) 147 || lease_expired(lease))
138 ) { 148 ) {
139 packet.yiaddr = req_align; 149 packet.yiaddr = req_align;
140 /* otherwise, find a free IP */ 150 }
141 } else { 151 /* Otherwise, find a free IP */
142 packet.yiaddr = find_free_or_expired_address(); 152 else {
153 packet.yiaddr = find_free_or_expired_address(oldpacket->chaddr);
143 } 154 }
144 155
145 if (!packet.yiaddr) { 156 if (!packet.yiaddr) {