From: Alan T. DeKok Date: Wed, 13 Jul 2011 12:50:41 +0000 (+0200) Subject: More fixes for DHCP relaying X-Git-Tag: release_3_0_0_beta0~699 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f032d1b76df18173f302367543d7fca0becab85b;p=thirdparty%2Ffreeradius-server.git More fixes for DHCP relaying --- diff --git a/src/main/dhcpd.c b/src/main/dhcpd.c index 5af566d1f73..9e9c71c4fad 100644 --- a/src/main/dhcpd.c +++ b/src/main/dhcpd.c @@ -62,6 +62,7 @@ static int dhcp_process(REQUEST *request) * For messages from a client, look for Relay attribute, * and forward it if necessary. */ + vp = NULL; if (request->packet->data[0] == 1) { vp = pairfind(request->config_items, 270, DHCP_MAGIC_VENDOR); } @@ -88,15 +89,14 @@ static int dhcp_process(REQUEST *request) } /* - * Say there's no "original" packet. Instead, - * just forward the "response". + * Forward a reply... */ - rad_free(&request->reply); - request->reply = request->packet; - request->packet = NULL; - - request->reply->src_ipaddr = request->reply->dst_ipaddr; - request->reply->src_port = request->reply->dst_port; + pairfree(&request->reply->vps); + request->reply->vps = paircopy(request->packet->vps); + request->reply->code = request->packet->code; + request->reply->id = request->packet->id; + request->reply->src_ipaddr = request->packet->dst_ipaddr; + request->reply->src_port = request->packet->dst_port; request->reply->dst_ipaddr.af = AF_INET; request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; /* @@ -117,6 +117,11 @@ static int dhcp_process(REQUEST *request) * Responses from a server. Handle them differently. */ if (request->packet->data[0] == 2) { + pairfree(&request->reply->vps); + request->reply->vps = paircopy(request->packet->vps); + request->reply->code = request->packet->code; + request->reply->id = request->packet->id; + /* * Delete any existing giaddr. If we received a * message from the server, then we're NOT the @@ -125,10 +130,6 @@ static int dhcp_process(REQUEST *request) */ pairdelete(&request->packet->vps, 266, DHCP_MAGIC_VENDOR); - rad_free(&request->reply); - request->reply = request->packet; - request->packet = NULL; - /* * Search for client IP address. */ @@ -142,11 +143,11 @@ static int dhcp_process(REQUEST *request) /* * FROM us, TO the client's IP, OUR port + 1. */ - request->reply->src_ipaddr = request->reply->dst_ipaddr; - request->reply->src_port = request->reply->dst_port; + request->reply->src_ipaddr = request->packet->dst_ipaddr; + request->reply->src_port = request->packet->dst_port; request->reply->dst_ipaddr.af = AF_INET; request->reply->dst_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr; - request->reply->dst_port++; + request->reply->dst_port = request->packet->dst_port + 1; /* * Hop count goes down. @@ -322,8 +323,14 @@ static int dhcp_socket_send(rad_listen_t *listener, REQUEST *request) if (request->reply->code == 0) return 0; /* don't reply */ - if (fr_dhcp_encode(request->reply, request->packet) < 0) { - return -1; + if (request->packet->code != request->reply->code) { + if (fr_dhcp_encode(request->reply, request->packet) < 0) { + return -1; + } + } else { + if (fr_dhcp_encode(request->reply, NULL) < 0) { + return -1; + } } sock = listener->data;