diff options
Diffstat (limited to 'src/libcharon/plugins/p_cscf/p_cscf_handler.c')
-rw-r--r-- | src/libcharon/plugins/p_cscf/p_cscf_handler.c | 153 |
1 files changed, 153 insertions, 0 deletions
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; +} |