-SUBMAKEFILES := proto_vmps.mk proto_vmps_udp.mk proto_vmps_all.mk proto_vmps_dynamic_client.mk libfreeradius-vqp.mk
+SUBMAKEFILES := proto_vmps.mk proto_vmps_udp.mk proto_vmps_all.mk proto_vmps_dynamic_client.mk
return 0;
}
+static int mod_load(void)
+{
+ if (fr_vqp_init() < 0) return -1;
+
+ return 0;
+}
+
+static void mod_unload(void)
+{
+ fr_vqp_free();
+}
+
fr_app_t proto_vmps = {
- .magic = RLM_MODULE_INIT,
- .name = "vmps",
- .config = proto_vmps_config,
- .inst_size = sizeof(proto_vmps_t),
-
- .bootstrap = mod_bootstrap,
- .instantiate = mod_instantiate,
- .open = mod_open,
- .decode = mod_decode,
- .encode = mod_encode,
+ .magic = RLM_MODULE_INIT,
+ .name = "vmps",
+ .config = proto_vmps_config,
+ .inst_size = sizeof(proto_vmps_t),
+
+ .load = mod_load,
+ .unload = mod_unload,
+ .bootstrap = mod_bootstrap,
+ .instantiate = mod_instantiate,
+ .open = mod_open,
+ .decode = mod_decode,
+ .encode = mod_encode,
.entry_point_set = mod_entry_point_set,
- .priority = mod_priority_set
+ .priority = mod_priority_set
};
* @copyright 2018 Alan DeKok <aland@freeradius.org>
*/
#include <freeradius-devel/io/master.h>
-#include <freeradius-devel/vqp.h>
-#include "vqp.h"
+#include <freeradius-devel/vqp/vqp.h>
/** An instance of a proto_vmps listen section
*
*/
-typedef struct proto_vmps_t {
+typedef struct {
fr_io_instance_t io; //!< wrapper for IO abstraction
dl_instance_t **type_submodule; //!< Instance of the various types
#include <freeradius-devel/unlang.h>
#include <freeradius-devel/dict.h>
#include <freeradius-devel/rad_assert.h>
-#include "vqp.h"
+#include <freeradius-devel/vqp/vqp.h>
static fr_dict_t *dict_vmps;
#include <freeradius-devel/unlang.h>
#include <freeradius-devel/dict.h>
#include <freeradius-devel/rad_assert.h>
-#include "vqp.h"
+#include <freeradius-devel/vqp/vqp.h>
static fr_dict_t *dict_freeradius;
#include <freeradius-devel/net.h>
#include <freeradius-devel/pcap.h>
+static int instance_count = 0;
+
typedef struct dhcp_option_t {
uint8_t code;
uint8_t length;
fr_value_box_t value = { .type = FR_TYPE_UINT8 };
uint8_t i;
+ if (instance_count > 0) {
+ instance_count++;
+ return 0;
+ }
+
if (fr_dict_autoload(dhcpv4_dict) < 0) return -1;
if (fr_dict_attr_autoload(dhcpv4_dict_attr) < 0) return -1;
}
}
+ instance_count++;
+
return 0;
}
void fr_dhcpv4_free(void)
{
+ if (--instance_count > 0) return;
+
fr_dict_autofree(dhcpv4_dict);
}
#
TARGET := libfreeradius-vqp.a
-SOURCES := vqp.c
+SOURCES := vqp.c base.c
SRC_CFLAGS := -I$(top_builddir)/src
--- /dev/null
+/*
+ * 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
+ */
+
+/**
+ * $Id$
+ *
+ * @file src/protocols/vqp/vqp.h
+ * @brief Structures and prototypes for Cisco's VLAN Query Protocol
+ *
+ * @copyright 2018 The FreeRADIUS server project
+ */
+
+RCSID("$Id$")
+
+#include <freeradius-devel/util/util.h>
+#include "vqp.h"
+
+static int instance_count = 0;
+
+fr_dict_t *dict_vqp;
+
+extern fr_dict_autoload_t libfreeradius_vqp[];
+fr_dict_autoload_t libfreeradius_vqp[] = {
+ { .out = &dict_vqp, .proto = "vqp" },
+ { NULL }
+};
+
+fr_dict_attr_t const *attr_vqp_error_code;
+fr_dict_attr_t const *attr_vqp_packet_type;
+fr_dict_attr_t const *attr_vqp_sequence_number;
+
+extern fr_dict_attr_autoload_t libfreeradius_vqp_attr[];
+fr_dict_attr_autoload_t libfreeradius_vqp_attr[] = {
+ { .out = &attr_vqp_error_code, .name = "VQP-Error-Code", .type = FR_TYPE_UINT32, .dict = &dict_vqp },
+ { .out = &attr_vqp_packet_type, .name = "VQP-Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_vqp },
+ { .out = &attr_vqp_sequence_number, .name = "VQP-Sequence-Number", .type = FR_TYPE_UINT32, .dict = &dict_vqp },
+ { NULL }
+};
+
+
+int fr_vqp_init(void)
+{
+ if (instance_count > 0) {
+ instance_count++;
+ return 0;
+ }
+
+ if (fr_dict_autoload(libfreeradius_vqp) < 0) return -1;
+ if (fr_dict_attr_autoload(libfreeradius_vqp_attr) < 0) return -1;
+
+ instance_count++;
+
+ return 0;
+}
+
+void fr_vqp_free(void)
+{
+ if (--instance_count > 0) return;
+
+ fr_dict_autofree(libfreeradius_vqp);
+}
/*
- * vqp.c Functions to send/receive VQP packets.
+ * 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.
*
- * Version: $Id$
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
+ * 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
- * Lesser General Public License for more details.
+ * 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 Lesser General Public
- * License along with this library; if not, write to the Free Software
+ * 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
+ */
+
+/**
+ * $Id$
+ *
+ * @file src/protocols/vqp/vqp.c
+ * @brief Functions to send/receive VQP packets.
*
* @copyright 2007 Alan DeKok <aland@deployingradius.com>
*/
if (packet->data_len < VQP_HDR_LEN) return -1;
fr_pair_cursor_init(&cursor, &packet->vps);
- vp = fr_pair_afrom_num(packet, 0, FR_VQP_PACKET_TYPE);
- if (!vp) {
- fr_strerror_printf("No memory");
- return -1;
- }
+
+ MEM(vp = fr_pair_afrom_da(packet, attr_vqp_packet_type));
vp->vp_uint32 = packet->data[1];
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_num(packet, 0, FR_VQP_ERROR_CODE);
- if (!vp) {
- fr_strerror_printf("No memory");
- return -1;
- }
+ MEM(vp = fr_pair_afrom_da(packet, attr_vqp_error_code));
vp->vp_uint32 = packet->data[2];
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
fr_pair_cursor_append(&cursor, vp);
- vp = fr_pair_afrom_num(packet, 0, FR_VQP_SEQUENCE_NUMBER);
- if (!vp) {
- fr_strerror_printf("No memory");
- return -1;
- }
+ MEM(vp = fr_pair_afrom_da(packet, attr_vqp_sequence_number));
vp->vp_uint32 = packet->id; /* already set by vqp_recv */
vp->vp_tainted = true;
DEBUG2("&%pP", vp);
* Hack to get the dictionaries to work correctly.
*/
attr |= 0x2000;
- vp = fr_pair_afrom_num(packet, 0, attr);
+ vp = fr_pair_afrom_child_num(packet, fr_dict_root(dict_vqp), attr);
if (!vp) {
fr_strerror_printf("No memory");
code = packet->code;
if (!code) {
- vp = fr_pair_find_by_num(packet->vps, 0, FR_VQP_PACKET_TYPE, TAG_ANY);
+ vp = fr_pair_find_by_da(packet->vps, attr_vqp_packet_type, TAG_ANY);
if (!vp) {
- fr_strerror_printf("Failed to find VQP-Packet-Type in response packet");
+ fr_strerror_printf("Failed to find %s in response packet", attr_vqp_packet_type->name);
return -1;
}
code = vp->vp_uint32;
if ((code < 1) || (code > 4)) {
- fr_strerror_printf("Invalid value %d for VQP-Packet-Type", code);
+ fr_strerror_printf("Invalid value %d for %s", code, attr_vqp_packet_type->name);
return -1;
}
}
length = VQP_HDR_LEN;
- vp = fr_pair_find_by_num(packet->vps, 0, FR_VQP_ERROR_CODE, TAG_ANY);
+ vp = fr_pair_find_by_da(packet->vps, attr_vqp_error_code, TAG_ANY);
if (vp) {
packet->data = talloc_array(packet, uint8_t, length);
if (!packet->data) {
for (i = 0; i < VQP_MAX_ATTRIBUTES; i++) {
if (!contents[code][i]) break;
- vps[i] = fr_pair_find_by_num(packet->vps, 0, contents[code][i] | 0x2000, TAG_ANY);
+ vps[i] = fr_pair_find_by_child_num(packet->vps, fr_dict_root(dict_vqp),
+ contents[code][i] | 0x2000, TAG_ANY);
/*
* FIXME: Print the name...
extern fr_dict_t *dict_vqp;
+extern fr_dict_attr_t const *attr_vqp_error_code;
+extern fr_dict_attr_t const *attr_vqp_packet_type;
+extern fr_dict_attr_t const *attr_vqp_sequence_number;
+
#define FR_MAX_VMPS_CODE (5)
-RADIUS_PACKET *vqp_recv(TALLOC_CTX *ctx, int sockfd);
-bool fr_vqp_ok(uint8_t const *packet, size_t *packet_len);
-int vqp_send(RADIUS_PACKET *packet);
-int vqp_decode(RADIUS_PACKET *packet);
-int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original);
-ssize_t vqp_packet_size(uint8_t const *data, size_t data_len);
-void fr_vmps_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len);
+RADIUS_PACKET *vqp_recv(TALLOC_CTX *ctx, int sockfd);
+
+bool fr_vqp_ok(uint8_t const *packet, size_t *packet_len);
+
+int vqp_send(RADIUS_PACKET *packet);
+
+int vqp_decode(RADIUS_PACKET *packet);
+
+int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original);
+
+ssize_t vqp_packet_size(uint8_t const *data, size_t data_len);
+
+void fr_vmps_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len);
+
+ssize_t fr_vmps_encode(uint8_t *buffer, size_t buflen, uint8_t const *original,
+ int code, uint32_t id, VALUE_PAIR *vps) CC_HINT(nonnull(1));
+
+extern char const *fr_vmps_codes[FR_MAX_VMPS_CODE];
-ssize_t fr_vmps_encode(uint8_t *buffer, size_t buflen, uint8_t const *original,
- int code, uint32_t id, VALUE_PAIR *vps) CC_HINT(nonnull(1));
+int fr_vqp_init(void);
-extern char const *fr_vmps_codes[FR_MAX_VMPS_CODE];
+void fr_vqp_free(void);
#ifdef __cplusplus
}