Add missing rlm_dhcp module
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 3 Nov 2012 21:43:04 +0000 (21:43 +0000)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Sat, 3 Nov 2012 21:51:02 +0000 (21:51 +0000)
raddb/dictionary.in
raddb/mods-available/dhcp [new file with mode: 0644]
src/modules/rlm_dhcp/Makefile [new file with mode: 0644]
src/modules/rlm_dhcp/rlm_dhcp.c [new file with mode: 0644]

index ef22be9..3f293db 100644 (file)
@@ -20,7 +20,7 @@
 #  Ideally, the "configure" process should automatically enable this
 #  dictionary, but we don't yet do that.
 #
-#$INCLUDE      @prefix@/share/freeradius/dictionary.dhcp
+$INCLUDE       @prefix@/share/freeradius/dictionary.dhcp
 
 #
 #      The filename given here should be an absolute path. 
diff --git a/raddb/mods-available/dhcp b/raddb/mods-available/dhcp
new file mode 100644 (file)
index 0000000..a431633
--- /dev/null
@@ -0,0 +1,19 @@
+# -*- text -*-
+#
+#  $Id$
+
+#
+#  This module is useful only for 'xlat'.  To use it,
+#  put 'dhcp' into the 'instantiate' section.
+#
+#  %{dhcp_options:<Attribute-ref>} may be used to decode
+#  DHCP options data included in RADIUS packets by vendors
+#  of DHCP to RADIUS gateways.
+#
+#  This is known to work with the following VSAs:
+#      * Juniper               - ERX-Dhcp-Options
+#      * Alcatel lucent SR     - Alc-ToServer-Dhcp-Options
+#                              - Alc-ToClient-Dhcp-Options
+#
+dhcp {
+}
diff --git a/src/modules/rlm_dhcp/Makefile b/src/modules/rlm_dhcp/Makefile
new file mode 100644 (file)
index 0000000..8e53d5b
--- /dev/null
@@ -0,0 +1,11 @@
+TARGET         = rlm_dhcp
+SRCS           = rlm_dhcp.c
+HEADERS                = 
+RLM_CFLAGS     =
+RLM_LIBS       = 
+
+include ../rules.mak
+
+$(STATIC_OBJS): $(HEADERS)
+
+$(DYNAMIC_OBJS): $(HEADERS)
diff --git a/src/modules/rlm_dhcp/rlm_dhcp.c b/src/modules/rlm_dhcp/rlm_dhcp.c
new file mode 100644 (file)
index 0000000..d4c5d5c
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * rlm_dhcp.c
+ *
+ * Version:    $Id$
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ *
+ * Copyright 2012  The FreeRADIUS server project
+ */
+
+#include <freeradius-devel/ident.h>
+RCSID("$Id$")
+
+#include <freeradius-devel/autoconf.h>
+
+#ifdef WITH_DHCP
+
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/modules.h>
+#include <freeradius-devel/dhcp.h>
+
+#include <ctype.h>
+
+/*
+ *     Define a structure for our module configuration.
+ *
+ *     These variables do not need to be in a structure, but it's
+ *     a lot cleaner to do so, and a pointer to the structure can
+ *     be used as the instance handle.
+ */
+typedef struct rlm_dhcp_t {
+} rlm_dhcp_t;
+
+
+/*
+ *     Allow single attribute values to be retrieved from the dhcp.
+ */
+static size_t dhcp_options_xlat(UNUSED void *instance, REQUEST *request,
+                               const char *fmt, char *out, size_t freespace)
+{
+       VALUE_PAIR *vp, *head = NULL, *next;
+       int decoded = 0;
+       
+       while (isspace((int) *fmt)) fmt++;
+       
+       
+       if (!radius_get_vp(request, fmt, &vp) || !vp) {
+                *out = '\0';
+                
+                return 0;
+       }
+       
+       if ((fr_dhcp_decode_options(vp->vp_octets, vp->length, &head) < 0) ||
+           (head == NULL)) {
+               RDEBUG("WARNING: DHCP option decoding failed");
+               goto fail;
+       }
+       
+       next = head;
+       
+       do {
+                next = next->next;
+                decoded++;
+       } while (next);
+       
+       pairmove(&(request->packet->vps), &head);
+       
+       /* Free any unmoved pairs */
+       pairfree(&head);
+       
+       fail:
+       
+       snprintf(out, freespace, "%i", decoded);
+                        
+       return strlen(out);
+}
+
+
+/*
+ *     A mapping of configuration file names to internal variables.
+ *
+ *     Note that the string is dynamically allocated, so it MUST
+ *     be freed.  When the configuration file parse re-reads the string,
+ *     it free's the old one, and strdup's the new one, placing the pointer
+ *     to the strdup'd string into 'config.string'.  This gets around
+ *     buffer over-flows.
+ */
+static const CONF_PARSER module_config[] = {
+       { NULL, -1, 0, NULL, NULL }             /* end the list */
+};
+
+
+/*
+ *     Only free memory we allocated.  The strings allocated via
+ *     cf_section_parse() do not need to be freed.
+ */
+static int dhcp_detach(void *instance)
+{
+       free(instance);
+       return 0;
+}
+
+
+/*
+ *     Instantiate the module.
+ */
+static int dhcp_instantiate(CONF_SECTION *conf, void **instance)
+{
+       rlm_dhcp_t *inst;
+
+       inst = rad_malloc(sizeof(*inst));
+       if (!inst) {
+               return -1;
+       }
+       memset(inst, 0, sizeof(*inst));
+       
+       xlat_register("dhcp_options", dhcp_options_xlat, inst);
+
+       /*
+        *      If the configuration parameters can't be parsed, then
+        *      fail.
+        */
+       if (cf_section_parse(conf, inst, module_config) < 0) {
+               free(inst);
+               return -1;
+       }
+
+       *instance = inst;
+
+       return 0;
+}
+
+
+/*
+ *     The module name should be the only globally exported symbol.
+ *     That is, everything else should be 'static'.
+ *
+ *     If the module needs to temporarily modify it's instantiation
+ *     data, the type should be changed to RLM_TYPE_THREAD_UNSAFE.
+ *     The server will then take care of ensuring that the module
+ *     is single-threaded.
+ */
+module_t rlm_dhcp = {
+       RLM_MODULE_INIT,
+       "dhcp",
+       0,                              /* type */
+       dhcp_instantiate,               /* instantiation */
+       dhcp_detach,                    /* detach */
+       {
+               NULL,                   /* authentication */
+               NULL,                   /* authorization */
+               NULL,                   /* preaccounting */
+               NULL,                   /* accounting */
+               NULL,                   /* checksimul */
+               NULL,                   /* pre-proxy */
+               NULL,                   /* post-proxy */
+               NULL,                   /* post-auth */
+       },
+};
+
+#endif