From: Arran Cudbard-Bell Date: Wed, 23 Sep 2015 20:18:59 +0000 (-0400) Subject: Correct precedence for determining src ip of DHCP packet X-Git-Tag: release_3_0_10~43 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=freeradius.git;a=commitdiff_plain;h=e6a9c14b3a305c4a66c35e4f1e475b8f11428c3d Correct precedence for determining src ip of DHCP packet --- diff --git a/src/modules/proto_dhcp/dhcpd.c b/src/modules/proto_dhcp/dhcpd.c index a74346b..9c8085d 100644 --- a/src/modules/proto_dhcp/dhcpd.c +++ b/src/modules/proto_dhcp/dhcpd.c @@ -449,22 +449,35 @@ static int dhcp_process(REQUEST *request) */ request->reply->dst_ipaddr.af = AF_INET; request->reply->src_ipaddr.af = AF_INET; - request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = sock->src_ipaddr.ipaddr.ip4addr.s_addr; request->reply->src_ipaddr.prefix = 32; /* - * They didn't set a proper src_ipaddr, but we want to - * send the packet with a source IP. If there's a server - * identifier, use it. + * Packet-Src-IP-Address has highest precedence */ - if (request->reply->src_ipaddr.ipaddr.ip4addr.s_addr == INADDR_ANY) { - vp = fr_pair_find_by_num(request->reply->vps, PW_PACKET_SRC_IP_ADDRESS, 0, TAG_ANY); - if (!vp) vp = fr_pair_find_by_num(request->reply->vps, 54, DHCP_MAGIC_VENDOR, TAG_ANY); /* DHCP-DHCP-Server-Identifier */ - if (vp) { - request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; - } + vp = fr_pair_find_by_num(request->reply->vps, PW_PACKET_SRC_IP_ADDRESS, 0, TAG_ANY); + if (vp) { + request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; + /* + * The request was unicast (via a relay) + */ + } else if (request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr != htonl(INADDR_BROADCAST)) { + request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = request->packet->dst_ipaddr.ipaddr.ip4addr.s_addr; + /* + * The listener was bound to an IP address, or we determined + * the address automatically, as it was the only address bound + * to the interface, and we bound to the interface. + */ + } else if (sock->src_ipaddr.ipaddr.ip4addr.s_addr != htonl(INADDR_ANY)) { + request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = sock->src_ipaddr.ipaddr.ip4addr.s_addr; + /* + * There's a Server-Identification attribute + */ + } else if ((vp = fr_pair_find_by_num(request->reply->vps, 54, DHCP_MAGIC_VENDOR, TAG_ANY))) { + request->reply->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; + } else { + REDEBUG("Unable to determine correct src_ipaddr for response"); + return -1; } - request->reply->dst_port = request->packet->src_port; request->reply->src_port = request->packet->dst_port;