]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
More fixes for DHCP relaying
authorAlan T. DeKok <aland@freeradius.org>
Wed, 13 Jul 2011 12:50:41 +0000 (14:50 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 29 Jul 2011 13:47:55 +0000 (09:47 -0400)
src/main/dhcpd.c

index 5af566d1f73770d05a586a7eb22a9efa7d799ca0..9e9c71c4fad5565190f1b14cc047a5a12788093c 100644 (file)
@@ -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;