Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/cp_payload.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 "cp_payload.h"
21:
22: #include <encoding/payloads/encodings.h>
23: #include <collections/linked_list.h>
24:
25: ENUM(config_type_names, CFG_REQUEST, CFG_ACK,
26: "CFG_REQUEST",
27: "CFG_REPLY",
28: "CFG_SET",
29: "CFG_ACK",
30: );
31:
32: typedef struct private_cp_payload_t private_cp_payload_t;
33:
34: /**
35: * Private data of an cp_payload_t object.
36: */
37: struct private_cp_payload_t {
38:
39: /**
40: * Public cp_payload_t interface.
41: */
42: cp_payload_t public;
43:
44: /**
45: * Next payload type.
46: */
47: uint8_t next_payload;
48:
49: /**
50: * Critical flag.
51: */
52: bool critical;
53:
54: /**
55: * Reserved bits
56: */
57: bool reserved_bit[7];
58:
59: /**
60: * Reserved bytes
61: */
62: uint8_t reserved_byte[3];
63:
64: /**
65: * Length of this payload.
66: */
67: uint16_t payload_length;
68:
69: /**
70: * Identifier field, IKEv1 only
71: */
72: uint16_t identifier;
73:
74: /**
75: * List of attributes, as configuration_attribute_t
76: */
77: linked_list_t *attributes;
78:
79: /**
80: * Config Type.
81: */
82: uint8_t cfg_type;
83:
84: /**
85: * PLV2_CONFIGURATION or PLV1_CONFIGURATION
86: */
87: payload_type_t type;
88: };
89:
90: /**
91: * Encoding rules to for an IKEv2 configuration payload
92: */
93: static encoding_rule_t encodings_v2[] = {
94: /* 1 Byte next payload type, stored in the field next_payload */
95: { U_INT_8, offsetof(private_cp_payload_t, next_payload) },
96: /* the critical bit */
97: { FLAG, offsetof(private_cp_payload_t, critical) },
98: /* 7 Bit reserved bits */
99: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
100: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
101: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
102: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
103: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
104: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
105: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
106: /* Length of the whole CP payload*/
107: { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
108: { U_INT_8, offsetof(private_cp_payload_t, cfg_type) },
109: /* 3 reserved bytes */
110: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
111: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[1])},
112: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[2])},
113: /* list of configuration attributes in a list */
114: { PAYLOAD_LIST + PLV2_CONFIGURATION_ATTRIBUTE,
115: offsetof(private_cp_payload_t, attributes) },
116: };
117:
118: /*
119: 1 2 3
120: 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
121: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122: ! Next Payload !C! RESERVED ! Payload Length !
123: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124: ! CFG Type ! RESERVED !
125: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126: ! !
127: ~ Configuration Attributes ~
128: ! !
129: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
130: */
131:
132: /**
133: * Encoding rules to for an IKEv1 configuration payload
134: */
135: static encoding_rule_t encodings_v1[] = {
136: /* 1 Byte next payload type, stored in the field next_payload */
137: { U_INT_8, offsetof(private_cp_payload_t, next_payload) },
138: /* the critical bit */
139: { FLAG, offsetof(private_cp_payload_t, critical) },
140: /* 7 Bit reserved bits */
141: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) },
142: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) },
143: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) },
144: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) },
145: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) },
146: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) },
147: { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) },
148: /* Length of the whole CP payload*/
149: { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) },
150: { U_INT_8, offsetof(private_cp_payload_t, cfg_type) },
151: /* 1 reserved bytes */
152: { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])},
153: { U_INT_16, offsetof(private_cp_payload_t, identifier)},
154: /* list of configuration attributes in a list */
155: { PAYLOAD_LIST + PLV1_CONFIGURATION_ATTRIBUTE,
156: offsetof(private_cp_payload_t, attributes) },
157: };
158:
159: /*
160: 1 2 3
161: 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
162: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163: ! Next Payload ! RESERVED ! Payload Length !
164: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165: ! CFG Type ! RESERVED ! Identifier !
166: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167: ! !
168: ~ Configuration Attributes ~
169: ! !
170: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171: */
172:
173: METHOD(payload_t, verify, status_t,
174: private_cp_payload_t *this)
175: {
176: status_t status = SUCCESS;
177: enumerator_t *enumerator;
178: payload_t *attribute;
179:
180: enumerator = this->attributes->create_enumerator(this->attributes);
181: while (enumerator->enumerate(enumerator, &attribute))
182: {
183: status = attribute->verify(attribute);
184: if (status != SUCCESS)
185: {
186: break;
187: }
188: }
189: enumerator->destroy(enumerator);
190: return status;
191: }
192:
193: METHOD(payload_t, get_encoding_rules, int,
194: private_cp_payload_t *this, encoding_rule_t **rules)
195: {
196: if (this->type == PLV2_CONFIGURATION)
197: {
198: *rules = encodings_v2;
199: return countof(encodings_v2);
200: }
201: *rules = encodings_v1;
202: return countof(encodings_v1);
203: }
204:
205: METHOD(payload_t, get_header_length, int,
206: private_cp_payload_t *this)
207: {
208: return 8;
209: }
210:
211: METHOD(payload_t, get_type, payload_type_t,
212: private_cp_payload_t *this)
213: {
214: return this->type;
215: }
216:
217: METHOD(payload_t, get_next_type, payload_type_t,
218: private_cp_payload_t *this)
219: {
220: return this->next_payload;
221: }
222:
223: METHOD(payload_t, set_next_type, void,
224: private_cp_payload_t *this,payload_type_t type)
225: {
226: this->next_payload = type;
227: }
228:
229: /**
230: * recompute the length of the payload.
231: */
232: static void compute_length(private_cp_payload_t *this)
233: {
234: enumerator_t *enumerator;
235: payload_t *attribute;
236:
237: this->payload_length = get_header_length(this);
238:
239: enumerator = this->attributes->create_enumerator(this->attributes);
240: while (enumerator->enumerate(enumerator, &attribute))
241: {
242: this->payload_length += attribute->get_length(attribute);
243: }
244: enumerator->destroy(enumerator);
245: }
246:
247: METHOD(payload_t, get_length, size_t,
248: private_cp_payload_t *this)
249: {
250: return this->payload_length;
251: }
252:
253: METHOD(cp_payload_t, create_attribute_enumerator, enumerator_t*,
254: private_cp_payload_t *this)
255: {
256: return this->attributes->create_enumerator(this->attributes);
257: }
258:
259: METHOD(cp_payload_t, add_attribute, void,
260: private_cp_payload_t *this, configuration_attribute_t *attribute)
261: {
262: this->attributes->insert_last(this->attributes, attribute);
263: compute_length(this);
264: }
265:
266: METHOD(cp_payload_t, get_config_type, config_type_t,
267: private_cp_payload_t *this)
268: {
269: return this->cfg_type;
270: }
271:
272: METHOD(cp_payload_t, get_identifier, uint16_t,
273: private_cp_payload_t *this)
274: {
275: return this->identifier;
276: }
277: METHOD(cp_payload_t, set_identifier, void,
278: private_cp_payload_t *this, uint16_t identifier)
279: {
280: this->identifier = identifier;
281: }
282:
283: METHOD2(payload_t, cp_payload_t, destroy, void,
284: private_cp_payload_t *this)
285: {
286: this->attributes->destroy_offset(this->attributes,
287: offsetof(configuration_attribute_t, destroy));
288: free(this);
289: }
290:
291: /*
292: * Described in header.
293: */
294: cp_payload_t *cp_payload_create_type(payload_type_t type, config_type_t cfg_type)
295: {
296: private_cp_payload_t *this;
297:
298: INIT(this,
299: .public = {
300: .payload_interface = {
301: .verify = _verify,
302: .get_encoding_rules = _get_encoding_rules,
303: .get_header_length = _get_header_length,
304: .get_length = _get_length,
305: .get_next_type = _get_next_type,
306: .set_next_type = _set_next_type,
307: .get_type = _get_type,
308: .destroy = _destroy,
309: },
310: .create_attribute_enumerator = _create_attribute_enumerator,
311: .add_attribute = _add_attribute,
312: .get_type = _get_config_type,
313: .get_identifier = _get_identifier,
314: .set_identifier = _set_identifier,
315: .destroy = _destroy,
316: },
317: .next_payload = PL_NONE,
318: .payload_length = get_header_length(this),
319: .attributes = linked_list_create(),
320: .cfg_type = cfg_type,
321: .type = type,
322: );
323: return &this->public;
324: }
325:
326: /*
327: * Described in header.
328: */
329: cp_payload_t *cp_payload_create(payload_type_t type)
330: {
331: return cp_payload_create_type(type, CFG_REQUEST);
332: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>