######################################################################
server dhcp.eth1 {
+ # When the machine is not Linux, or has only one network interface, use
+ # the following listener:
listen {
+ # Listen for broadcasts + unicast on eth1
ipaddr = *
port = 67
type = dhcp
interface = eth1
}
+ # When the machine is Linux and has multiple network interfaces, use
+ # the following listeners instead:
+ listen {
+ # Listen for broadcasts on eth1
+ ipaddr = 255.255.255.255
+ port = 67
+ type = dhcp
+ interface = eth1
+ }
+ listen {
+ # Listen for unicast on our IP address, not bound to any
+ # interface but telling on which interface to forward the
+ # packets to.
+ ipaddr = 192.0.100.2
+ port = 67
+ type = dhcp
+ arp_interface = eth1
+ }
# Packets received on the socket will be processed through one
# of the following sections, named after the DHCP packet type.
dhcp DHCP-Discover {
update config {
# IP Address of the DHCP server
- DHCP-Relay-To-IP-Address := 192.0.2.2
+ DHCP-Relay-To-IP-Address := 192.0.1.2
}
update request {
- # IP Address of the DHCP relay (ourselves)
- DHCP-Gateway-IP-Address := 192.0.2.1
+ # IP Address of the DHCP relay (eth1)
+ DHCP-Gateway-IP-Address := 192.0.100.2
}
ok
}
dhcp DHCP-Request {
update config {
# IP Address of the DHCP server
- DHCP-Relay-To-IP-Address := 192.0.2.2
+ DHCP-Relay-To-IP-Address := 192.0.1.2
}
update request {
- DHCP-Gateway-IP-Address := 192.0.2.2
+ DHCP-Gateway-IP-Address := 192.0.100.2
}
ok
}
*/
int suppress_responses;
RADCLIENT dhcp_client;
+ const char *arp_interface;
} dhcp_socket_t;
static int dhcprelay_process_client_request(REQUEST *request)
{
uint8_t maxhops = 16;
- VALUE_PAIR *vp;
+ VALUE_PAIR *vp, *giaddrvp;
dhcp_socket_t *sock;
rad_assert(request->packet->data[0] == 1);
/*
* It's invalid to have giaddr=0 AND a relay option
*/
- vp = pairfind(request->packet->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
+ giaddrvp = vp = pairfind(request->packet->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
if ((vp && (vp->vp_ipaddr == htonl(INADDR_ANY))) &&
pairfind(request->packet->vps, DHCP2ATTR(82))) { /* DHCP-Relay-Agent-Information */
DEBUG("DHCP: Received packet with giaddr = 0 and containing relay option: Discarding packet\n");
*/
/* set SRC ipaddr/port to the listener ipaddr/port */
request->packet->src_ipaddr.af = AF_INET;
- /* XXX sock->ipaddr == 0 (listening on '*') */
- request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = sock->ipaddr.ipaddr.ip4addr.s_addr;
+ request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = giaddrvp->vp_ipaddr;
request->packet->src_port = sock->port;
vp = pairfind(request->config_items, DHCP2ATTR(270)); /* DHCP-Relay-To-IP-Address */
static int dhcprelay_process_server_reply(REQUEST *request)
{
- VALUE_PAIR *vp;
+ VALUE_PAIR *vp, *giaddrvp;
dhcp_socket_t *sock;
rad_assert(request->packet->data[0] == 2);
/*
* Check that packet is for us.
*/
- vp = pairfind(request->packet->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
+ giaddrvp = vp = pairfind(request->packet->vps, DHCP2ATTR(266)); /* DHCP-Gateway-IP-Address */
rad_assert(vp != NULL);
#ifndef WITH_UDPFROMTO
/* set SRC ipaddr/port to the listener ipaddr/port */
request->packet->src_ipaddr.af = AF_INET;
- /* XXX sock->ipaddr == 0 (listening on '*') */
- request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = sock->ipaddr.ipaddr.ip4addr.s_addr;
+ request->packet->src_ipaddr.ipaddr.ip4addr.s_addr = giaddrvp->vp_ipaddr;
request->packet->src_port = sock->port;
/* set DEST ipaddr/port to clientip/68 or broadcast in specific cases */
"no Client Hardware Address. Discarding packet");
return 1;
}
- if (fr_dhcp_add_arp_entry(request->packet->sockfd, sock->interface, hwvp, vp) < 0) {
+ if (sock->arp_interface == NULL)
+ sock->arp_interface = sock->interface;
+ if (fr_dhcp_add_arp_entry(request->packet->sockfd, sock->arp_interface, hwvp, vp) < 0) {
return -1;
}
}
/* else it's a packet from a client, without relaying */
rad_assert(vp->vp_integer == 1); /* BOOTREQUEST */
+
sock = request->listener->data;
/*
if (request->reply->code == PW_DHCP_OFFER) {
VALUE_PAIR *hwvp = pairfind(request->reply->vps, DHCP2ATTR(267)); /* DHCP-Client-Hardware-Address */
rad_assert(hwvp != NULL);
- if (fr_dhcp_add_arp_entry(request->reply->sockfd, sock->interface, hwvp, vp) < 0) {
+ if (sock->arp_interface == NULL)
+ sock->arp_interface = sock->interface;
+ if (fr_dhcp_add_arp_entry(request->reply->sockfd, sock->arp_interface, hwvp, vp) < 0) {
return -1;
}
}
}
}
+ cp = cf_pair_find(cs, "arp_interface");
+ if (cp) {
+ const char *value;
+ value = cf_pair_value(cp);
+ sock->arp_interface = value;
+ }
+
/*
* Initialize the fake client.
*/