From: Arran Cudbard-Bell Date: Mon, 28 May 2018 05:48:41 +0000 (+0600) Subject: Split out VQP into a library X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fdb938790842011003f67be6fd2cde93bf6d892c;p=thirdparty%2Ffreeradius-server.git Split out VQP into a library --- diff --git a/src/modules/proto_vmps/all.mk b/src/modules/proto_vmps/all.mk index 2a799a2645f..1e0a74eceff 100644 --- a/src/modules/proto_vmps/all.mk +++ b/src/modules/proto_vmps/all.mk @@ -1 +1 @@ -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 diff --git a/src/modules/proto_vmps/proto_vmps.c b/src/modules/proto_vmps/proto_vmps.c index f5549549689..d7431cf2ac3 100644 --- a/src/modules/proto_vmps/proto_vmps.c +++ b/src/modules/proto_vmps/proto_vmps.c @@ -796,17 +796,31 @@ static int mod_bootstrap(void *instance, CONF_SECTION *conf) 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 }; diff --git a/src/modules/proto_vmps/proto_vmps.h b/src/modules/proto_vmps/proto_vmps.h index dd65fd6fe5d..3acfc18fc65 100644 --- a/src/modules/proto_vmps/proto_vmps.h +++ b/src/modules/proto_vmps/proto_vmps.h @@ -24,13 +24,12 @@ * @copyright 2018 Alan DeKok */ #include -#include -#include "vqp.h" +#include /** 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 diff --git a/src/modules/proto_vmps/proto_vmps_all.c b/src/modules/proto_vmps/proto_vmps_all.c index 35f8bb4edf6..b6f81fa1d71 100644 --- a/src/modules/proto_vmps/proto_vmps_all.c +++ b/src/modules/proto_vmps/proto_vmps_all.c @@ -28,7 +28,7 @@ #include #include #include -#include "vqp.h" +#include static fr_dict_t *dict_vmps; diff --git a/src/modules/proto_vmps/proto_vmps_dynamic_client.c b/src/modules/proto_vmps/proto_vmps_dynamic_client.c index dd04bdf49a0..92a3da9209a 100644 --- a/src/modules/proto_vmps/proto_vmps_dynamic_client.c +++ b/src/modules/proto_vmps/proto_vmps_dynamic_client.c @@ -28,7 +28,7 @@ #include #include #include -#include "vqp.h" +#include static fr_dict_t *dict_freeradius; diff --git a/src/protocols/dhcpv4/base.c b/src/protocols/dhcpv4/base.c index 95fc0b3f47f..079e940cf3e 100644 --- a/src/protocols/dhcpv4/base.c +++ b/src/protocols/dhcpv4/base.c @@ -30,6 +30,8 @@ RCSID("$Id$") #include #include +static int instance_count = 0; + typedef struct dhcp_option_t { uint8_t code; uint8_t length; @@ -484,6 +486,11 @@ int fr_dhcpv4_init(void) 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; @@ -504,11 +511,15 @@ int fr_dhcpv4_init(void) } } + instance_count++; + return 0; } void fr_dhcpv4_free(void) { + if (--instance_count > 0) return; + fr_dict_autofree(dhcpv4_dict); } diff --git a/src/modules/proto_vmps/libfreeradius-vqp.mk b/src/protocols/vqp/all.mk similarity index 85% rename from src/modules/proto_vmps/libfreeradius-vqp.mk rename to src/protocols/vqp/all.mk index 1156c3db974..16d9c370a4d 100644 --- a/src/modules/proto_vmps/libfreeradius-vqp.mk +++ b/src/protocols/vqp/all.mk @@ -5,7 +5,7 @@ # TARGET := libfreeradius-vqp.a -SOURCES := vqp.c +SOURCES := vqp.c base.c SRC_CFLAGS := -I$(top_builddir)/src diff --git a/src/protocols/vqp/base.c b/src/protocols/vqp/base.c new file mode 100644 index 00000000000..9e73948149b --- /dev/null +++ b/src/protocols/vqp/base.c @@ -0,0 +1,74 @@ +/* + * 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 +#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); +} diff --git a/src/modules/proto_vmps/vqp.c b/src/protocols/vqp/vqp.c similarity index 92% rename from src/modules/proto_vmps/vqp.c rename to src/protocols/vqp/vqp.c index 497b79c6388..85791cb6fa8 100644 --- a/src/modules/proto_vmps/vqp.c +++ b/src/protocols/vqp/vqp.c @@ -1,21 +1,24 @@ /* - * 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 */ @@ -279,31 +282,20 @@ int vqp_decode(RADIUS_PACKET *packet) 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); @@ -335,7 +327,7 @@ int vqp_decode(RADIUS_PACKET *packet) * 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"); @@ -530,22 +522,22 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original) 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) { @@ -578,7 +570,8 @@ int vqp_encode(RADIUS_PACKET *packet, RADIUS_PACKET *original) 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... diff --git a/src/modules/proto_vmps/vqp.h b/src/protocols/vqp/vqp.h similarity index 57% rename from src/modules/proto_vmps/vqp.h rename to src/protocols/vqp/vqp.h index 2a8ef5d764a..8f0d35f74c9 100644 --- a/src/modules/proto_vmps/vqp.h +++ b/src/protocols/vqp/vqp.h @@ -33,20 +33,34 @@ extern "C" { 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 } diff --git a/src/modules/proto_vmps/vqpcli.pl b/src/protocols/vqp/vqpcli.pl similarity index 100% rename from src/modules/proto_vmps/vqpcli.pl rename to src/protocols/vqp/vqpcli.pl