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:39:57 +0000 (16:39 +0200)
raddb/sites-available/dhcp
src/main/dhcpd.c
src/main/listen.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 15685e5..9db6c96 100644 (file)
 
 #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;
@@ -84,7 +100,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 = common_socket_parse(cs, this);
        if (rcode != 0) return rcode;
@@ -106,6 +124,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;
 }
 
@@ -120,7 +166,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) {
@@ -128,14 +174,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;
        }
@@ -151,6 +191,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);
 
@@ -160,6 +202,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);
 }
 
index 1276f69..140506d 100644 (file)
@@ -88,7 +88,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
@@ -1601,9 +1600,6 @@ static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
 #ifdef WITH_VMPS
        case RAD_LISTEN_VQP:
 #endif
-#ifdef WITH_DHCP
-       case RAD_LISTEN_DHCP:
-#endif
 #ifdef WITH_COA
        case RAD_LISTEN_COA:
 #endif
@@ -1611,6 +1607,13 @@ static rad_listen_t *listen_alloc(RAD_LISTEN_TYPE type)
                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;