# multiple interfaces, each with a separate policy.
#
# If you have multiple interfaces, it is a good idea to bind the
-# listen section to an interface. You will likely also need one
-# listen section per interface.
+# listen section to an interface. You will also need one listen
+# section per interface.
+#
+# FreeBSD does *not* support binding sockets to interfaces. Therefore,
+# if you have multiple interfaces, broadcasts may go out of the wrong
+# one, or even all interfaces. The only solution is to update FreeRADIUS
+# to use BPF sockets.
+#
listen {
- ipaddr = *
+ ipaddr = 127.0.0.1
port = 6700
type = dhcp
- #interface = eth0
+# interface = lo0
+
+ # The DHCP server defaults to allowing broadcast packets.
+ # Set this to "no" only when the server receives *all* packets
+ # from a relay agent. i.e. when *no* clients are on the same
+ # LAN as the DHCP server.
+ #
+ # It's set to "no" here for testing.
+ broadcast = no
}
# Packets received on the socket will be processed through one
static int dhcp_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
{
- int rcode;
+ int rcode, broadcast = 1;
int on = 1;
dhcp_socket_t *sock;
RADCLIENT *client;
sock = this->data;
/*
+ * See whether or not we enable broadcast packets.
+ */
+ cp = cf_pair_find(cs, "broadcast");
+ if (cp) {
+ const char *value = cf_pair_value(cp);
+ if (value && (strcmp(value, "no") == 0)) {
+ broadcast = 0;
+ }
+ }
+
+ if (broadcast) {
+ if (setsockopt(this->fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
+ radlog(L_ERR, "Can't set broadcast option: %s\n",
+ strerror(errno));
+ return -1;
+ }
+ }
+
+ if (setsockopt(this->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
+ radlog(L_ERR, "Can't set re-use addres option: %s\n",
+ strerror(errno));
+ return -1;
+ }
+
+ /*
* Undocumented extension for testing without
* destroying your network!
*/