Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/transform_substructure.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2005-2010 Martin Willi
3: * Copyright (C) 2010 revosec AG
4: * Copyright (C) 2005 Jan Hutter
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #include <stddef.h>
19:
20: #include "transform_substructure.h"
21:
22: #include <encoding/payloads/transform_attribute.h>
23: #include <encoding/payloads/encodings.h>
24: #include <library.h>
25: #include <collections/linked_list.h>
26: #include <daemon.h>
27:
28: typedef struct private_transform_substructure_t private_transform_substructure_t;
29:
30: /**
31: * Private data of an transform_substructure_t object.
32: */
33: struct private_transform_substructure_t {
34:
35: /**
36: * Public transform_substructure_t interface.
37: */
38: transform_substructure_t public;
39:
40: /**
41: * Next payload type.
42: */
43: uint8_t next_payload;
44:
45: /**
46: * Reserved byte
47: */
48: uint8_t reserved[3];
49:
50: /**
51: * Length of this payload.
52: */
53: uint16_t transform_length;
54:
55: /**
56: * Type or number, Type of the transform in IKEv2, number in IKEv2.
57: */
58: uint8_t transform_ton;
59:
60: /**
61: * Transform ID, as encoded in IKEv1.
62: */
63: uint8_t transform_id_v1;
64:
65: /**
66: * Transform ID, as encoded in IKEv2.
67: */
68: uint16_t transform_id_v2;
69:
70: /**
71: * Transforms Attributes are stored in a linked_list_t.
72: */
73: linked_list_t *attributes;
74:
75: /**
76: * Payload type, PLV2_TRANSFORM_SUBSTRUCTURE or PLV1_TRANSFORM_SUBSTRUCTURE
77: */
78: payload_type_t type;
79: };
80:
81: /**
82: * Encoding rules for PLV2_TRANSFORM_SUBSTRUCTURE
83: */
84: static encoding_rule_t encodings_v2[] = {
85: /* 1 Byte next payload type, stored in the field next_payload */
86: { U_INT_8, offsetof(private_transform_substructure_t, next_payload) },
87: /* 1 Reserved Byte */
88: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[0]) },
89: /* Length of the whole transform substructure*/
90: { PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length)},
91: /* transform type */
92: { U_INT_8, offsetof(private_transform_substructure_t, transform_ton) },
93: /* transform identifier, as used by IKEv1 */
94: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) },
95: /* transform identifier, as used by IKEv2 */
96: { U_INT_16, offsetof(private_transform_substructure_t, transform_id_v2) },
97: /* Attributes in a transform attribute list */
98: { PAYLOAD_LIST + PLV2_TRANSFORM_ATTRIBUTE,
99: offsetof(private_transform_substructure_t, attributes) }
100: };
101:
102: /**
103: * Encoding rules for PLV1_TRANSFORM_SUBSTRUCTURE
104: */
105: static encoding_rule_t encodings_v1[] = {
106: /* 1 Byte next payload type, stored in the field next_payload */
107: { U_INT_8, offsetof(private_transform_substructure_t, next_payload) },
108: /* 1 Reserved Byte */
109: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[0]) },
110: /* Length of the whole transform substructure*/
111: { PAYLOAD_LENGTH, offsetof(private_transform_substructure_t, transform_length)},
112: /* transform number */
113: { U_INT_8, offsetof(private_transform_substructure_t, transform_ton)},
114: /* transform identifier, as used by IKEv1 */
115: { U_INT_8, offsetof(private_transform_substructure_t, transform_id_v1) },
116: /* transform identifier, as used by IKEv2 */
117: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[1]) },
118: { RESERVED_BYTE, offsetof(private_transform_substructure_t, reserved[2]) },
119: /* Attributes in a transform attribute list */
120: { PAYLOAD_LIST + PLV1_TRANSFORM_ATTRIBUTE,
121: offsetof(private_transform_substructure_t, attributes) }
122: };
123:
124: /*
125: 1 2 3
126: 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
127: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128: ! 0 (last) or 3 ! RESERVED ! Transform Length !
129: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130: ! Tfrm Typ or # ! Tfrm ID IKEv1 ! Transform ID IKEv2 !
131: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
132: ! !
133: ~ Transform Attributes ~
134: ! !
135: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136: */
137:
138: METHOD(payload_t, verify, status_t,
139: private_transform_substructure_t *this)
140: {
141: status_t status = SUCCESS;
142: enumerator_t *enumerator;
143: payload_t *attribute;
144:
145: if (this->next_payload != PL_NONE && this->next_payload != 3)
146: {
147: DBG1(DBG_ENC, "inconsistent next payload");
148: return FAILED;
149: }
150:
151: enumerator = this->attributes->create_enumerator(this->attributes);
152: while (enumerator->enumerate(enumerator, &attribute))
153: {
154: status = attribute->verify(attribute);
155: if (status != SUCCESS)
156: {
157: DBG1(DBG_ENC, "TRANSFORM_ATTRIBUTE verification failed");
158: break;
159: }
160: }
161: enumerator->destroy(enumerator);
162:
163: /* proposal number is checked in SA payload */
164: return status;
165: }
166:
167: METHOD(payload_t, get_encoding_rules, int,
168: private_transform_substructure_t *this, encoding_rule_t **rules)
169: {
170: if (this->type == PLV2_TRANSFORM_SUBSTRUCTURE)
171: {
172: *rules = encodings_v2;
173: return countof(encodings_v2);
174: }
175: *rules = encodings_v1;
176: return countof(encodings_v1);
177: }
178:
179: METHOD(payload_t, get_header_length, int,
180: private_transform_substructure_t *this)
181: {
182: return 8;
183: }
184:
185: METHOD(payload_t, get_type, payload_type_t,
186: private_transform_substructure_t *this)
187: {
188: return this->type;
189: }
190:
191: METHOD(payload_t, get_next_type, payload_type_t,
192: private_transform_substructure_t *this)
193: {
194: return this->next_payload;
195: }
196:
197: /**
198: * recompute the length of the payload.
199: */
200: static void compute_length(private_transform_substructure_t *this)
201: {
202: enumerator_t *enumerator;
203: payload_t *attribute;
204:
205: this->transform_length = get_header_length(this);
206: enumerator = this->attributes->create_enumerator(this->attributes);
207: while (enumerator->enumerate(enumerator, &attribute))
208: {
209: this->transform_length += attribute->get_length(attribute);
210: }
211: enumerator->destroy(enumerator);
212: }
213:
214: METHOD(payload_t, get_length, size_t,
215: private_transform_substructure_t *this)
216: {
217: return this->transform_length;
218: }
219:
220: METHOD(transform_substructure_t, add_transform_attribute, void,
221: private_transform_substructure_t *this, transform_attribute_t *attribute)
222: {
223: this->attributes->insert_last(this->attributes, attribute);
224: compute_length(this);
225: }
226:
227: METHOD(transform_substructure_t, set_is_last_transform, void,
228: private_transform_substructure_t *this, bool is_last)
229: {
230: this->next_payload = is_last ? 0: TRANSFORM_TYPE_VALUE;
231: }
232:
233: METHOD(payload_t, set_next_type, void,
234: private_transform_substructure_t *this,payload_type_t type)
235: {
236: }
237:
238: METHOD(transform_substructure_t, get_transform_type_or_number, uint8_t,
239: private_transform_substructure_t *this)
240: {
241: return this->transform_ton;
242: }
243:
244: METHOD(transform_substructure_t, get_transform_id, uint16_t,
245: private_transform_substructure_t *this)
246: {
247: if (this->type == PLV2_TRANSFORM_SUBSTRUCTURE)
248: {
249: return this->transform_id_v2;
250: }
251: return this->transform_id_v1;
252: }
253:
254: METHOD(transform_substructure_t, create_attribute_enumerator, enumerator_t*,
255: private_transform_substructure_t *this)
256: {
257: return this->attributes->create_enumerator(this->attributes);
258: }
259:
260: METHOD2(payload_t, transform_substructure_t, destroy, void,
261: private_transform_substructure_t *this)
262: {
263: this->attributes->destroy_offset(this->attributes,
264: offsetof(payload_t, destroy));
265: free(this);
266: }
267:
268: /*
269: * Described in header.
270: */
271: transform_substructure_t *transform_substructure_create(payload_type_t type)
272: {
273: private_transform_substructure_t *this;
274:
275: INIT(this,
276: .public = {
277: .payload_interface = {
278: .verify = _verify,
279: .get_encoding_rules = _get_encoding_rules,
280: .get_header_length = _get_header_length,
281: .get_length = _get_length,
282: .get_next_type = _get_next_type,
283: .set_next_type = _set_next_type,
284: .get_type = _get_type,
285: .destroy = _destroy,
286: },
287: .add_transform_attribute = _add_transform_attribute,
288: .set_is_last_transform = _set_is_last_transform,
289: .get_transform_type_or_number = _get_transform_type_or_number,
290: .get_transform_id = _get_transform_id,
291: .create_attribute_enumerator = _create_attribute_enumerator,
292: .destroy = _destroy,
293: },
294: .next_payload = PL_NONE,
295: .transform_length = get_header_length(this),
296: .attributes = linked_list_create(),
297: .type = type,
298: );
299: return &this->public;
300: }
301:
302: /*
303: * Described in header
304: */
305: transform_substructure_t *transform_substructure_create_type(payload_type_t type,
306: uint8_t type_or_number, uint16_t id)
307: {
308: private_transform_substructure_t *this;
309:
310: this = (private_transform_substructure_t*)transform_substructure_create(type);
311:
312: this->transform_ton = type_or_number;
313: if (type == PLV2_TRANSFORM_SUBSTRUCTURE)
314: {
315: this->transform_id_v2 = id;
316: }
317: else
318: {
319: this->transform_id_v1 = id;
320: }
321: return &this->public;
322: }
323:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>