]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp-server: Send replies to BOOTP relay server port 2743/head
authorPatrik Flykt <patrik.flykt@linux.intel.com>
Thu, 25 Feb 2016 13:36:40 +0000 (15:36 +0200)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Thu, 25 Feb 2016 13:46:55 +0000 (15:46 +0200)
RFC 2131 Section 4.1 says that

 "If the ’giaddr’ field in a DHCP message from a client is non-zero,
  the server sends any return messages to the ’DHCP server’ port on the
  BOOTP relay agent whose address appears in ’giaddr’."

Fix this by adding a destination port when sending unicast UDP packets
and provide the server port when a BOOTP relay agent is being used.

src/libsystemd-network/sd-dhcp-server.c

index 1c408aaaac8ec663724af914c07b281865ff13f3..9adf8ec19d894701535170ca4797d17c2d0f487b 100644 (file)
@@ -280,10 +280,11 @@ static int dhcp_server_send_unicast_raw(sd_dhcp_server *server,
 }
 
 static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
+                                uint16_t destination_port,
                                 DHCPMessage *message, size_t len) {
         union sockaddr_union dest = {
                 .in.sin_family = AF_INET,
-                .in.sin_port = htobe16(DHCP_PORT_CLIENT),
+                .in.sin_port = htobe16(destination_port),
                 .in.sin_addr.s_addr = destination,
         };
         struct iovec iov = {
@@ -342,6 +343,7 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
                             DHCPRequest *req, DHCPPacket *packet,
                             int type, size_t optoffset) {
         be32_t destination = INADDR_ANY;
+        uint16_t destination_port = DHCP_PORT_CLIENT;
         int r;
 
         assert(server);
@@ -386,17 +388,19 @@ int dhcp_server_send_packet(sd_dhcp_server *server,
          */
         if (req->message->giaddr) {
                 destination = req->message->giaddr;
+                destination_port = DHCP_PORT_SERVER;
                 if (type == DHCP_NAK)
                         packet->dhcp.flags = htobe16(0x8000);
         } else if (req->message->ciaddr && type != DHCP_NAK)
                 destination = req->message->ciaddr;
 
         if (destination != INADDR_ANY)
-                return dhcp_server_send_udp(server, destination, &packet->dhcp,
+                return dhcp_server_send_udp(server, destination,
+                                            destination_port, &packet->dhcp,
                                             sizeof(DHCPMessage) + optoffset);
         else if (requested_broadcast(req) || type == DHCP_NAK)
                 return dhcp_server_send_udp(server, INADDR_BROADCAST,
-                                            &packet->dhcp,
+                                            destination_port, &packet->dhcp,
                                             sizeof(DHCPMessage) + optoffset);
         else
                 /* we cannot send UDP packet to specific MAC address when the
@@ -579,7 +583,8 @@ static int server_send_forcerenew(sd_dhcp_server *server, be32_t address,
 
         memcpy(&packet->dhcp.chaddr, chaddr, ETH_ALEN);
 
-        r = dhcp_server_send_udp(server, address, &packet->dhcp,
+        r = dhcp_server_send_udp(server, address, DHCP_PORT_CLIENT,
+                                 &packet->dhcp,
                                  sizeof(DHCPMessage) + optoffset);
         if (r < 0)
                 return r;