fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t);
proto_dhcpv4_track_t *request = talloc_get_type_abort(track->packet, proto_dhcpv4_track_t);
- fr_io_address_t address = {};
+ fr_socket_t socket;
int flags;
ssize_t data_size;
/*
* Swap src/dst IP/port
*/
- fr_socket_addr_swap(&address.socket, &track->address->socket);
+ fr_socket_addr_swap(&socket, &track->address->socket);
/*
* Figure out which kind of packet we're sending.
* - else if socket wasn't bound to *, then use that
* - else if we have ifindex, get main IP from that interface and use that.
* - else for offer/ack, look at option 54, for Server Identification and use that
- * - else leave source IP as whatever is already in "address.socket.inet.src_ipaddr".
+ * - else leave source IP as whatever is already in "socket.inet.src_ipaddr".
*/
if (!fr_ipaddr_is_inaddr_any(&inst->src_ipaddr)) {
- address.socket.inet.src_ipaddr = inst->src_ipaddr;
+ socket.inet.src_ipaddr = inst->src_ipaddr;
} else if (!fr_ipaddr_is_inaddr_any(&inst->ipaddr)) {
- address.socket.inet.src_ipaddr = inst->ipaddr;
+ socket.inet.src_ipaddr = inst->ipaddr;
#ifdef WITH_IFINDEX_IPADDR_RESOLUTION
} else if ((address->socket.inet.ifindex > 0) &&
- (fr_ipaddr_from_ifindex(&primary, thread->sockfd, &address.socket.inet.dst_ipaddr.af,
- &address.socket.inet.ifindex) == 0)) {
- address.socket.inet.src_ipaddr = primary;
+ (fr_ipaddr_from_ifindex(&primary, thread->sockfd, &socket.inet.dst_ipaddr.af,
+ &socket.inet.ifindex) == 0)) {
+ socket.inet.src_ipaddr = primary;
#endif
} else if (((code[2] == FR_DHCP_OFFER) || (code[2] == FR_DHCP_ACK)) &&
((sid = fr_dhcpv4_packet_get_option(packet, buffer_len, attr_dhcp_server_identifier)) != NULL) &&
(sid[1] == 4)) {
- memcpy(&address.socket.inet.src_ipaddr.addr.v4.s_addr, sid + 2, 4);
+ memcpy(&socket.inet.src_ipaddr.addr.v4.s_addr, sid + 2, 4);
}
/*
*/
if (packet->giaddr != INADDR_ANY) {
DEBUG("Reply will be sent to giaddr.");
- address.socket.inet.dst_ipaddr.addr.v4.s_addr = packet->giaddr;
- address.socket.inet.dst_port = inst->port;
- address.socket.inet.src_port = inst->port;
+ socket.inet.dst_ipaddr.addr.v4.s_addr = packet->giaddr;
+ socket.inet.dst_port = inst->port;
+ socket.inet.src_port = inst->port;
/*
* Increase the hop count for client
*/
if (code[2] == FR_DHCP_NAK) {
DEBUG("Reply will be broadcast due to NAK.");
- address.socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
+ socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
goto send_reply;
}
*/
if (request->ciaddr != INADDR_ANY) {
DEBUG("Reply will be unicast to CIADDR from original packet.");
- memcpy(&address.socket.inet.dst_ipaddr.addr.v4.s_addr, &request->ciaddr, 4);
+ memcpy(&socket.inet.dst_ipaddr.addr.v4.s_addr, &request->ciaddr, 4);
goto send_reply;
}
*/
if (request->broadcast) {
DEBUG("Reply will be broadcast due to client request.");
- address.socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
+ socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
goto send_reply;
}
* This extension isn't in the RFC, but we find it useful.
*/
if ((packet->yiaddr == htonl(INADDR_ANY)) &&
- (address.socket.inet.dst_ipaddr.addr.v4.s_addr != htonl(INADDR_BROADCAST))) {
+ (socket.inet.dst_ipaddr.addr.v4.s_addr != htonl(INADDR_BROADCAST))) {
DEBUG("Reply will be unicast to source IP from original packet.");
goto send_reply;
}
* This check simply makes sure that we
* don't needlessly update the ARP table.
*/
- if (memcmp(&address.socket.inet.dst_ipaddr.addr.v4.s_addr, &packet->yiaddr, 4) == 0) {
+ if (memcmp(&socket.inet.dst_ipaddr.addr.v4.s_addr, &packet->yiaddr, 4) == 0) {
DEBUG("Reply will be unicast to YIADDR.");
#ifdef SIOCSARP
*/
if (fr_arp_entry_add(thread->sockfd, inst->interface, ipaddr, macaddr) == 0) {
DEBUG("Reply will be unicast to YIADDR, done ARP table updates.");
- memcpy(&address.socket.inet.dst_ipaddr.addr.v4.s_addr, &packet->yiaddr, 4);
+ memcpy(&socket.inet.dst_ipaddr.addr.v4.s_addr, &packet->yiaddr, 4);
} else {
DEBUG("Failed adding ARP entry. Reply will be broadcast.");
- address.socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
+ socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
}
#endif
} else {
DEBUG("Reply will be broadcast as we do not create raw UDP sockets.");
- address.socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
+ socket.inet.dst_ipaddr.addr.v4.s_addr = INADDR_BROADCAST;
}
break;
*/
case FR_DHCP_ACK:
DEBUG("Reply will be unicast to YIADDR.");
- memcpy(&address.socket.inet.dst_ipaddr.addr.v4.s_addr, &packet->yiaddr, 4);
+ memcpy(&socket.inet.dst_ipaddr.addr.v4.s_addr, &packet->yiaddr, 4);
break;
default:
/*
* proto_dhcpv4 takes care of suppressing do-not-respond, etc.
*/
- data_size = udp_send(&address.socket, flags, buffer, buffer_len);
+ data_size = udp_send(&socket, flags, buffer, buffer_len);
/*
* This socket is dead. That's an error...
proto_dhcpv6_udp_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_dhcpv6_udp_thread_t);
fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t);
- fr_io_address_t address = {};
+ fr_socket_t socket;
int flags;
ssize_t data_size;
* Send packets to the originator, EXCEPT that we always
* originate packets from our src_ipaddr.
*/
- fr_socket_addr_swap(&address.socket, &track->address->socket);
- if (!fr_ipaddr_is_inaddr_any(&inst->src_ipaddr)) address.socket.inet.src_ipaddr = inst->src_ipaddr;
+ fr_socket_addr_swap(&socket, &track->address->socket);
+ if (!fr_ipaddr_is_inaddr_any(&inst->src_ipaddr)) socket.inet.src_ipaddr = inst->src_ipaddr;
/*
* Figure out which kind of packet we're sending.
/*
* proto_dhcpv6 takes care of suppressing do-not-respond, etc.
*/
- data_size = udp_send(&address.socket, flags, buffer, buffer_len);
+ data_size = udp_send(&socket, flags, buffer, buffer_len);
/*
* This socket is dead. That's an error...
proto_radius_udp_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_radius_udp_thread_t);
fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t);
- fr_io_address_t const *address = track->address;
+ fr_socket_t socket;
int flags;
ssize_t data_size;
flags = UDP_FLAGS_CONNECTED * (thread->connection != NULL);
+ /*
+ * Swap src/dst address so we send the response to
+ * the client, not ourselves.
+ */
+ fr_socket_addr_swap(&socket, &track->address->socket);
+
/*
* This handles the race condition where we get a DUP,
* but the original packet replies before we're run.
memcpy(&packet, &track->reply, sizeof(packet)); /* const issues */
- (void) udp_send(&address->socket, flags, packet, track->reply_len);
+ (void) udp_send(&socket, flags, packet, track->reply_len);
}
return buffer_len;
* Only write replies if they're RADIUS packets.
* sometimes we want to NOT send a reply...
*/
- data_size = udp_send(&address->socket, flags, buffer, buffer_len);
+ data_size = udp_send(&socket, flags, buffer, buffer_len);
/*
* This socket is dead. That's an error...
{
proto_vmps_udp_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_vmps_udp_thread_t);
fr_io_track_t *track = talloc_get_type_abort(packet_ctx, fr_io_track_t);
- fr_io_address_t const *address = track->address;
+ fr_socket_t socket;
int flags;
ssize_t data_size;
flags = UDP_FLAGS_CONNECTED * (thread->connection != NULL);
+ fr_socket_addr_swap(&socket, &track->address->socket);
+
/*
* This handles the race condition where we get a DUP,
* but the original packet replies before we're run.
memcpy(&packet, &track->reply, sizeof(packet)); /* const issues */
- (void) udp_send(&address->socket, flags, packet, track->reply_len);
+ (void) udp_send(&socket, flags, packet, track->reply_len);
}
return buffer_len;
* Only write replies if they're VMPS packets.
* sometimes we want to NOT send a reply...
*/
- data_size = udp_send(&address->socket, flags, buffer, buffer_len);
+ data_size = udp_send(&socket, flags, buffer, buffer_len);
/*
* This socket is dead. That's an error...