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>