After the many iterations of the layer 2 diff, I noticed I broke the
layer 3 default Relay Agent Information insertion: the relayed packet is
using the wrong address in the remote-id field.

This diff makes the Relay Agent Information init function to run later
and get the right address for the default remote-id.

ok?

Index: dhcrelay.c
===================================================================
RCS file: /home/obsdcvs/src/usr.sbin/dhcrelay/dhcrelay.c,v
retrieving revision 1.52
diff -u -p -r1.52 dhcrelay.c
--- dhcrelay.c  13 Dec 2016 09:29:05 -0000      1.52
+++ dhcrelay.c  13 Dec 2016 13:57:16 -0000
@@ -72,7 +72,7 @@ char  *print_hw_addr(int, int, unsigned c
 void    got_response(struct protocol *);
 int     get_rdomain(char *);
 
-void    relay_agentinfo(struct packet_ctx *, struct interface_info *);
+void    relay_agentinfo(struct packet_ctx *, struct interface_info *, int);
 
 int     relay_agentinfo_cmp(struct packet_ctx *pc, uint8_t *, int);
 ssize_t         relay_agentinfo_append(struct packet_ctx *, struct dhcp_packet 
*,
@@ -337,8 +337,6 @@ relay(struct interface_info *ip, struct 
                return;
        }
 
-       relay_agentinfo(pc, ip);
-
        /* If it's a bootreply, forward it to the client. */
        if (packet->op == BOOTREPLY) {
                /* Filter packet that were not meant for us. */
@@ -373,6 +371,7 @@ relay(struct interface_info *ip, struct 
                        memset(pc->pc_dmac, 0xff, sizeof(pc->pc_dmac));
                }
 
+               relay_agentinfo(pc, interfaces, packet->op);
                if ((length = relay_agentinfo_remove(pc, packet,
                    length)) == -1) {
                        note("ignoring BOOTREPLY with invalid "
@@ -420,6 +419,7 @@ relay(struct interface_info *ip, struct 
        if (!packet->giaddr.s_addr)
                packet->giaddr = ip->primary_address;
 
+       relay_agentinfo(pc, interfaces, packet->op);
        if ((length = relay_agentinfo_append(pc, packet, length)) == -1) {
                note("ignoring BOOTREQUEST with invalid "
                    "relay agent information");
@@ -559,9 +559,11 @@ got_response(struct protocol *l)
 }
 
 void
-relay_agentinfo(struct packet_ctx *pc, struct interface_info *intf)
+relay_agentinfo(struct packet_ctx *pc, struct interface_info *intf,
+    int bootop)
 {
-       static u_int8_t         buf[8];
+       static u_int8_t          buf[8];
+       struct sockaddr_in      *sin;
 
        if (oflag == 0)
                return;
@@ -579,10 +581,15 @@ relay_agentinfo(struct packet_ctx *pc, s
                pc->pc_circuitlen = 2;
 
                if (rai_remote == NULL) {
+                       if (bootop == BOOTREPLY)
+                               sin = ss2sin(&pc->pc_dst);
+                       else
+                               sin = ss2sin(&pc->pc_src);
+
                        pc->pc_remote =
-                           (uint8_t *)&ss2sin(&pc->pc_dst)->sin_addr;
+                           (uint8_t *)&sin->sin_addr;
                        pc->pc_remotelen =
-                           sizeof(ss2sin(&pc->pc_dst)->sin_addr);
+                           sizeof(sin->sin_addr);
                }
        } else {
                pc->pc_circuit = (u_int8_t *)rai_circuit;
@@ -867,7 +874,7 @@ l2relay(struct interface_info *ip, struc
                return;
        }
 
-       relay_agentinfo(pc, ip);
+       relay_agentinfo(pc, ip, dp->op);
 
        switch (dp->op) {
        case BOOTREQUEST:

Reply via email to