2 * @file delete_payload.c
4 * @brief Implementation of delete_payload_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26 #include "delete_payload.h"
29 typedef struct private_delete_payload_t private_delete_payload_t
;
32 * Private data of an delete_payload_t object.
35 struct private_delete_payload_t
{
37 * Public delete_payload_t interface.
39 delete_payload_t
public;
44 u_int8_t next_payload
;
52 * Length of this payload.
54 u_int16_t payload_length
;
72 * The contained SPI's.
77 * List containing u_int32_t spis
79 linked_list_t
*spi_list
;
83 * Encoding rules to parse or generate a DELETE payload
85 * The defined offsets are the positions in a object of type
86 * private_delete_payload_t.
89 encoding_rule_t delete_payload_encodings
[] = {
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, nowhere stored */
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 { SPIS
, 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 * Implementation of payload_t.verify.
128 static status_t
verify(private_delete_payload_t
*this)
130 switch (this->protocol_id
)
134 if (this->spi_size
!= 4)
141 /* IKE deletion has no spi assigned! */
142 if (this->spi_size
!= 0)
150 if (this->spis
.len
!= (this->spi_count
* this->spi_size
))
158 * Implementation of delete_payload_t.get_encoding_rules.
160 static void get_encoding_rules(private_delete_payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
162 *rules
= delete_payload_encodings
;
163 *rule_count
= sizeof(delete_payload_encodings
) / sizeof(encoding_rule_t
);
167 * Implementation of payload_t.get_type.
169 static payload_type_t
get_payload_type(private_delete_payload_t
*this)
175 * Implementation of payload_t.get_next_type.
177 static payload_type_t
get_next_type(private_delete_payload_t
*this)
179 return (this->next_payload
);
183 * Implementation of payload_t.set_next_type.
185 static void set_next_type(private_delete_payload_t
*this,payload_type_t type
)
187 this->next_payload
= type
;
191 * Implementation of payload_t.get_length.
193 static size_t get_length(private_delete_payload_t
*this)
195 return this->payload_length
;
199 * Implementation of delete_payload_t.get_protocol_id.
201 static protocol_id_t
get_protocol_id (private_delete_payload_t
*this)
203 return (this->protocol_id
);
207 * Implementation of delete_payload_t.add_spi.
209 static void add_spi(private_delete_payload_t
*this, u_int32_t spi
)
211 /* only add SPIs if AH|ESP, ignore others */
212 if (this->protocol_id
== PROTO_AH
|| this->protocol_id
== PROTO_ESP
)
214 this->spi_count
+= 1;
215 this->spis
.len
+= this->spi_size
;
216 this->spis
.ptr
= realloc(this->spis
.ptr
, this->spis
.len
);
217 *(u_int32_t
*)(this->spis
.ptr
+ (this->spis
.len
/ this->spi_size
- 1)) = spi
;
220 /* reset SPI iterator list */
221 this->spi_list
->destroy(this->spi_list
);
222 this->spi_list
= NULL
;
228 * Implementation of delete_payload_t.create_spi_iterator.
230 static iterator_t
* create_spi_iterator(private_delete_payload_t
*this)
234 if (this->spi_list
== NULL
)
236 this->spi_list
= linked_list_create();
237 /* only parse SPIs if AH|ESP */
238 if (this->protocol_id
== PROTO_AH
|| this->protocol_id
== PROTO_ESP
)
240 for (i
= 0; i
< this->spi_count
; i
++)
242 this->spi_list
->insert_last(this->spi_list
, this->spis
.ptr
+ i
*
247 return this->spi_list
->create_iterator(this->spi_list
, TRUE
);
251 * Implementation of payload_t.destroy and delete_payload_t.destroy.
253 static void destroy(private_delete_payload_t
*this)
255 if (this->spis
.ptr
!= NULL
)
257 chunk_free(&this->spis
);
261 this->spi_list
->destroy(this->spi_list
);
267 * Described in header
269 delete_payload_t
*delete_payload_create(protocol_id_t protocol_id
)
271 private_delete_payload_t
*this = malloc_thing(private_delete_payload_t
);
273 /* interface functions */
274 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
275 this->public.payload_interface
.get_encoding_rules
= (void (*) (payload_t
*, encoding_rule_t
**, size_t *) ) get_encoding_rules
;
276 this->public.payload_interface
.get_length
= (size_t (*) (payload_t
*)) get_length
;
277 this->public.payload_interface
.get_next_type
= (payload_type_t (*) (payload_t
*)) get_next_type
;
278 this->public.payload_interface
.set_next_type
= (void (*) (payload_t
*,payload_type_t
)) set_next_type
;
279 this->public.payload_interface
.get_type
= (payload_type_t (*) (payload_t
*)) get_payload_type
;
280 this->public.payload_interface
.destroy
= (void (*) (payload_t
*))destroy
;
282 /* public functions */
283 this->public.destroy
= (void (*) (delete_payload_t
*)) destroy
;
284 this->public.get_protocol_id
= (protocol_id_t (*) (delete_payload_t
*)) get_protocol_id
;
285 this->public.add_spi
= (void (*) (delete_payload_t
*,u_int32_t
))add_spi
;
286 this->public.create_spi_iterator
= (iterator_t
* (*) (delete_payload_t
*)) create_spi_iterator
;
288 /* private variables */
289 this->critical
= FALSE
;
290 this->next_payload
= NO_PAYLOAD
;
291 this->payload_length
= DELETE_PAYLOAD_HEADER_LENGTH
;
292 this->protocol_id
= protocol_id
;
293 this->spi_size
= protocol_id
== PROTO_AH
|| protocol_id
== PROTO_ESP ?
4 : 0;
295 this->spis
= chunk_empty
;
296 this->spi_list
= NULL
;
298 return (&this->public);