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: