2 * Copyright (C) 2005-2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
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>.
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
20 #include "delete_payload.h"
23 typedef struct private_delete_payload_t private_delete_payload_t
;
26 * Private data of an delete_payload_t object.
28 struct private_delete_payload_t
{
31 * Public delete_payload_t interface.
33 delete_payload_t
public;
38 u_int8_t next_payload
;
51 * Length of this payload.
53 u_int16_t payload_length
;
56 * IKEv1 Domain of Interpretation
76 * The contained SPI's.
81 * Payload type, DELETE or DELETE_V1
87 * Encoding rules for an IKEv2 delete payload.
89 static encoding_rule_t encodings_v2
[] = {
90 /* 1 Byte next payload type, stored in the field next_payload */
91 { U_INT_8
, offsetof(private_delete_payload_t
, next_payload
) },
92 /* the critical bit */
93 { FLAG
, offsetof(private_delete_payload_t
, critical
) },
94 /* 7 Bit reserved bits */
95 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[0]) },
96 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[1]) },
97 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[2]) },
98 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[3]) },
99 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[4]) },
100 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[5]) },
101 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[6]) },
102 /* Length of the whole payload*/
103 { PAYLOAD_LENGTH
, offsetof(private_delete_payload_t
, payload_length
) },
104 { U_INT_8
, offsetof(private_delete_payload_t
, protocol_id
) },
105 { U_INT_8
, offsetof(private_delete_payload_t
, spi_size
) },
106 { U_INT_16
, offsetof(private_delete_payload_t
, spi_count
) },
107 /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
108 { CHUNK_DATA
, offsetof(private_delete_payload_t
, spis
) },
113 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
114 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115 ! Next Payload !C! RESERVED ! Payload Length !
116 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
117 ! Protocol ID ! SPI Size ! # of SPIs !
118 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120 ~ Security Parameter Index(es) (SPI) ~
122 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
126 * Encoding rules for an IKEv1 delete payload.
128 static encoding_rule_t encodings_v1
[] = {
129 /* 1 Byte next payload type, stored in the field next_payload */
130 { U_INT_8
, offsetof(private_delete_payload_t
, next_payload
) },
131 /* 8 Bit reserved bits */
132 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[0]) },
133 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[1]) },
134 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[2]) },
135 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[3]) },
136 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[4]) },
137 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[5]) },
138 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[6]) },
139 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[7]) },
140 /* Length of the whole payload*/
141 { PAYLOAD_LENGTH
, offsetof(private_delete_payload_t
, payload_length
) },
142 /* Domain of interpretation */
143 { U_INT_32
, offsetof(private_delete_payload_t
, doi
) },
144 { U_INT_8
, offsetof(private_delete_payload_t
, protocol_id
) },
145 { U_INT_8
, offsetof(private_delete_payload_t
, spi_size
) },
146 { U_INT_16
, offsetof(private_delete_payload_t
, spi_count
) },
147 /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
148 { CHUNK_DATA
, offsetof(private_delete_payload_t
, spis
) },
153 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
154 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155 ! Next Payload !C! RESERVED ! Payload Length !
156 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159 ! Protocol ID ! SPI Size ! # of SPIs !
160 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
162 ~ Security Parameter Index(es) (SPI) ~
164 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167 METHOD(payload_t
, verify
, status_t
,
168 private_delete_payload_t
*this)
170 switch (this->protocol_id
)
174 if (this->spi_size
!= 4)
181 /* IKE deletion has no spi assigned! */
182 if (this->spi_size
!= 0)
190 if (this->spis
.len
!= (this->spi_count
* this->spi_size
))
197 METHOD(payload_t
, get_encoding_rules
, int,
198 private_delete_payload_t
*this, encoding_rule_t
**rules
)
200 if (this->type
== DELETE
)
202 *rules
= encodings_v2
;
203 return countof(encodings_v2
);
205 *rules
= encodings_v1
;
206 return countof(encodings_v1
);
209 METHOD(payload_t
, get_header_length
, int,
210 private_delete_payload_t
*this)
212 if (this->type
== DELETE
)
219 METHOD(payload_t
, get_payload_type
, payload_type_t
,
220 private_delete_payload_t
*this)
225 METHOD(payload_t
, get_next_type
, payload_type_t
,
226 private_delete_payload_t
*this)
228 return this->next_payload
;
231 METHOD(payload_t
, set_next_type
, void,
232 private_delete_payload_t
*this,payload_type_t type
)
234 this->next_payload
= type
;
237 METHOD(payload_t
, get_length
, size_t,
238 private_delete_payload_t
*this)
240 return this->payload_length
;
243 METHOD(delete_payload_t
, get_protocol_id
, protocol_id_t
,
244 private_delete_payload_t
*this)
246 return this->protocol_id
;
249 METHOD(delete_payload_t
, add_spi
, void,
250 private_delete_payload_t
*this, u_int32_t spi
)
252 switch (this->protocol_id
)
257 this->payload_length
+= sizeof(spi
);
258 this->spis
= chunk_cat("mc", this->spis
, chunk_from_thing(spi
));
266 * SPI enumerator implementation
269 /** implements enumerator_t */
271 /** remaining SPIs */
275 METHOD(enumerator_t
, spis_enumerate
, bool,
276 spi_enumerator_t
*this, u_int32_t
*spi
)
278 if (this->spis
.len
>= sizeof(*spi
))
280 memcpy(spi
, this->spis
.ptr
, sizeof(*spi
));
281 this->spis
= chunk_skip(this->spis
, sizeof(*spi
));
287 METHOD(delete_payload_t
, create_spi_enumerator
, enumerator_t
*,
288 private_delete_payload_t
*this)
292 if (this->spi_size
!= sizeof(u_int32_t
))
294 return enumerator_create_empty();
298 .enumerate
= (void*)_spis_enumerate
,
299 .destroy
= (void*)free
,
306 METHOD2(payload_t
, delete_payload_t
, destroy
, void,
307 private_delete_payload_t
*this)
309 free(this->spis
.ptr
);
314 * Described in header
316 delete_payload_t
*delete_payload_create(payload_type_t type
,
317 protocol_id_t protocol_id
)
319 private_delete_payload_t
*this;
323 .payload_interface
= {
325 .get_encoding_rules
= _get_encoding_rules
,
326 .get_header_length
= _get_header_length
,
327 .get_length
= _get_length
,
328 .get_next_type
= _get_next_type
,
329 .set_next_type
= _set_next_type
,
330 .get_type
= _get_payload_type
,
333 .get_protocol_id
= _get_protocol_id
,
335 .create_spi_enumerator
= _create_spi_enumerator
,
338 .next_payload
= NO_PAYLOAD
,
339 .payload_length
= get_header_length(this),
340 .doi
= IKEV1_DOI_IPSEC
,
341 .protocol_id
= protocol_id
,
342 .spi_size
= protocol_id
== PROTO_AH
|| protocol_id
== PROTO_ESP ?
4 : 0,
345 return &this->public;