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.
29 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
;
71 * The contained SPI's.
77 * Encoding rules to parse or generate a DELETE payload
79 * The defined offsets are the positions in a object of type
80 * private_delete_payload_t.
82 static encoding_rule_t encodings
[] = {
83 /* 1 Byte next payload type, stored in the field next_payload */
84 { U_INT_8
, offsetof(private_delete_payload_t
, next_payload
) },
85 /* the critical bit */
86 { FLAG
, offsetof(private_delete_payload_t
, critical
) },
87 /* 7 Bit reserved bits */
88 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[0]) },
89 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[1]) },
90 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[2]) },
91 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[3]) },
92 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[4]) },
93 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[5]) },
94 { RESERVED_BIT
, offsetof(private_delete_payload_t
, reserved
[6]) },
95 /* Length of the whole payload*/
96 { PAYLOAD_LENGTH
, offsetof(private_delete_payload_t
, payload_length
) },
97 { U_INT_8
, offsetof(private_delete_payload_t
, protocol_id
) },
98 { U_INT_8
, offsetof(private_delete_payload_t
, spi_size
) },
99 { U_INT_16
, offsetof(private_delete_payload_t
, spi_count
) },
100 /* some delete data bytes, length is defined in PAYLOAD_LENGTH */
101 { SPIS
, offsetof(private_delete_payload_t
, spis
) }
106 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
107 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108 ! Next Payload !C! RESERVED ! Payload Length !
109 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
110 ! Protocol ID ! SPI Size ! # of SPIs !
111 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113 ~ Security Parameter Index(es) (SPI) ~
115 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
118 METHOD(payload_t
, verify
, status_t
,
119 private_delete_payload_t
*this)
121 switch (this->protocol_id
)
125 if (this->spi_size
!= 4)
132 /* IKE deletion has no spi assigned! */
133 if (this->spi_size
!= 0)
141 if (this->spis
.len
!= (this->spi_count
* this->spi_size
))
148 METHOD(payload_t
, get_encoding_rules
, int,
149 private_delete_payload_t
*this, encoding_rule_t
**rules
)
152 return countof(encodings
);
155 METHOD(payload_t
, get_payload_type
, payload_type_t
,
156 private_delete_payload_t
*this)
161 METHOD(payload_t
, get_next_type
, payload_type_t
,
162 private_delete_payload_t
*this)
164 return this->next_payload
;
167 METHOD(payload_t
, set_next_type
, void,
168 private_delete_payload_t
*this,payload_type_t type
)
170 this->next_payload
= type
;
173 METHOD(payload_t
, get_length
, size_t,
174 private_delete_payload_t
*this)
176 return this->payload_length
;
179 METHOD(delete_payload_t
, get_protocol_id
, protocol_id_t
,
180 private_delete_payload_t
*this)
182 return this->protocol_id
;
185 METHOD(delete_payload_t
, add_spi
, void,
186 private_delete_payload_t
*this, u_int32_t spi
)
188 switch (this->protocol_id
)
193 this->payload_length
+= sizeof(spi
);
194 this->spis
= chunk_cat("mc", this->spis
, chunk_from_thing(spi
));
202 * SPI enumerator implementation
205 /** implements enumerator_t */
207 /** remaining SPIs */
211 METHOD(enumerator_t
, spis_enumerate
, bool,
212 spi_enumerator_t
*this, u_int32_t
*spi
)
214 if (this->spis
.len
>= sizeof(*spi
))
216 memcpy(spi
, this->spis
.ptr
, sizeof(*spi
));
217 this->spis
= chunk_skip(this->spis
, sizeof(*spi
));
223 METHOD(delete_payload_t
, create_spi_enumerator
, enumerator_t
*,
224 private_delete_payload_t
*this)
228 if (this->spi_size
!= sizeof(u_int32_t
))
230 return enumerator_create_empty();
234 .enumerate
= (void*)_spis_enumerate
,
235 .destroy
= (void*)free
,
242 METHOD2(payload_t
, delete_payload_t
, destroy
, void,
243 private_delete_payload_t
*this)
245 free(this->spis
.ptr
);
250 * Described in header
252 delete_payload_t
*delete_payload_create(protocol_id_t protocol_id
)
254 private_delete_payload_t
*this;
258 .payload_interface
= {
260 .get_encoding_rules
= _get_encoding_rules
,
261 .get_length
= _get_length
,
262 .get_next_type
= _get_next_type
,
263 .set_next_type
= _set_next_type
,
264 .get_type
= _get_payload_type
,
267 .get_protocol_id
= _get_protocol_id
,
269 .create_spi_enumerator
= _create_spi_enumerator
,
272 .next_payload
= NO_PAYLOAD
,
273 .payload_length
= DELETE_PAYLOAD_HEADER_LENGTH
,
274 .protocol_id
= protocol_id
,
275 .spi_size
= protocol_id
== PROTO_AH
|| protocol_id
== PROTO_ESP ?
4 : 0,
277 return &this->public;