4 * @brief Implementation of cp_payload_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #include "cp_payload.h"
27 #include <encoding/payloads/encodings.h>
28 #include <utils/linked_list.h>
32 * String mappings for config_type_t.
34 mapping_t config_type_m
[] = {
35 {CFG_REQUEST
, "CFG_REQUEST"},
36 {CFG_REPLY
, "CFG_REPLY"},
43 typedef struct private_cp_payload_t private_cp_payload_t
;
46 * Private data of an cp_payload_t object.
49 struct private_cp_payload_t
{
51 * Public cp_payload_t interface.
58 u_int8_t next_payload
;
66 * Length of this payload.
68 u_int16_t payload_length
;
71 * Configuration Attributes in this payload are stored in a linked_list_t.
73 linked_list_t
* attributes
;
81 * @brief Computes the length of this payload.
83 * @param this calling private_cp_payload_t object
85 void (*compute_length
) (private_cp_payload_t
*this);
89 * Encoding rules to parse or generate a IKEv2-CP Payload
91 * The defined offsets are the positions in a object of type
92 * private_cp_payload_t.
95 encoding_rule_t cp_payload_encodings
[] = {
96 /* 1 Byte next payload type, stored in the field next_payload */
97 { U_INT_8
, offsetof(private_cp_payload_t
, next_payload
) },
98 /* the critical bit */
99 { FLAG
, offsetof(private_cp_payload_t
, critical
) },
100 /* 7 Bit reserved bits, nowhere stored */
108 /* Length of the whole CP payload*/
109 { PAYLOAD_LENGTH
, offsetof(private_cp_payload_t
, payload_length
) },
110 /* Proposals are stored in a proposal substructure,
111 offset points to a linked_list_t pointer */
112 { U_INT_8
, offsetof(private_cp_payload_t
, config_type
) },
116 { CONFIGURATION_ATTRIBUTES
, offsetof(private_cp_payload_t
, attributes
) }
121 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
122 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
123 ! Next Payload !C! RESERVED ! Payload Length !
124 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
125 ! CFG Type ! RESERVED !
126 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128 ~ Configuration Attributes ~
130 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
134 * Implementation of payload_t.verify.
136 static status_t
verify(private_cp_payload_t
*this)
138 status_t status
= SUCCESS
;
139 iterator_t
*iterator
;
141 iterator
= this->attributes
->create_iterator(this->attributes
,TRUE
);
143 while(iterator
->has_next(iterator
))
145 configuration_attribute_t
*attribute
;
146 iterator
->current(iterator
,(void **)&attribute
);
147 status
= attribute
->payload_interface
.verify(&(attribute
->payload_interface
));
148 if (status
!= SUCCESS
)
154 iterator
->destroy(iterator
);
159 * Implementation of payload_t.get_encoding_rules.
161 static void get_encoding_rules(private_cp_payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
163 *rules
= cp_payload_encodings
;
164 *rule_count
= sizeof(cp_payload_encodings
) / sizeof(encoding_rule_t
);
168 * Implementation of payload_t.get_type.
170 static payload_type_t
get_type(private_cp_payload_t
*this)
172 return CONFIGURATION
;
176 * Implementation of payload_t.get_next_type.
178 static payload_type_t
get_next_type(private_cp_payload_t
*this)
180 return (this->next_payload
);
184 * Implementation of payload_t.set_next_type.
186 static void set_next_type(private_cp_payload_t
*this,payload_type_t type
)
188 this->next_payload
= type
;
192 * Implementation of payload_t.get_length.
194 static size_t get_length(private_cp_payload_t
*this)
196 this->compute_length(this);
197 return this->payload_length
;
201 * Implementation of cp_payload_t.create_configuration_attribute_iterator.
203 static iterator_t
*create_configuration_attribute_iterator (private_cp_payload_t
*this,bool forward
)
205 return this->attributes
->create_iterator(this->attributes
,forward
);
209 * Implementation of cp_payload_t.add_proposal_substructure.
211 static void add_configuration_attribute (private_cp_payload_t
*this,configuration_attribute_t
*attribute
)
213 this->attributes
->insert_last(this->attributes
,(void *) attribute
);
214 this->compute_length(this);
218 * Implementation of cp_payload_t.set_config_type.
220 static void set_config_type (private_cp_payload_t
*this,config_type_t config_type
)
222 this->config_type
= config_type
;
226 * Implementation of cp_payload_t.get_config_type.
228 static config_type_t
get_config_type (private_cp_payload_t
*this)
230 return this->config_type
;
234 * Implementation of private_cp_payload_t.compute_length.
236 static void compute_length (private_cp_payload_t
*this)
238 iterator_t
*iterator
;
239 size_t length
= CP_PAYLOAD_HEADER_LENGTH
;
240 iterator
= this->attributes
->create_iterator(this->attributes
,TRUE
);
241 while (iterator
->has_next(iterator
))
243 payload_t
*current_attribute
;
244 iterator
->current(iterator
,(void **) ¤t_attribute
);
245 length
+= current_attribute
->get_length(current_attribute
);
247 iterator
->destroy(iterator
);
249 this->payload_length
= length
;
253 * Implementation of payload_t.destroy and cp_payload_t.destroy.
255 static status_t
destroy(private_cp_payload_t
*this)
257 /* all attributes are getting destroyed */
258 while (this->attributes
->get_count(this->attributes
) > 0)
260 configuration_attribute_t
*current_attribute
;
261 this->attributes
->remove_last(this->attributes
,(void **)¤t_attribute
);
262 current_attribute
->destroy(current_attribute
);
264 this->attributes
->destroy(this->attributes
);
272 * Described in header.
274 cp_payload_t
*cp_payload_create()
276 private_cp_payload_t
*this = malloc_thing(private_cp_payload_t
);
278 /* public interface */
279 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
280 this->public.payload_interface
.get_encoding_rules
= (void (*) (payload_t
*, encoding_rule_t
**, size_t *) ) get_encoding_rules
;
281 this->public.payload_interface
.get_length
= (size_t (*) (payload_t
*)) get_length
;
282 this->public.payload_interface
.get_next_type
= (payload_type_t (*) (payload_t
*)) get_next_type
;
283 this->public.payload_interface
.set_next_type
= (void (*) (payload_t
*,payload_type_t
)) set_next_type
;
284 this->public.payload_interface
.get_type
= (payload_type_t (*) (payload_t
*)) get_type
;
285 this->public.payload_interface
.destroy
= (void (*) (payload_t
*))destroy
;
287 /* public functions */
288 this->public.create_configuration_attribute_iterator
= (iterator_t
* (*) (cp_payload_t
*,bool)) create_configuration_attribute_iterator
;
289 this->public.add_configuration_attribute
= (void (*) (cp_payload_t
*,configuration_attribute_t
*)) add_configuration_attribute
;
290 this->public.set_config_type
= (void (*) (cp_payload_t
*, config_type_t
)) set_config_type
;
291 this->public.get_config_type
= (config_type_t (*) (cp_payload_t
*)) get_config_type
;
292 this->public.destroy
= (void (*) (cp_payload_t
*)) destroy
;
295 /* private functions */
296 this->compute_length
= compute_length
;
298 /* set default values of the fields */
299 this->critical
= FALSE
;
300 this->next_payload
= NO_PAYLOAD
;
301 this->payload_length
= CP_PAYLOAD_HEADER_LENGTH
;
303 this->attributes
= linked_list_create();
304 return (&(this->public));