Annotation of embedaddon/strongswan/src/libimcv/ietf/ietf_attr_attr_request.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2012-2014 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 "imcv.h"
                     17: #include "ietf_attr_attr_request.h"
                     18: 
                     19: #include <pa_tnc/pa_tnc_msg.h>
                     20: #include <bio/bio_writer.h>
                     21: #include <bio/bio_reader.h>
                     22: #include <collections/linked_list.h>
                     23: 
                     24: #include <utils/debug.h>
                     25: 
                     26: typedef struct private_ietf_attr_attr_request_t private_ietf_attr_attr_request_t;
                     27: 
                     28: /**
                     29:  * PA-TNC Attribute Request type  (see section 4.2.1 of RFC 5792)
                     30:  *
                     31:  *                      1                   2                   3
                     32:  *  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
                     33:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     34:  * |   Reserved    |           PA-TNC Attribute Vendor ID          |
                     35:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     36:  * |                      PA-TNC Attribute Type                    |
                     37:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     38:  * |   Reserved    |           PA-TNC Attribute Vendor ID          |
                     39:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     40:  * |                      PA-TNC Attribute Type                    |
                     41:  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     42:  */
                     43: 
                     44: #define ATTR_REQUEST_ENTRY_SIZE                8
                     45: 
                     46: /**
                     47:  * Private data of an ietf_attr_attr_request_t object.
                     48:  */
                     49: struct private_ietf_attr_attr_request_t {
                     50: 
                     51:        /**
                     52:         * Public members of ietf_attr_attr_request_t
                     53:         */
                     54:        ietf_attr_attr_request_t public;
                     55: 
                     56:        /**
                     57:         * Vendor-specific attribute type
                     58:         */
                     59:        pen_type_t type;
                     60: 
                     61:        /**
                     62:         * Length of attribute value
                     63:         */
                     64:        size_t length;
                     65: 
                     66:        /**
                     67:         * Attribute value or segment
                     68:         */
                     69:        chunk_t value;
                     70: 
                     71:        /**
                     72:         * Noskip flag
                     73:         */
                     74:        bool noskip_flag;
                     75: 
                     76:        /**
                     77:         * List of requested attribute types
                     78:         */
                     79:        linked_list_t *list;
                     80: 
                     81:        /**
                     82:         * Reference count
                     83:         */
                     84:        refcount_t ref;
                     85: };
                     86: 
                     87: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
                     88:        private_ietf_attr_attr_request_t *this)
                     89: {
                     90:        return this->type;
                     91: }
                     92: 
                     93: METHOD(pa_tnc_attr_t, get_value, chunk_t,
                     94:        private_ietf_attr_attr_request_t *this)
                     95: {
                     96:        return this->value;
                     97: }
                     98: 
                     99: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
                    100:        private_ietf_attr_attr_request_t *this)
                    101: {
                    102:        return this->noskip_flag;
                    103: }
                    104: 
                    105: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
                    106:        private_ietf_attr_attr_request_t *this, bool noskip)
                    107: {
                    108:        this->noskip_flag = noskip;
                    109: }
                    110: 
                    111: METHOD(pa_tnc_attr_t, build, void,
                    112:        private_ietf_attr_attr_request_t *this)
                    113: {
                    114:        bio_writer_t *writer;
                    115:        enumerator_t *enumerator;
                    116:        pen_type_t *entry;
                    117: 
                    118:        if (this->value.ptr)
                    119:        {
                    120:                return;
                    121:        }
                    122:        writer = bio_writer_create(ATTR_REQUEST_ENTRY_SIZE *
                    123:                                                           this->list->get_count(this->list));
                    124: 
                    125:        enumerator = this->list->create_enumerator(this->list);
                    126:        while (enumerator->enumerate(enumerator, &entry))
                    127:        {
                    128:                writer->write_uint32(writer, entry->vendor_id);
                    129:                writer->write_uint32(writer, entry->type);
                    130:        }
                    131:        enumerator->destroy(enumerator);
                    132: 
                    133:        this->value = writer->extract_buf(writer);
                    134:        this->length = this->value.len;
                    135:        writer->destroy(writer);
                    136: }
                    137: 
                    138: METHOD(ietf_attr_attr_request_t, add, void,
                    139:        private_ietf_attr_attr_request_t *this, pen_t vendor_id, uint32_t type)
                    140: {
                    141:        enum_name_t *pa_attr_names;
                    142:        pen_type_t *entry;
                    143: 
                    144:        pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
                    145:                                                                                                                  vendor_id);
                    146:        if (pa_attr_names)
                    147:        {
                    148:                DBG2(DBG_TNC, "  0x%06x/0x%08x '%N/%N'", vendor_id, type,
                    149:                                                 pen_names, vendor_id, pa_attr_names, type);
                    150:        }
                    151:        else
                    152:        {
                    153:                DBG2(DBG_TNC, "  0x%06x/0x%08x '%N'", vendor_id, type,
                    154:                                                 pen_names, vendor_id);
                    155:        }
                    156:        entry = malloc_thing(pen_type_t);
                    157:        entry->vendor_id = vendor_id;
                    158:        entry->type = type;
                    159:        this->list->insert_last(this->list, entry);
                    160: }
                    161: 
                    162: METHOD(pa_tnc_attr_t, process, status_t,
                    163:        private_ietf_attr_attr_request_t *this, uint32_t *offset)
                    164: {
                    165:        bio_reader_t *reader;
                    166:        pen_t vendor_id;
                    167:        uint32_t type;
                    168:        uint8_t reserved;
                    169:        int count;
                    170: 
                    171:        *offset = 0;
                    172: 
                    173:        if (this->value.len < this->length)
                    174:        {
                    175:                return NEED_MORE;
                    176:        }
                    177: 
                    178:        count = this->value.len / ATTR_REQUEST_ENTRY_SIZE;
                    179:        if (this->value.len != ATTR_REQUEST_ENTRY_SIZE * count)
                    180:        {
                    181:                DBG1(DBG_TNC, "incorrect attribute length for IETF attribute request");
                    182:                return FAILED;
                    183:        }
                    184: 
                    185:        reader = bio_reader_create(this->value);
                    186:        while (count--)
                    187:        {
                    188:                reader->read_uint8 (reader, &reserved);
                    189:                reader->read_uint24(reader, &vendor_id);
                    190:                reader->read_uint32(reader, &type);
                    191:                add(this, vendor_id, type);
                    192:        }
                    193:        reader->destroy(reader);
                    194: 
                    195:        return SUCCESS;
                    196: }
                    197: 
                    198: METHOD(pa_tnc_attr_t, add_segment, void,
                    199:        private_ietf_attr_attr_request_t *this, chunk_t segment)
                    200: {
                    201:        this->value = chunk_cat("mc", this->value, segment);
                    202: }
                    203: 
                    204: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
                    205:        private_ietf_attr_attr_request_t *this)
                    206: {
                    207:        ref_get(&this->ref);
                    208:        return &this->public.pa_tnc_attribute;
                    209: }
                    210: 
                    211: METHOD(pa_tnc_attr_t, destroy, void,
                    212:        private_ietf_attr_attr_request_t *this)
                    213: {
                    214:        if (ref_put(&this->ref))
                    215:        {
                    216:                this->list->destroy_function(this->list, free);
                    217:                free(this->value.ptr);
                    218:                free(this);
                    219:        }
                    220: }
                    221: 
                    222: METHOD(ietf_attr_attr_request_t, create_enumerator, enumerator_t*,
                    223:        private_ietf_attr_attr_request_t *this)
                    224: {
                    225:        return this->list->create_enumerator(this->list);
                    226: }
                    227: 
                    228: /**
                    229:  * Described in header.
                    230:  */
                    231: pa_tnc_attr_t *ietf_attr_attr_request_create(pen_t vendor_id, uint32_t type)
                    232: {
                    233:        private_ietf_attr_attr_request_t *this;
                    234: 
                    235:        INIT(this,
                    236:                .public = {
                    237:                        .pa_tnc_attribute = {
                    238:                                .get_type = _get_type,
                    239:                                .get_value = _get_value,
                    240:                                .get_noskip_flag = _get_noskip_flag,
                    241:                                .set_noskip_flag = _set_noskip_flag,
                    242:                                .build = _build,
                    243:                                .process = _process,
                    244:                                .add_segment = _add_segment,
                    245:                                .get_ref = _get_ref,
                    246:                                .destroy = _destroy,
                    247:                        },
                    248:                        .add = _add,
                    249:                        .create_enumerator = _create_enumerator,
                    250:                },
                    251:                .type = { PEN_IETF, IETF_ATTR_ATTRIBUTE_REQUEST },
                    252:                .list = linked_list_create(),
                    253:                .ref = 1,
                    254:        );
                    255: 
                    256:        if (vendor_id != PEN_RESERVED)
                    257:        {
                    258:                add(this, vendor_id, type);
                    259:        }
                    260: 
                    261:        return &this->public.pa_tnc_attribute;
                    262: }
                    263: 
                    264: /**
                    265:  * Described in header.
                    266:  */
                    267: pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(size_t length,
                    268:                                                                                                           chunk_t data)
                    269: {
                    270:        private_ietf_attr_attr_request_t *this;
                    271: 
                    272:        INIT(this,
                    273:                .public = {
                    274:                        .pa_tnc_attribute = {
                    275:                                .get_type = _get_type,
                    276:                                .get_value = _get_value,
                    277:                                .get_noskip_flag = _get_noskip_flag,
                    278:                                .set_noskip_flag = _set_noskip_flag,
                    279:                                .build = _build,
                    280:                                .process = _process,
                    281:                                .add_segment = _add_segment,
                    282:                                .get_ref = _get_ref,
                    283:                                .destroy = _destroy,
                    284:                        },
                    285:                        .add = _add,
                    286:                        .create_enumerator = _create_enumerator,
                    287:                },
                    288:                .type = { PEN_IETF, IETF_ATTR_ATTRIBUTE_REQUEST },
                    289:                .length = length,
                    290:                .value = chunk_clone(data),
                    291:                .list = linked_list_create(),
                    292:                .ref = 1,
                    293:        );
                    294: 
                    295:        return &this->public.pa_tnc_attribute;
                    296: }
                    297: 

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