Annotation of embedaddon/strongswan/src/libimcv/ietf/swima/ietf_swima_attr_req.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2017 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_swima_attr_req.h"
17: #include "swima/swima_record.h"
18:
19: #include <pa_tnc/pa_tnc_msg.h>
20: #include <bio/bio_writer.h>
21: #include <bio/bio_reader.h>
22: #include <utils/debug.h>
23: #include <collections/linked_list.h>
24:
25: typedef struct private_ietf_swima_attr_req_t private_ietf_swima_attr_req_t;
26:
27: /**
28: * SW Request
29: * see section 5.7 of RFC 8412 SWIMA
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: * |C|S|R| Reserved| Software Identifier Count |
35: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36: * | Request ID |
37: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
38: * | Earliest EID |
39: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
40: * | Software Identifier Length | Software Identifier (Var Len) |
41: * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42: */
43:
44: #define SW_REQ_RESERVED_MASK 0xE0
45:
46: /**
47: * Private data of an ietf_swima_attr_req_t object.
48: */
49: struct private_ietf_swima_attr_req_t {
50:
51: /**
52: * Public members of ietf_swima_attr_req_t
53: */
54: ietf_swima_attr_req_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: * SWID request flags
78: */
79: uint8_t flags;
80:
81: /**
82: * Request ID
83: */
84: uint32_t request_id;
85:
86: /**
87: * Inventory of Target Software Identifiers
88: */
89: swima_inventory_t *targets;
90:
91: /**
92: * Reference count
93: */
94: refcount_t ref;
95: };
96:
97: METHOD(pa_tnc_attr_t, get_type, pen_type_t,
98: private_ietf_swima_attr_req_t *this)
99: {
100: return this->type;
101: }
102:
103: METHOD(pa_tnc_attr_t, get_value, chunk_t,
104: private_ietf_swima_attr_req_t *this)
105: {
106: return this->value;
107: }
108:
109: METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
110: private_ietf_swima_attr_req_t *this)
111: {
112: return this->noskip_flag;
113: }
114:
115: METHOD(pa_tnc_attr_t, set_noskip_flag,void,
116: private_ietf_swima_attr_req_t *this, bool noskip)
117: {
118: this->noskip_flag = noskip;
119: }
120:
121: METHOD(pa_tnc_attr_t, build, void,
122: private_ietf_swima_attr_req_t *this)
123: {
124: bio_writer_t *writer;
125: swima_record_t *sw_record;
126: uint32_t earliest_eid;
127: chunk_t sw_id;
128: enumerator_t *enumerator;
129:
130: if (this->value.ptr)
131: {
132: return;
133: }
134: earliest_eid = this->targets->get_eid(this->targets, NULL);
135:
136: writer = bio_writer_create(IETF_SWIMA_REQ_MIN_SIZE);
137: writer->write_uint8 (writer, this->flags);
138: writer->write_uint24(writer, this->targets->get_count(this->targets));
139: writer->write_uint32(writer, this->request_id);
140: writer->write_uint32(writer, earliest_eid);
141:
142: enumerator = this->targets->create_enumerator(this->targets);
143: while (enumerator->enumerate(enumerator, &sw_record))
144: {
145: sw_id = sw_record->get_sw_id(sw_record, NULL);
146: writer->write_data16(writer, sw_id);
147: }
148: enumerator->destroy(enumerator);
149:
150: this->value = writer->extract_buf(writer);
151: this->length = this->value.len;
152: writer->destroy(writer);
153: }
154:
155: METHOD(pa_tnc_attr_t, process, status_t,
156: private_ietf_swima_attr_req_t *this, uint32_t *offset)
157: {
158: bio_reader_t *reader;
159: swima_record_t *sw_record;
160: uint32_t sw_id_count, earliest_eid;
161: chunk_t sw_id;
162:
163: *offset = 0;
164:
165: if (this->value.len < this->length)
166: {
167: return NEED_MORE;
168: }
169: if (this->value.len < IETF_SWIMA_REQ_MIN_SIZE)
170: {
171: DBG1(DBG_TNC, "insufficient data for SW Request");
172: return FAILED;
173: }
174:
175: reader = bio_reader_create(this->value);
176: reader->read_uint8 (reader, &this->flags);
177: reader->read_uint24(reader, &sw_id_count);
178: reader->read_uint32(reader, &this->request_id);
179: reader->read_uint32(reader, &earliest_eid);
180:
181: *offset = IETF_SWIMA_REQ_MIN_SIZE;
182: this->flags &= SW_REQ_RESERVED_MASK;
183: this->targets->set_eid(this->targets, earliest_eid, 0);
184:
185: while (sw_id_count--)
186: {
187: if (!reader->read_data16(reader, &sw_id))
188: {
189: DBG1(DBG_TNC, "insufficient data for Software ID");
190: reader->destroy(reader);
191: return FAILED;
192: }
193: *offset += 2 + sw_id.len;
194:
195: sw_record = swima_record_create(0, sw_id, chunk_empty);
196: this->targets->add(this->targets, sw_record);
197: }
198: reader->destroy(reader);
199:
200: return SUCCESS;
201: }
202:
203: METHOD(pa_tnc_attr_t, add_segment, void,
204: private_ietf_swima_attr_req_t *this, chunk_t segment)
205: {
206: this->value = chunk_cat("mc", this->value, segment);
207: }
208:
209: METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
210: private_ietf_swima_attr_req_t *this)
211: {
212: ref_get(&this->ref);
213: return &this->public.pa_tnc_attribute;
214: }
215:
216: METHOD(pa_tnc_attr_t, destroy, void,
217: private_ietf_swima_attr_req_t *this)
218: {
219: if (ref_put(&this->ref))
220: {
221: this->targets->destroy(this->targets);
222: free(this->value.ptr);
223: free(this);
224: }
225: }
226:
227: METHOD(ietf_swima_attr_req_t, get_flags, uint8_t,
228: private_ietf_swima_attr_req_t *this)
229: {
230: return this->flags;
231: }
232:
233: METHOD(ietf_swima_attr_req_t, get_request_id, uint32_t,
234: private_ietf_swima_attr_req_t *this)
235: {
236: return this->request_id;
237: }
238:
239: METHOD(ietf_swima_attr_req_t, set_targets, void,
240: private_ietf_swima_attr_req_t *this, swima_inventory_t *targets)
241: {
242: this->targets->destroy(this->targets);
243: this->targets = targets->get_ref(targets);
244: }
245:
246: METHOD(ietf_swima_attr_req_t, get_targets, swima_inventory_t*,
247: private_ietf_swima_attr_req_t *this)
248: {
249: return this->targets;
250: }
251:
252: /**
253: * Described in header.
254: */
255: pa_tnc_attr_t *ietf_swima_attr_req_create(uint8_t flags, uint32_t request_id)
256: {
257: private_ietf_swima_attr_req_t *this;
258:
259: INIT(this,
260: .public = {
261: .pa_tnc_attribute = {
262: .get_type = _get_type,
263: .get_value = _get_value,
264: .get_noskip_flag = _get_noskip_flag,
265: .set_noskip_flag = _set_noskip_flag,
266: .build = _build,
267: .process = _process,
268: .add_segment = _add_segment,
269: .get_ref = _get_ref,
270: .destroy = _destroy,
271: },
272: .get_flags = _get_flags,
273: .get_request_id = _get_request_id,
274: .set_targets = _set_targets,
275: .get_targets = _get_targets,
276: },
277: .type = { PEN_IETF, IETF_ATTR_SWIMA_REQUEST },
278: .flags = flags & SW_REQ_RESERVED_MASK,
279: .request_id = request_id,
280: .targets = swima_inventory_create(),
281: .ref = 1,
282: );
283:
284: return &this->public.pa_tnc_attribute;
285: }
286:
287: /**
288: * Described in header.
289: */
290: pa_tnc_attr_t *ietf_swima_attr_req_create_from_data(size_t length, chunk_t data)
291: {
292: private_ietf_swima_attr_req_t *this;
293:
294: INIT(this,
295: .public = {
296: .pa_tnc_attribute = {
297: .get_type = _get_type,
298: .get_value = _get_value,
299: .get_noskip_flag = _get_noskip_flag,
300: .set_noskip_flag = _set_noskip_flag,
301: .build = _build,
302: .process = _process,
303: .add_segment = _add_segment,
304: .get_ref = _get_ref,
305: .destroy = _destroy,
306: },
307: .get_flags = _get_flags,
308: .get_request_id = _get_request_id,
309: .set_targets = _set_targets,
310: .get_targets = _get_targets,
311: },
312: .type = { PEN_IETF, IETF_ATTR_SWIMA_REQUEST },
313: .length = length,
314: .value = chunk_clone(data),
315: .targets = swima_inventory_create(),
316: .ref = 1,
317: );
318:
319: return &this->public.pa_tnc_attribute;
320: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>