diff options
author | Tobias Brunner <tobias@strongswan.org> | 2016-02-04 18:26:29 +0100 |
---|---|---|
committer | Tobias Brunner <tobias@strongswan.org> | 2016-03-10 11:57:38 +0100 |
commit | 3d91d013cc4b0d9da69ecc800016db6164b2a7fc (patch) | |
tree | 6b647fc122da551976286aab8bedd78422870bc3 | |
parent | 12ac5fac1a437e4ff88e03b3841d521a6d59932a (diff) | |
download | strongswan-3d91d013cc4b0d9da69ecc800016db6164b2a7fc.tar.bz2 strongswan-3d91d013cc4b0d9da69ecc800016db6164b2a7fc.tar.xz |
p-cscf: Add attribute handler for P-CSCF server addresses
-rw-r--r-- | src/libcharon/plugins/p_cscf/Makefile.am | 3 | ||||
-rw-r--r-- | src/libcharon/plugins/p_cscf/p_cscf_handler.c | 153 | ||||
-rw-r--r-- | src/libcharon/plugins/p_cscf/p_cscf_handler.h | 49 | ||||
-rw-r--r-- | src/libcharon/plugins/p_cscf/p_cscf_plugin.c | 39 |
4 files changed, 243 insertions, 1 deletions
diff --git a/src/libcharon/plugins/p_cscf/Makefile.am b/src/libcharon/plugins/p_cscf/Makefile.am index 178981704..1e00a56a8 100644 --- a/src/libcharon/plugins/p_cscf/Makefile.am +++ b/src/libcharon/plugins/p_cscf/Makefile.am @@ -13,6 +13,7 @@ plugin_LTLIBRARIES = libstrongswan-p-cscf.la endif libstrongswan_p_cscf_la_SOURCES = \ - p_cscf_plugin.c p_cscf_plugin.h + p_cscf_plugin.c p_cscf_plugin.h \ + p_cscf_handler.c p_cscf_handler.h libstrongswan_p_cscf_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/p_cscf/p_cscf_handler.c b/src/libcharon/plugins/p_cscf/p_cscf_handler.c new file mode 100644 index 000000000..15313ea6a --- /dev/null +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +#include "p_cscf_handler.h" + +#include <networking/host.h> +#include <utils/debug.h> + +typedef struct private_p_cscf_handler_t private_p_cscf_handler_t; + +/** + * Private data + */ +struct private_p_cscf_handler_t { + + /** + * Public interface + */ + p_cscf_handler_t public; +}; + +METHOD(attribute_handler_t, handle, bool, + private_p_cscf_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + host_t *server; + int family = AF_INET6; + + switch (type) + { + case P_CSCF_IP4_ADDRESS: + family = AF_INET; + /* fall-through */ + case P_CSCF_IP6_ADDRESS: + server = host_create_from_chunk(family, data, 0); + if (!server) + { + DBG1(DBG_CFG, "received invalid P-CSCF server IP"); + return FALSE; + } + DBG1(DBG_CFG, "received P-CSCF server IP %H", server); + server->destroy(server); + return TRUE; + default: + return FALSE; + } +} + +METHOD(attribute_handler_t, release, void, + private_p_cscf_handler_t *this, ike_sa_t *ike_sa, + configuration_attribute_type_t type, chunk_t data) +{ + switch (type) + { + case P_CSCF_IP4_ADDRESS: + case P_CSCF_IP6_ADDRESS: + /* nothing to do as we only log the server IPs */ + break; + default: + break; + } +} + +/** + * Data for attribute enumerator + */ +typedef struct { + enumerator_t public; + bool request_ipv4; + bool request_ipv6; +} attr_enumerator_t; + +METHOD(enumerator_t, enumerate_attrs, bool, + attr_enumerator_t *this, configuration_attribute_type_t *type, + chunk_t *data) +{ + if (this->request_ipv4) + { + *type = P_CSCF_IP4_ADDRESS; + *data = chunk_empty; + this->request_ipv4 = FALSE; + return TRUE; + } + if (this->request_ipv6) + { + *type = P_CSCF_IP6_ADDRESS; + *data = chunk_empty; + this->request_ipv6 = FALSE; + return TRUE; + } + return FALSE; +} + +METHOD(attribute_handler_t, create_attribute_enumerator, enumerator_t *, + private_p_cscf_handler_t *this, ike_sa_t *ike_sa, + linked_list_t *vips) +{ + attr_enumerator_t *enumerator; + + if (ike_sa->get_version(ike_sa) == IKEV1) + { + return enumerator_create_empty(); + } + + INIT(enumerator, + .public = { + .enumerate = (void*)_enumerate_attrs, + .destroy = (void*)free, + }, + .request_ipv4 = TRUE, + .request_ipv6 = TRUE, + ); + return &enumerator->public; +} + +METHOD(p_cscf_handler_t, destroy, void, + private_p_cscf_handler_t *this) +{ + free(this); +} + +/** + * See header + */ +p_cscf_handler_t *p_cscf_handler_create() +{ + private_p_cscf_handler_t *this; + + INIT(this, + .public = { + .handler = { + .handle = _handle, + .release = _release, + .create_attribute_enumerator = _create_attribute_enumerator, + }, + .destroy = _destroy, + }, + ); + + return &this->public; +} diff --git a/src/libcharon/plugins/p_cscf/p_cscf_handler.h b/src/libcharon/plugins/p_cscf/p_cscf_handler.h new file mode 100644 index 000000000..ad4f1acce --- /dev/null +++ b/src/libcharon/plugins/p_cscf/p_cscf_handler.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 Tobias Brunner + * Hochschule fuer Technik Rapperswil + * + * 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. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * 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. + */ + +/** + * @defgroup p_cscf_handler p_cscf_handler + * @{ @ingroup p_cscf + */ + +#ifndef P_CSCF_HANDLER_H_ +#define P_CSCF_HANDLER_H_ + +#include <attributes/attribute_handler.h> + +typedef struct p_cscf_handler_t p_cscf_handler_t; + +/** + * Attribute handler for P-CSCF server addresses. + */ +struct p_cscf_handler_t { + + /** + * Implements attribute_handler_t. + */ + attribute_handler_t handler; + + /** + * Destroy a p_cscf_handler_t. + */ + void (*destroy)(p_cscf_handler_t *this); +}; + +/** + * Create an p_cscf_handler_t instance. + */ +p_cscf_handler_t *p_cscf_handler_create(); + +#endif /** P_CSCF_HANDLER_H_ @}*/ diff --git a/src/libcharon/plugins/p_cscf/p_cscf_plugin.c b/src/libcharon/plugins/p_cscf/p_cscf_plugin.c index ff4753e87..8e2bc727e 100644 --- a/src/libcharon/plugins/p_cscf/p_cscf_plugin.c +++ b/src/libcharon/plugins/p_cscf/p_cscf_plugin.c @@ -14,6 +14,7 @@ */ #include "p_cscf_plugin.h" +#include "p_cscf_handler.h" #include <daemon.h> @@ -28,6 +29,11 @@ struct private_p_cscf_plugin_t { * Public interface */ p_cscf_plugin_t public; + + /** + * P-CSCF server address attribute handler + */ + p_cscf_handler_t *handler; }; METHOD(plugin_t, get_name, char*, @@ -36,9 +42,40 @@ METHOD(plugin_t, get_name, char*, return "p-cscf"; } +/** + * Register handler + */ +static bool plugin_cb(private_p_cscf_plugin_t *this, + plugin_feature_t *feature, bool reg, void *cb_data) +{ + if (reg) + { + charon->attributes->add_handler(charon->attributes, + &this->handler->handler); + } + else + { + charon->attributes->remove_handler(charon->attributes, + &this->handler->handler); + } + return TRUE; +} + +METHOD(plugin_t, get_features, int, + private_p_cscf_plugin_t *this, plugin_feature_t *features[]) +{ + static plugin_feature_t f[] = { + PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL), + PLUGIN_PROVIDE(CUSTOM, "p-cscf"), + }; + *features = f; + return countof(f); +} + METHOD(plugin_t, destroy, void, private_p_cscf_plugin_t *this) { + this->handler->destroy(this->handler); free(this); } @@ -53,9 +90,11 @@ plugin_t *p_cscf_plugin_create() .public = { .plugin = { .get_name = _get_name, + .get_features = _get_features, .destroy = _destroy, }, }, + .handler = p_cscf_handler_create(), ); return &this->public.plugin; |