From: David Hankins Date: Tue, 22 Aug 2006 17:13:25 +0000 (+0000) Subject: - DHCPINFORM handling for clients that properly set ciaddr and come to the X-Git-Tag: v4_0_0a1~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=87a08cccd5796695e77bc87a9d540ea9fcd46746;p=thirdparty%2Fdhcp.git - DHCPINFORM handling for clients that properly set ciaddr and come to the server via a relay agent has been repaired. [ISC-Bugs #16355] --- diff --git a/RELNOTES b/RELNOTES index 586e0b6f6..681ee3f43 100644 --- a/RELNOTES +++ b/RELNOTES @@ -151,6 +151,9 @@ the README file. after the EXPIRE state, so that interfaces that might be configured 'down' can be brought back 'up' and initialized. +- DHCPINFORM handling for clients that properly set ciaddr and come to the + server via a relay aget has been repaired. + Changes since 3.0.4 - A warning that host statements declared within subnet or shared-network diff --git a/server/dhcp.c b/server/dhcp.c index 59b97d9ae..4263781d0 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -34,7 +34,7 @@ #ifndef lint static char copyright[] = -"$Id: dhcp.c,v 1.211 2006/08/09 14:57:48 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; +"$Id: dhcp.c,v 1.212 2006/08/22 17:13:25 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -1223,33 +1223,28 @@ void dhcpinform (packet, ms_nulltp) /* RFC2131 states the server SHOULD unciast to ciaddr. * There are two wrinkles - relays, and when ciaddr is zero. - * There's actually no mention of relays at all in rfc2131. - * I think it's best to use relays where present...a relay is - * a bit more trustworthy about getting the message to a client - * than a client might be (it's better to send to a relay than - * to, say, a link-local address the client has selected). + * There's actually no mention of relays at all in rfc2131 in + * regard to DHCPINFORM, except to say we might get packets from + * clients via them. Note: relays unicast to clients to the + * "yiaddr" address, which servers are forbidden to set when + * answering an inform. * - * Where ciaddr is zero, which actually does happen quite frequently - * even though rfc2131 is unequivocal on the subject, we try to help - * by using the IP source address. + * The solution: If ciaddr is zero, and giaddr is set, go via the + * relay with the broadcast flag set to help the relay (with no + * yiaddr and very likely no chaddr, it will have no idea where to + * send the packet). * - * Where ciaddr is zero AND we got it via a relay, the IP source - * address is the relay - and we're transmitting to the client - * port. This might cause a loop. + * If the ciaddr is zero and giaddr is not set, go via the source + * IP address (but you are permitted to barf on their shoes). * - * So, overall, this is neater if the relay is selected first, - * treated like a relay, client addressing taken second. Since - * a relay possibly has no way of knowing how to reach the client - * if chaddr is zero (equally as common as ciaddr being zeroed), - * set the broadcast bit to try and help. + * If ciaddr is not zero, send the packet there always. */ - if (gip.len) { + if (!raw.ciaddr.s_addr && gip.len) { memcpy(&to.sin_addr, gip.iabuf, 4); to.sin_port = local_port; - - if (!raw.hlen) - raw.flags |= htons(BOOTP_BROADCAST); + raw.flags |= htons(BOOTP_BROADCAST); } else { + gip.len = 0; memcpy(&to.sin_addr, cip.iabuf, 4); to.sin_port = remote_port; }