Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/delete_payload.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2015 Tobias Brunner
3: * Copyright (C) 2005-2010 Martin Willi
4: * Copyright (C) 2010 revosec AG
5: * Copyright (C) 2005 Jan Hutter
6: * HSR Hochschule fuer Technik Rapperswil
7: *
8: * This program is free software; you can redistribute it and/or modify it
9: * under the terms of the GNU General Public License as published by the
10: * Free Software Foundation; either version 2 of the License, or (at your
11: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12: *
13: * This program is distributed in the hope that it will be useful, but
14: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16: * for more details.
17: */
18:
19: #include <stddef.h>
20:
21: #include "delete_payload.h"
22:
23:
24: typedef struct private_delete_payload_t private_delete_payload_t;
25:
26: /**
27: * Private data of an delete_payload_t object.
28: */
29: struct private_delete_payload_t {
30:
31: /**
32: * Public delete_payload_t interface.
33: */
34: delete_payload_t public;
35:
36: /**
37: * Next payload type.
38: */
39: uint8_t next_payload;
40:
41: /**
42: * Critical flag.
43: */
44: bool critical;
45:
46: /**
47: * reserved bits
48: */
49: bool reserved[8];
50:
51: /**
52: * Length of this payload.
53: */
54: uint16_t payload_length;
55:
56: /**
57: * IKEv1 Domain of Interpretation
58: */
59: uint32_t doi;
60:
61: /**
62: * Protocol ID.
63: */
64: uint8_t protocol_id;
65:
66: /**
67: * SPI Size.
68: */
69: uint8_t spi_size;
70:
71: /**
72: * Number of SPI's.
73: */
74: uint16_t spi_count;
75:
76: /**
77: * The contained SPI's.
78: */
79: chunk_t spis;
80:
81: /**
82: * Payload type, PLV2_DELETE or PLV1_DELETE
83: */
84: payload_type_t type;
85: };
86:
87: /**
88: * Encoding rules for an IKEv2 delete payload.
89: */
90: static encoding_rule_t encodings_v2[] = {
91: /* 1 Byte next payload type, stored in the field next_payload */
92: { U_INT_8, offsetof(private_delete_payload_t, next_payload) },
93: /* the critical bit */
94: { FLAG, offsetof(private_delete_payload_t, critical) },
95: /* 7 Bit reserved bits */
96: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[0]) },
97: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[1]) },
98: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[2]) },
99: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[3]) },
100: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[4]) },
101: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[5]) },
102: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[6]) },
103: /* Length of the whole payload*/
104: { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) },
105: { U_INT_8, offsetof(private_delete_payload_t, protocol_id) },
106: { U_INT_8, offsetof(private_delete_payload_t, spi_size) },
107: { U_INT_16, offsetof(private_delete_payload_t, spi_count) },
108: /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
109: { CHUNK_DATA, offsetof(private_delete_payload_t, spis) },
110: };
111:
112: /*
113: 1 2 3
114: 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
115: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116: ! Next Payload !C! RESERVED ! Payload Length !
117: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118: ! Protocol ID ! SPI Size ! # of SPIs !
119: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120: ! !
121: ~ Security Parameter Index(es) (SPI) ~
122: ! !
123: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124: */
125:
126: /**
127: * Encoding rules for an IKEv1 delete payload.
128: */
129: static encoding_rule_t encodings_v1[] = {
130: /* 1 Byte next payload type, stored in the field next_payload */
131: { U_INT_8, offsetof(private_delete_payload_t, next_payload) },
132: /* 8 Bit reserved bits */
133: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[0]) },
134: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[1]) },
135: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[2]) },
136: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[3]) },
137: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[4]) },
138: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[5]) },
139: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[6]) },
140: { RESERVED_BIT, offsetof(private_delete_payload_t, reserved[7]) },
141: /* Length of the whole payload*/
142: { PAYLOAD_LENGTH, offsetof(private_delete_payload_t, payload_length) },
143: /* Domain of interpretation */
144: { U_INT_32, offsetof(private_delete_payload_t, doi) },
145: { U_INT_8, offsetof(private_delete_payload_t, protocol_id) },
146: { U_INT_8, offsetof(private_delete_payload_t, spi_size) },
147: { U_INT_16, offsetof(private_delete_payload_t, spi_count) },
148: /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
149: { CHUNK_DATA, offsetof(private_delete_payload_t, spis) },
150: };
151:
152: /*
153: 1 2 3
154: 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
155: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156: ! Next Payload !C! RESERVED ! Payload Length !
157: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158: ! DOI !
159: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160: ! Protocol ID ! SPI Size ! # of SPIs !
161: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
162: ! !
163: ~ Security Parameter Index(es) (SPI) ~
164: ! !
165: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166: */
167:
168: METHOD(payload_t, verify, status_t,
169: private_delete_payload_t *this)
170: {
171: switch (this->protocol_id)
172: {
173: case PROTO_AH:
174: case PROTO_ESP:
175: if (this->spi_size != 4)
176: {
177: return FAILED;
178: }
179: break;
180: case PROTO_IKE:
181: case 0:
182: if (this->type == PLV2_DELETE)
183: { /* IKEv2 deletion has no spi assigned! */
184: if (this->spi_size != 0)
185: {
186: return FAILED;
187: }
188: }
189: else
190: { /* IKEv1 uses the two concatenated ISAKMP cookies as SPI */
191: if (this->spi_size != 16)
192: {
193: return FAILED;
194: }
195: }
196: break;
197: default:
198: return FAILED;
199: }
200: if (this->spis.len != (this->spi_count * this->spi_size))
201: {
202: return FAILED;
203: }
204: return SUCCESS;
205: }
206:
207: METHOD(payload_t, get_encoding_rules, int,
208: private_delete_payload_t *this, encoding_rule_t **rules)
209: {
210: if (this->type == PLV2_DELETE)
211: {
212: *rules = encodings_v2;
213: return countof(encodings_v2);
214: }
215: *rules = encodings_v1;
216: return countof(encodings_v1);
217: }
218:
219: METHOD(payload_t, get_header_length, int,
220: private_delete_payload_t *this)
221: {
222: if (this->type == PLV2_DELETE)
223: {
224: return 8;
225: }
226: return 12;
227: }
228:
229: METHOD(payload_t, get_payload_type, payload_type_t,
230: private_delete_payload_t *this)
231: {
232: return this->type;
233: }
234:
235: METHOD(payload_t, get_next_type, payload_type_t,
236: private_delete_payload_t *this)
237: {
238: return this->next_payload;
239: }
240:
241: METHOD(payload_t, set_next_type, void,
242: private_delete_payload_t *this,payload_type_t type)
243: {
244: this->next_payload = type;
245: }
246:
247: METHOD(payload_t, get_length, size_t,
248: private_delete_payload_t *this)
249: {
250: return this->payload_length;
251: }
252:
253: METHOD(delete_payload_t, get_protocol_id, protocol_id_t,
254: private_delete_payload_t *this)
255: {
256: return this->protocol_id;
257: }
258:
259: METHOD(delete_payload_t, add_spi, void,
260: private_delete_payload_t *this, uint32_t spi)
261: {
262: switch (this->protocol_id)
263: {
264: case PROTO_AH:
265: case PROTO_ESP:
266: this->spi_count++;
267: this->payload_length += sizeof(spi);
268: this->spis = chunk_cat("mc", this->spis, chunk_from_thing(spi));
269: break;
270: default:
271: break;
272: }
273: }
274:
275: METHOD(delete_payload_t, set_ike_spi, void,
276: private_delete_payload_t *this, uint64_t spi_i, uint64_t spi_r)
277: {
278: free(this->spis.ptr);
279: this->spis = chunk_cat("cc", chunk_from_thing(spi_i),
280: chunk_from_thing(spi_r));
281: this->spi_count = 1;
282: this->payload_length = get_header_length(this) + this->spi_size;
283: }
284:
285: METHOD(delete_payload_t, get_ike_spi, bool,
286: private_delete_payload_t *this, uint64_t *spi_i, uint64_t *spi_r)
287: {
288: if (this->protocol_id != PROTO_IKE ||
289: this->spis.len < 2 * sizeof(uint64_t))
290: {
291: return FALSE;
292: }
293: memcpy(spi_i, this->spis.ptr, sizeof(uint64_t));
294: memcpy(spi_r, this->spis.ptr + sizeof(uint64_t), sizeof(uint64_t));
295: return TRUE;
296: }
297:
298: /**
299: * SPI enumerator implementation
300: */
301: typedef struct {
302: /** implements enumerator_t */
303: enumerator_t public;
304: /** remaining SPIs */
305: chunk_t spis;
306: } spi_enumerator_t;
307:
308: METHOD(enumerator_t, spis_enumerate, bool,
309: spi_enumerator_t *this, va_list args)
310: {
311: uint32_t *spi;
312:
313: VA_ARGS_VGET(args, spi);
314:
315: if (this->spis.len >= sizeof(*spi))
316: {
317: memcpy(spi, this->spis.ptr, sizeof(*spi));
318: this->spis = chunk_skip(this->spis, sizeof(*spi));
319: return TRUE;
320: }
321: return FALSE;
322: }
323:
324: METHOD(delete_payload_t, create_spi_enumerator, enumerator_t*,
325: private_delete_payload_t *this)
326: {
327: spi_enumerator_t *e;
328:
329: if (this->spi_size != sizeof(uint32_t))
330: {
331: return enumerator_create_empty();
332: }
333: INIT(e,
334: .public = {
335: .enumerate = enumerator_enumerate_default,
336: .venumerate = _spis_enumerate,
337: .destroy = (void*)free,
338: },
339: .spis = this->spis,
340: );
341: return &e->public;
342: }
343:
344: METHOD2(payload_t, delete_payload_t, destroy, void,
345: private_delete_payload_t *this)
346: {
347: free(this->spis.ptr);
348: free(this);
349: }
350:
351: /*
352: * Described in header
353: */
354: delete_payload_t *delete_payload_create(payload_type_t type,
355: protocol_id_t protocol_id)
356: {
357: private_delete_payload_t *this;
358:
359: INIT(this,
360: .public = {
361: .payload_interface = {
362: .verify = _verify,
363: .get_encoding_rules = _get_encoding_rules,
364: .get_header_length = _get_header_length,
365: .get_length = _get_length,
366: .get_next_type = _get_next_type,
367: .set_next_type = _set_next_type,
368: .get_type = _get_payload_type,
369: .destroy = _destroy,
370: },
371: .get_protocol_id = _get_protocol_id,
372: .add_spi = _add_spi,
373: .set_ike_spi = _set_ike_spi,
374: .get_ike_spi = _get_ike_spi,
375: .create_spi_enumerator = _create_spi_enumerator,
376: .destroy = _destroy,
377: },
378: .next_payload = PL_NONE,
379: .protocol_id = protocol_id,
380: .doi = IKEV1_DOI_IPSEC,
381: .type = type,
382: );
383: this->payload_length = get_header_length(this);
384:
385: if (protocol_id == PROTO_IKE)
386: {
387: if (type == PLV1_DELETE)
388: {
389: this->spi_size = 16;
390: }
391: }
392: else
393: {
394: this->spi_size = 4;
395: }
396: return &this->public;
397: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>