diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-07-01 18:10:33 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-07-01 18:10:33 +0200 |
commit | 956759533ff1488c251af55081db3c29daf34dab (patch) | |
tree | f55886857d8398521496f2723c5a65aba4688ea0 /src/libimcv/ietf | |
parent | 294c25fa60520df309a39fdff394506d849303af (diff) | |
download | strongswan-956759533ff1488c251af55081db3c29daf34dab.tar.bz2 strongswan-956759533ff1488c251af55081db3c29daf34dab.tar.xz |
added support if the IETF port filter attribute
Diffstat (limited to 'src/libimcv/ietf')
-rw-r--r-- | src/libimcv/ietf/ietf_attr_port_filter.c | 266 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_port_filter.h | 74 |
2 files changed, 340 insertions, 0 deletions
diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c new file mode 100644 index 000000000..975aa46ac --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -0,0 +1,266 @@ +/* + * Copyright (C) 2011 Andreas Steffen, HSR 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 "ietf_attr_port_filter.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/linked_list.h> +#include <debug.h> + + +typedef struct private_ietf_attr_port_filter_t private_ietf_attr_port_filter_t; +typedef struct port_entry_t port_entry_t; + +/** + * Port Filter entry + */ +struct port_entry_t { + bool blocked; + u_int8_t protocol; + u_int16_t port; +}; + +/** + * PA-TNC Port Filter Type (see section 4.2.6 of RFC 5792) + * + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved |B| Protocol | Port Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved |B| Protocol | Port Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PORT_FILTER_ENTRY_SIZE 4 + +/** + * Private data of an ietf_attr_port_filter_t object. + */ +struct private_ietf_attr_port_filter_t { + + /** + * Public members of ietf_attr_port_filter_t + */ + ietf_attr_port_filter_t public; + + /** + * Attribute vendor ID + */ + pen_t vendor_id; + + /** + * Attribute type + */ + u_int32_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * List of Port Filter entries + */ + linked_list_t *ports; +}; + +METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, + private_ietf_attr_port_filter_t *this) +{ + return this->vendor_id; +} + +METHOD(pa_tnc_attr_t, get_type, u_int32_t, + private_ietf_attr_port_filter_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_port_filter_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_port_filter_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_port_filter_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_port_filter_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + port_entry_t *entry; + + writer = bio_writer_create(this->ports->get_count(this->ports) * + PORT_FILTER_ENTRY_SIZE); + + enumerator = this->ports->create_enumerator(this->ports); + while (enumerator->enumerate(enumerator, &entry)) + { + writer->write_uint8 (writer, entry->blocked ? 0x01 : 0x00); + writer->write_uint8 (writer, entry->protocol); + writer->write_uint16(writer, entry->port); + } + enumerator->destroy(enumerator); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_port_filter_t *this) +{ + bio_reader_t *reader; + port_entry_t *entry; + u_int8_t blocked; + + if (this->value.len % PORT_FILTER_ENTRY_SIZE) + { + return FAILED; + } + reader = bio_reader_create(this->value); + + while (reader->remaining(reader)) + { + entry = malloc_thing(port_entry_t); + reader->read_uint8 (reader, &blocked); + entry->blocked = blocked & 0x01; + reader->read_uint8 (reader, &entry->protocol); + reader->read_uint16(reader, &entry->port); + this->ports->insert_last(this->ports, entry); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_port_filter_t *this) +{ + this->ports->destroy_function(this->ports, free); + free(this->value.ptr); + free(this); +} + +METHOD(ietf_attr_port_filter_t, add_port, void, + private_ietf_attr_port_filter_t *this, bool blocked, u_int8_t protocol, + u_int16_t port) +{ + port_entry_t *entry; + + entry = malloc_thing(port_entry_t); + entry->blocked = blocked; + entry->protocol = protocol; + entry->port = port; + this->ports->insert_last(this->ports, entry); +} + +/** + * Enumerate port filter entries + */ +static bool port_filter(void *null, port_entry_t **entry, + bool *blocked, void *i2, u_int8_t *protocol, void *i3, + u_int16_t *port) +{ + *blocked = (*entry)->blocked; + *protocol = (*entry)->protocol; + *port = (*entry)->port; + return TRUE; +} + +METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*, + private_ietf_attr_port_filter_t *this) +{ + return enumerator_create_filter(this->ports->create_enumerator(this->ports), + (void*)port_filter, NULL, NULL); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_port_filter_create(void) +{ + private_ietf_attr_port_filter_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_vendor_id = _get_vendor_id, + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .destroy = _destroy, + }, + .add_port = _add_port, + .create_port_enumerator = _create_port_enumerator, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PORT_FILTER, + .ports = linked_list_create(), + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) +{ + private_ietf_attr_port_filter_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_vendor_id = _get_vendor_id, + .get_type = _get_type, + .get_value = _get_value, + .build = _build, + .process = _process, + .destroy = _destroy, + }, + .add_port = _add_port, + .create_port_enumerator = _create_port_enumerator, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PORT_FILTER, + .value = chunk_clone(data), + .ports = linked_list_create(), + ); + + return &this->public.pa_tnc_attribute; +} + + diff --git a/src/libimcv/ietf/ietf_attr_port_filter.h b/src/libimcv/ietf/ietf_attr_port_filter.h new file mode 100644 index 000000000..ad5553417 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_port_filter.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 Andreas Steffen + * HSR 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 ietf_attr_port_filtert ietf_attr_port_filter + * @{ @ingroup ietf_attr_port_filter + */ + +#ifndef IETF_ATTR_PORT_FILTER_H_ +#define IETF_ATTR_PORT_FILTER_H_ + +typedef struct ietf_attr_port_filter_t ietf_attr_port_filter_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC Port Filter attribute. + * + */ +struct ietf_attr_port_filter_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Add a port entry + * + * @param blocked TRUE if blocked, FALSE if allowed + * @param protocol IP protocol type + * @param port TCP/UDP port number + */ + void (*add_port)(ietf_attr_port_filter_t *this, bool blocked, + u_int8_t protocol, u_int16_t port); + + /** + * Enumerates over all ports + * Format: bool *blocked, u_int8_t *protocol, u_int16_t *port + * + * @return enumerator + */ + enumerator_t* (*create_port_enumerator)(ietf_attr_port_filter_t *this); + +}; + +/** + * Creates an ietf_attr_port_filter_t object + * + */ +pa_tnc_attr_t* ietf_attr_port_filter_create(void); + +/** + * Creates an ietf_attr_port_filter_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_port_filter_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_PORT_FILTER_H_ @}*/ |