Annotation of embedaddon/strongswan/src/libimcv/ietf/ietf_attr_port_filter.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2011-2015 Andreas Steffen
        !             3:  * HSR Hochschule fuer Technik Rapperswil
        !             4:  *
        !             5:  * This program is free software; you can redistribute it and/or modify it
        !             6:  * under the terms of the GNU General Public License as published by the
        !             7:  * Free Software Foundation; either version 2 of the License, or (at your
        !             8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !             9:  *
        !            10:  * This program is distributed in the hope that it will be useful, but
        !            11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            13:  * for more details.
        !            14:  */
        !            15: 
        !            16: #include "ietf_attr_port_filter.h"
        !            17: 
        !            18: #include <pa_tnc/pa_tnc_msg.h>
        !            19: #include <bio/bio_writer.h>
        !            20: #include <bio/bio_reader.h>
        !            21: #include <collections/linked_list.h>
        !            22: #include <utils/debug.h>
        !            23: 
        !            24: 
        !            25: typedef struct private_ietf_attr_port_filter_t private_ietf_attr_port_filter_t;
        !            26: typedef struct port_entry_t port_entry_t;
        !            27: 
        !            28: /**
        !            29:  * Port Filter entry
        !            30:  */
        !            31: struct port_entry_t {
        !            32:        bool      blocked;
        !            33:        uint8_t  protocol;
        !            34:        uint16_t port;
        !            35: };
        !            36: 
        !            37: /**
        !            38:  * PA-TNC Port Filter Type  (see section 4.2.6 of RFC 5792)
        !            39:  *
        !            40:  *                       1                   2                   3
        !            41:  *   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
        !            42:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            43:  *  |   Reserved  |B|    Protocol   |         Port Number           |
        !            44:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            45:  *  |   Reserved  |B|    Protocol   |         Port Number           |
        !            46:  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            47:  */
        !            48: 
        !            49: #define PORT_FILTER_ENTRY_SIZE 4
        !            50: 
        !            51: /**
        !            52:  * Private data of an ietf_attr_port_filter_t object.
        !            53:  */
        !            54: struct private_ietf_attr_port_filter_t {
        !            55: 
        !            56:        /**
        !            57:         * Public members of ietf_attr_port_filter_t
        !            58:         */
        !            59:        ietf_attr_port_filter_t public;
        !            60: 
        !            61:        /**
        !            62:         * Vendor-specific attribute type
        !            63:         */
        !            64:        pen_type_t type;
        !            65: 
        !            66:        /**
        !            67:         * Length of attribute value
        !            68:         */
        !            69:        size_t length;
        !            70: 
        !            71:        /**
        !            72:         * Attribute value or segment
        !            73:         */
        !            74:        chunk_t value;
        !            75: 
        !            76:        /**
        !            77:         * Noskip flag
        !            78:         */
        !            79:        bool noskip_flag;
        !            80: 
        !            81:        /**
        !            82:         * List of Port Filter entries
        !            83:         */
        !            84:        linked_list_t *ports;
        !            85: 
        !            86:        /**
        !            87:         * Reference count
        !            88:         */
        !            89:        refcount_t ref;
        !            90: };
        !            91: 
        !            92: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
        !            93:        private_ietf_attr_port_filter_t *this)
        !            94: {
        !            95:        return this->type;
        !            96: }
        !            97: 
        !            98: METHOD(pa_tnc_attr_t, get_value, chunk_t,
        !            99:        private_ietf_attr_port_filter_t *this)
        !           100: {
        !           101:        return this->value;
        !           102: }
        !           103: 
        !           104: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
        !           105:        private_ietf_attr_port_filter_t *this)
        !           106: {
        !           107:        return this->noskip_flag;
        !           108: }
        !           109: 
        !           110: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
        !           111:        private_ietf_attr_port_filter_t *this, bool noskip)
        !           112: {
        !           113:        this->noskip_flag = noskip;
        !           114: }
        !           115: 
        !           116: METHOD(pa_tnc_attr_t, build, void,
        !           117:        private_ietf_attr_port_filter_t *this)
        !           118: {
        !           119:        bio_writer_t *writer;
        !           120:        enumerator_t *enumerator;
        !           121:        port_entry_t *entry;
        !           122: 
        !           123:        if (this->value.ptr)
        !           124:        {
        !           125:                return;
        !           126:        }
        !           127:        writer = bio_writer_create(this->ports->get_count(this->ports) *
        !           128:                                                           PORT_FILTER_ENTRY_SIZE);
        !           129: 
        !           130:        enumerator = this->ports->create_enumerator(this->ports);
        !           131:        while (enumerator->enumerate(enumerator, &entry))
        !           132:        {
        !           133:                writer->write_uint8 (writer, entry->blocked ? 0x01 : 0x00);
        !           134:                writer->write_uint8 (writer, entry->protocol);
        !           135:                writer->write_uint16(writer, entry->port);
        !           136:        }
        !           137:        enumerator->destroy(enumerator);
        !           138: 
        !           139:        this->value = writer->extract_buf(writer);
        !           140:        this->length = this->value.len;
        !           141:        writer->destroy(writer);
        !           142: }
        !           143: 
        !           144: METHOD(pa_tnc_attr_t, process, status_t,
        !           145:        private_ietf_attr_port_filter_t *this, uint32_t *offset)
        !           146: {
        !           147:        bio_reader_t *reader;
        !           148:        port_entry_t *entry;
        !           149:        uint8_t blocked;
        !           150: 
        !           151:        *offset = 0;
        !           152: 
        !           153:        if (this->value.len < this->length)
        !           154:        {
        !           155:                return NEED_MORE;
        !           156:        }
        !           157:        if (this->value.len % PORT_FILTER_ENTRY_SIZE)
        !           158:        {
        !           159:                DBG1(DBG_TNC, "ietf port filter attribute value is not a multiple of %d",
        !           160:                         PORT_FILTER_ENTRY_SIZE);
        !           161:                return FAILED;
        !           162:        }
        !           163:        reader = bio_reader_create(this->value);
        !           164: 
        !           165:        while (reader->remaining(reader))
        !           166:        {
        !           167:                entry = malloc_thing(port_entry_t);
        !           168:                reader->read_uint8 (reader, &blocked);
        !           169:                entry->blocked = blocked & 0x01;
        !           170:                reader->read_uint8 (reader, &entry->protocol);
        !           171:                reader->read_uint16(reader, &entry->port);
        !           172:                this->ports->insert_last(this->ports, entry);
        !           173:        }
        !           174:        reader->destroy(reader);
        !           175: 
        !           176:        return SUCCESS;
        !           177: }
        !           178: 
        !           179: METHOD(pa_tnc_attr_t, add_segment, void,
        !           180:        private_ietf_attr_port_filter_t *this, chunk_t segment)
        !           181: {
        !           182:        this->value = chunk_cat("mc", this->value, segment);
        !           183: }
        !           184: 
        !           185: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
        !           186:        private_ietf_attr_port_filter_t *this)
        !           187: {
        !           188:        ref_get(&this->ref);
        !           189:        return &this->public.pa_tnc_attribute;
        !           190: }
        !           191: 
        !           192: METHOD(pa_tnc_attr_t, destroy, void,
        !           193:        private_ietf_attr_port_filter_t *this)
        !           194: {
        !           195:        if (ref_put(&this->ref))
        !           196:        {
        !           197:                this->ports->destroy_function(this->ports, free);
        !           198:                free(this->value.ptr);
        !           199:                free(this);
        !           200:        }
        !           201: }
        !           202: 
        !           203: METHOD(ietf_attr_port_filter_t, add_port, void,
        !           204:        private_ietf_attr_port_filter_t *this, bool blocked, uint8_t protocol,
        !           205:        uint16_t port)
        !           206: {
        !           207:        port_entry_t *entry;
        !           208: 
        !           209:        entry = malloc_thing(port_entry_t);
        !           210:        entry->blocked = blocked;
        !           211:        entry->protocol = protocol;
        !           212:        entry->port = port;
        !           213:        this->ports->insert_last(this->ports, entry);
        !           214: }
        !           215: 
        !           216: CALLBACK(port_filter, bool,
        !           217:        void *null, enumerator_t *orig, va_list args)
        !           218: {
        !           219:        port_entry_t *entry;
        !           220:        uint16_t *port;
        !           221:        uint8_t *protocol;
        !           222:        bool *blocked;
        !           223: 
        !           224:        VA_ARGS_VGET(args, blocked, protocol, port);
        !           225: 
        !           226:        if (orig->enumerate(orig, &entry))
        !           227:        {
        !           228:                *blocked = entry->blocked;
        !           229:                *protocol = entry->protocol;
        !           230:                *port = entry->port;
        !           231:                return TRUE;
        !           232:        }
        !           233:        return FALSE;
        !           234: }
        !           235: 
        !           236: METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*,
        !           237:        private_ietf_attr_port_filter_t *this)
        !           238: {
        !           239:        return enumerator_create_filter(this->ports->create_enumerator(this->ports),
        !           240:                                                                        port_filter, NULL, NULL);
        !           241: }
        !           242: 
        !           243: /**
        !           244:  * Described in header.
        !           245:  */
        !           246: pa_tnc_attr_t *ietf_attr_port_filter_create(pen_type_t type)
        !           247: {
        !           248:        private_ietf_attr_port_filter_t *this;
        !           249: 
        !           250:        INIT(this,
        !           251:                .public = {
        !           252:                        .pa_tnc_attribute = {
        !           253:                                .get_type = _get_type,
        !           254:                                .get_value = _get_value,
        !           255:                                .get_noskip_flag = _get_noskip_flag,
        !           256:                                .set_noskip_flag = _set_noskip_flag,
        !           257:                                .build = _build,
        !           258:                                .process = _process,
        !           259:                                .add_segment = _add_segment,
        !           260:                                .get_ref = _get_ref,
        !           261:                                .destroy = _destroy,
        !           262:                        },
        !           263:                        .add_port = _add_port,
        !           264:                        .create_port_enumerator = _create_port_enumerator,
        !           265:                },
        !           266:                .type = type,
        !           267:                .ports = linked_list_create(),
        !           268:                .ref = 1,
        !           269:        );
        !           270: 
        !           271:        return &this->public.pa_tnc_attribute;
        !           272: }
        !           273: 
        !           274: /**
        !           275:  * Described in header.
        !           276:  */
        !           277: pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(size_t length,
        !           278:                                                                                chunk_t data, pen_type_t type)
        !           279: {
        !           280:        private_ietf_attr_port_filter_t *this;
        !           281: 
        !           282:        INIT(this,
        !           283:                .public = {
        !           284:                        .pa_tnc_attribute = {
        !           285:                                .get_type = _get_type,
        !           286:                                .get_value = _get_value,
        !           287:                                .get_noskip_flag = _get_noskip_flag,
        !           288:                                .set_noskip_flag = _set_noskip_flag,
        !           289:                                .build = _build,
        !           290:                                .process = _process,
        !           291:                                .add_segment = _add_segment,
        !           292:                                .get_ref = _get_ref,
        !           293:                                .destroy = _destroy,
        !           294:                        },
        !           295:                        .add_port = _add_port,
        !           296:                        .create_port_enumerator = _create_port_enumerator,
        !           297:                },
        !           298:                .type = type,
        !           299:                .length = length,
        !           300:                .value = chunk_clone(data),
        !           301:                .ports = linked_list_create(),
        !           302:                .ref = 1,
        !           303:        );
        !           304: 
        !           305:        return &this->public.pa_tnc_attribute;
        !           306: }
        !           307: 
        !           308: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>