Annotation of embedaddon/strongswan/src/libimcv/ita/ita_attr_settings.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: #define _GNU_SOURCE /* for stdndup() */
17: #include <string.h>
18:
19: #include "ita_attr.h"
20: #include "ita_attr_settings.h"
21:
22: #include <bio/bio_reader.h>
23: #include <bio/bio_writer.h>
24: #include <collections/linked_list.h>
25: #include <pen/pen.h>
26: #include <utils/debug.h>
27:
28: typedef struct private_ita_attr_settings_t private_ita_attr_settings_t;
29: typedef struct entry_t entry_t;
30:
31: /**
32: * Contains a settings name/value pair
33: */
34: struct entry_t {
35: char *name;
36: chunk_t value;
37: };
38:
39: /**
40: * Free an entry_t object
41: */
42: static void free_entry(entry_t *this)
43: {
44: free(this->name);
45: free(this->value.ptr);
46: free(this);
47: }
48:
49: /**
50: * ITA Settings
51: *
52: * 1 2 3
53: * 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
54: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55: * | Settings Count |
56: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
57: * | Name Length | Name (Variable Length) ~
58: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59: * ~ Name (Variable Length) ~
60: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
61: * | Value Length | Value (Variable Length) ~
62: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63: * ~ Value (Variable Length) ~
64: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65: * | Name Length | Name (Variable Length) ~
66: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67: * ~ Name (Variable Length) ~
68: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69: * | Value Length | Value (Variable Length) ~
70: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71: * ~ Value (Variable Length) ~
72: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73: * ...........................
74: */
75:
76: #define ITA_SETTINGS_MIN_SIZE 4
77:
78: /**
79: * Private data of an ita_attr_settings_t object.
80: */
81: struct private_ita_attr_settings_t {
82:
83: /**
84: * Public members of ita_attr_settings_t
85: */
86: ita_attr_settings_t public;
87:
88: /**
89: * Vendor-specific attribute type
90: */
91: pen_type_t type;
92:
93: /**
94: * Length of attribute value
95: */
96: size_t length;
97:
98: /**
99: * Attribute value or segment
100: */
101: chunk_t value;
102:
103: /**
104: * Noskip flag
105: */
106: bool noskip_flag;
107:
108: /**
109: * List of settings
110: */
111: linked_list_t *list;
112:
113: /**
114: * Reference count
115: */
116: refcount_t ref;
117: };
118:
119: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
120: private_ita_attr_settings_t *this)
121: {
122: return this->type;
123: }
124:
125: METHOD(pa_tnc_attr_t, get_value, chunk_t,
126: private_ita_attr_settings_t *this)
127: {
128: return this->value;
129: }
130:
131: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
132: private_ita_attr_settings_t *this)
133: {
134: return this->noskip_flag;
135: }
136:
137: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
138: private_ita_attr_settings_t *this, bool noskip)
139: {
140: this->noskip_flag = noskip;
141: }
142:
143: METHOD(pa_tnc_attr_t, build, void,
144: private_ita_attr_settings_t *this)
145: {
146: bio_writer_t *writer;
147: enumerator_t *enumerator;
148: entry_t *entry;
149:
150: if (this->value.ptr)
151: {
152: return;
153: }
154: writer = bio_writer_create(ITA_SETTINGS_MIN_SIZE);
155: writer->write_uint32(writer, this->list->get_count(this->list));
156:
157: enumerator = this->list->create_enumerator(this->list);
158: while (enumerator->enumerate(enumerator, &entry))
159: {
160: writer->write_data16(writer, chunk_create(entry->name,
161: strlen(entry->name)));
162: writer->write_data16(writer, entry->value);
163: }
164: enumerator->destroy(enumerator);
165:
166: this->value = writer->extract_buf(writer);
167: this->length = this->value.len;
168: writer->destroy(writer);
169: }
170:
171: METHOD(pa_tnc_attr_t, process, status_t,
172: private_ita_attr_settings_t *this, uint32_t *offset)
173: {
174: bio_reader_t *reader;
175: uint32_t count;
176: chunk_t name, value;
177: entry_t *entry;
178: status_t status = FAILED;
179:
180: *offset = 0;
181:
182: if (this->value.len < this->length)
183: {
184: return NEED_MORE;
185: }
186: if (this->value.len < ITA_SETTINGS_MIN_SIZE)
187: {
188: DBG1(DBG_TNC, "insufficient data for ITA Settings attribute");
189: return FAILED;
190: }
191:
192: reader = bio_reader_create(this->value);
193: reader->read_uint32(reader, &count);
194:
195: *offset = ITA_SETTINGS_MIN_SIZE;
196:
197: while (count--)
198: {
199: if (!reader->read_data16(reader, &name))
200: {
201: DBG1(DBG_TNC, "insufficient data for setting name");
202: goto end;
203: }
204: *offset += 2 + name.len;
205:
206: if (!reader->read_data16(reader, &value))
207: {
208: DBG1(DBG_TNC, "insufficient data for setting value");
209: goto end;
210: }
211: *offset += 2 + value.len;
212:
213: /* remove a terminating newline character */
214: if (value.len && value.ptr[value.len - 1] == '\n')
215: {
216: value.len--;
217: }
218: entry = malloc_thing(entry_t);
219: entry->name = strndup(name.ptr, name.len);
220: entry->value = chunk_clone(value);
221: this->list->insert_last(this->list, entry);
222: }
223: status = SUCCESS;
224:
225: end:
226: reader->destroy(reader);
227: return status;
228: }
229:
230: METHOD(pa_tnc_attr_t, add_segment, void,
231: private_ita_attr_settings_t *this, chunk_t segment)
232: {
233: this->value = chunk_cat("mc", this->value, segment);
234: }
235:
236: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
237: private_ita_attr_settings_t *this)
238: {
239: ref_get(&this->ref);
240: return &this->public.pa_tnc_attribute;
241: }
242:
243: METHOD(pa_tnc_attr_t, destroy, void,
244: private_ita_attr_settings_t *this)
245: {
246: if (ref_put(&this->ref))
247: {
248: this->list->destroy_function(this->list, (void*)free_entry);
249: free(this->value.ptr);
250: free(this);
251: }
252: }
253:
254: METHOD(ita_attr_settings_t, add, void,
255: private_ita_attr_settings_t *this, char *name, chunk_t value)
256: {
257: entry_t *entry;
258:
259: entry = malloc_thing(entry_t);
260: entry->name = strdup(name);
261: entry->value = chunk_clone(value);
262: this->list->insert_last(this->list, entry);
263: }
264:
265: CALLBACK(entry_filter, bool,
266: void *null, enumerator_t *orig, va_list args)
267: {
268: entry_t *entry;
269: chunk_t *value;
270: char **name;
271:
272: VA_ARGS_VGET(args, name, value);
273:
274: while (orig->enumerate(orig, &entry))
275: {
276: *name = entry->name;
277: *value = entry->value;
278: return TRUE;
279: }
280: return FALSE;
281: }
282:
283: METHOD(ita_attr_settings_t, create_enumerator, enumerator_t*,
284: private_ita_attr_settings_t *this)
285: {
286: return enumerator_create_filter(this->list->create_enumerator(this->list),
287: entry_filter, NULL, NULL);
288: }
289:
290: /**
291: * Described in header.
292: */
293: pa_tnc_attr_t *ita_attr_settings_create(void)
294: {
295: private_ita_attr_settings_t *this;
296:
297: INIT(this,
298: .public = {
299: .pa_tnc_attribute = {
300: .get_type = _get_type,
301: .get_value = _get_value,
302: .get_noskip_flag = _get_noskip_flag,
303: .set_noskip_flag = _set_noskip_flag,
304: .build = _build,
305: .process = _process,
306: .add_segment = _add_segment,
307: .get_ref = _get_ref,
308: .destroy = _destroy,
309: },
310: .add = _add,
311: .create_enumerator = _create_enumerator,
312: },
313: .type = { PEN_ITA, ITA_ATTR_SETTINGS },
314: .list = linked_list_create(),
315: .ref = 1,
316: );
317:
318: return &this->public.pa_tnc_attribute;
319: }
320:
321: /**
322: * Described in header.
323: */
324: pa_tnc_attr_t *ita_attr_settings_create_from_data(size_t length, chunk_t data)
325: {
326: private_ita_attr_settings_t *this;
327:
328: INIT(this,
329: .public = {
330: .pa_tnc_attribute = {
331: .get_type = _get_type,
332: .get_value = _get_value,
333: .get_noskip_flag = _get_noskip_flag,
334: .set_noskip_flag = _set_noskip_flag,
335: .build = _build,
336: .process = _process,
337: .add_segment = _add_segment,
338: .get_ref = _get_ref,
339: .destroy = _destroy,
340: },
341: .add = _add,
342: .create_enumerator = _create_enumerator,
343: },
344: .type = { PEN_ITA, ITA_ATTR_SETTINGS },
345: .length = length,
346: .value = chunk_clone(data),
347: .list = linked_list_create(),
348: .ref = 1,
349: );
350:
351: return &this->public.pa_tnc_attribute;
352: }
353:
354:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>