Removed requirement for DHCP to have clients
authorAlan T. DeKok <aland@freeradius.org>
Tue, 16 Jun 2009 14:39:57 +0000 (16:39 +0200)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 16 Jun 2009 14:41:12 +0000 (16:41 +0200)
raddb/sites-available/dhcp
src/main/listen.c
src/modules/frs_dhcp/frs_dhcp.c

index a7fec32..ea1bd83 100644 (file)
 #
 server dhcp {
 
-#  This is part RADIUS legacy (sorry).  Clients have to be defined for
-#  DHCP.  This is not normal practice for a DHCP server, but it does
-#  enable a simple filter list of "known clients".
-#
-
-#  DHCP packets are normally sent with source IP address 0.0.0.0.
-#  If you want to accept packets from any IP, uncomment the "netmask"
-#  entry below, and delete the other "client" sections in this file.
-client any {
-       ipaddr = 0.0.0.0
-       #netmask = 0
-       dhcp = yes
-}
-
-#  For local testing.
-client localnet {
-       ipaddr = 127.0.0.0
-       netmask = 8
-       dhcp = yes
-}
-
 #  Define a DHCP socket.
 #
 #  The default port below is 6700, so you don't break your network.
index cd59063..38aac3d 100644 (file)
@@ -53,7 +53,6 @@ RADCLIENT *client_listener_find(const rad_listen_t *listener,
 {
 #ifdef WITH_DYNAMIC_CLIENTS
        int rcode;
-       listen_socket_t *sock;
        REQUEST *request;
        RADCLIENT *created;
 #endif
@@ -709,9 +708,6 @@ rad_listen_t *listen_alloc(const char *type_name)
 #ifdef WITH_VMPS
        case RAD_LISTEN_VQP:
 #endif
-#ifdef WITH_DHCP
-       case RAD_LISTEN_DHCP:
-#endif
 #ifdef WITH_COA
        case RAD_LISTEN_COA:
 #endif
@@ -719,6 +715,13 @@ rad_listen_t *listen_alloc(const char *type_name)
                memset(this->data, 0, sizeof(listen_socket_t));
                break;
 
+#ifdef WITH_DHCP
+       case RAD_LISTEN_DHCP:
+               this->data = rad_malloc(sizeof(dhcp_socket_t));
+               memset(this->data, 0, sizeof(dhcp_socket_t));
+               break;
+#endif
+
 #ifdef WITH_DETAIL
        case RAD_LISTEN_DETAIL:
                this->data = NULL;
index 292e715..fe42fdc 100644 (file)
 #include "dhcp.h"
 
 #ifdef WITH_DHCP
+
+/*
+ *     Same layout, etc. as listen_socket_t.
+ */
+typedef struct dhcp_socket_t {
+       /*
+        *      For normal sockets.
+        */
+       fr_ipaddr_t     ipaddr;
+       int             port;
+#ifdef SO_BINDTODEVICE
+       const char      *interface;
+#endif
+       int             suppress_responses;
+       RADCLIENT       dhcp_client;
+} dhcp_socket_t;
+
 static int dhcp_process(REQUEST *request)
 {
        int rcode;
@@ -89,7 +106,9 @@ static int dhcp_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
 {
        int rcode;
        int on = 1;
-       listen_socket_t *sock;
+       dhcp_socket_t *sock;
+       RADCLIENT *client;
+       CONF_PAIR *cp;
 
        rcode = listen_socket_parse(cs, this);
        if (rcode != 0) return rcode;
@@ -111,6 +130,34 @@ static int dhcp_socket_parse(CONF_SECTION *cs, rad_listen_t *this)
                return -1;
        }
 
+       /*
+        *      Undocumented extension for testing without
+        *      destroying your network!
+        */
+       sock->suppress_responses = FALSE;
+       cp = cf_pair_find(cs, "suppress_responses");
+       if (cp) {
+               const char *value;
+
+               value = cf_pair_value(cp);
+
+               if (value && (strcmp(value, "yes") == 0)) {
+                       sock->suppress_responses = TRUE;
+               }
+       }
+
+       /*
+        *      Initialize the fake client.
+        */
+       client = &sock->dhcp_client;
+       memset(client, 0, sizeof(*client));
+       client->ipaddr.af = AF_INET;
+       client->ipaddr.ipaddr.ip4addr.s_addr = INADDR_NONE;
+       client->prefix = 0;
+       client->longname = client->shortname = "dhcp";
+       client->secret = client->shortname;
+       client->nastype = strdup("none");
+
        return 0;
 }
 
@@ -125,7 +172,7 @@ static int dhcp_socket_recv(rad_listen_t *listener,
                            RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
 {
        RADIUS_PACKET   *packet;
-       RADCLIENT       *client;
+       dhcp_socket_t   *sock;
 
        packet = fr_dhcp_recv(listener->fd);
        if (!packet) {
@@ -133,14 +180,8 @@ static int dhcp_socket_recv(rad_listen_t *listener,
                return 0;
        }
 
-       if ((client = client_listener_find(listener,
-                                          &packet->src_ipaddr,
-                                          packet->src_port)) == NULL) {
-               rad_free(&packet);
-               return 0;
-       }
-
-       if (!received_request(listener, packet, prequest, client)) {
+       sock = listener->data;
+       if (!received_request(listener, packet, prequest, &sock->dhcp_client)) {
                rad_free(&packet);
                return 0;
        }
@@ -156,6 +197,8 @@ static int dhcp_socket_recv(rad_listen_t *listener,
  */
 static int dhcp_socket_send(rad_listen_t *listener, REQUEST *request)
 {
+       dhcp_socket_t   *sock;
+
        rad_assert(request->listener == listener);
        rad_assert(listener->send == dhcp_socket_send);
 
@@ -165,6 +208,12 @@ static int dhcp_socket_send(rad_listen_t *listener, REQUEST *request)
                return -1;
        }
 
+       sock = listener->data;
+       if (sock->suppress_responses) return 0;
+
+       /*
+        *      Don't send anything
+        */
        return fr_dhcp_send(request->reply);
 }