Annotation of embedaddon/strongswan/src/libimcv/ietf/ietf_attr_attr_request.c, revision 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>