Removed strayed code fragment
[strongswan.git] / src / charon / encoding / payloads / transform_attribute.c
1 /*
2 * Copyright (C) 2005-2006 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <string.h>
18 #include <stddef.h>
19
20 #include "transform_attribute.h"
21
22 #include <encoding/payloads/encodings.h>
23 #include <library.h>
24
25 typedef struct private_transform_attribute_t private_transform_attribute_t;
26
27 /**
28 * Private data of an transform_attribute_t object.
29 *
30 */
31 struct private_transform_attribute_t {
32 /**
33 * Public transform_attribute_t interface.
34 */
35 transform_attribute_t public;
36
37 /**
38 * Attribute Format Flag.
39 *
40 * - TRUE means value is stored in attribute_length_or_value
41 * - FALSE means value is stored in attribute_value
42 */
43 bool attribute_format;
44
45 /**
46 * Type of the attribute.
47 */
48 u_int16_t attribute_type;
49
50 /**
51 * Attribute Length if attribute_format is 0, attribute Value otherwise.
52 */
53 u_int16_t attribute_length_or_value;
54
55 /**
56 * Attribute value as chunk if attribute_format is 0 (FALSE).
57 */
58 chunk_t attribute_value;
59 };
60
61
62 ENUM_BEGIN(transform_attribute_type_name, ATTRIBUTE_UNDEFINED, ATTRIBUTE_UNDEFINED,
63 "ATTRIBUTE_UNDEFINED");
64 ENUM_NEXT(transform_attribute_type_name, KEY_LENGTH, KEY_LENGTH, ATTRIBUTE_UNDEFINED,
65 "KEY_LENGTH");
66 ENUM_END(transform_attribute_type_name, KEY_LENGTH);
67
68 /**
69 * Encoding rules to parse or generate a Transform attribute.
70 *
71 * The defined offsets are the positions in a object of type
72 * private_transform_attribute_t.
73 *
74 */
75 encoding_rule_t transform_attribute_encodings[] = {
76 /* Flag defining the format of this payload */
77 { ATTRIBUTE_FORMAT, offsetof(private_transform_attribute_t, attribute_format) },
78 /* type of the attribute as 15 bit unsigned integer */
79 { ATTRIBUTE_TYPE, offsetof(private_transform_attribute_t, attribute_type) },
80 /* Length or value, depending on the attribute format flag */
81 { ATTRIBUTE_LENGTH_OR_VALUE, offsetof(private_transform_attribute_t, attribute_length_or_value) },
82 /* Value of attribute if attribute format flag is zero */
83 { ATTRIBUTE_VALUE, offsetof(private_transform_attribute_t, attribute_value) }
84 };
85
86 /*
87 1 2 3
88 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
89 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90 !A! Attribute Type ! AF=0 Attribute Length !
91 !F! ! AF=1 Attribute Value !
92 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
93 ! AF=0 Attribute Value !
94 ! AF=1 Not Transmitted !
95 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96 */
97
98 /**
99 * Implementation of payload_t.verify.
100 */
101 static status_t verify(private_transform_attribute_t *this)
102 {
103 if (this->attribute_type != KEY_LENGTH)
104 {
105 return FAILED;
106 }
107
108 return SUCCESS;
109 }
110
111 /**
112 * Implementation of payload_t.get_encoding_rules.
113 */
114 static void get_encoding_rules(private_transform_attribute_t *this, encoding_rule_t **rules, size_t *rule_count)
115 {
116 *rules = transform_attribute_encodings;
117 *rule_count = sizeof(transform_attribute_encodings) / sizeof(encoding_rule_t);
118 }
119
120 /**
121 * Implementation of payload_t.get_type.
122 */
123 static payload_type_t get_type(private_transform_attribute_t *this)
124 {
125 return TRANSFORM_ATTRIBUTE;
126 }
127
128 /**
129 * Implementation of payload_t.get_next_type.
130 */
131 static payload_type_t get_next_type(private_transform_attribute_t *this)
132 {
133 return (NO_PAYLOAD);
134 }
135
136 /**
137 * Implementation of payload_t.set_next_type.
138 */
139 static void set_next_type(private_transform_attribute_t *this,payload_type_t type)
140 {
141 }
142
143 /**
144 * Implementation of transform_attribute_t.get_length.
145 */
146 static size_t get_length(private_transform_attribute_t *this)
147 {
148 if (this->attribute_format == TRUE)
149 {
150 /*Attribute size is only 4 byte */
151 return 4;
152 }
153 return (this->attribute_length_or_value + 4);
154 }
155
156 /**
157 * Implementation of transform_attribute_t.set_value_chunk.
158 */
159 static void set_value_chunk(private_transform_attribute_t *this, chunk_t value)
160 {
161 if (this->attribute_value.ptr != NULL)
162 {
163 /* free existing value */
164 free(this->attribute_value.ptr);
165 this->attribute_value.ptr = NULL;
166 this->attribute_value.len = 0;
167
168 }
169
170 if (value.len > 2)
171 {
172 this->attribute_value.ptr = clalloc(value.ptr,value.len);
173 this->attribute_value.len = value.len;
174 this->attribute_length_or_value = value.len;
175 /* attribute has not a fixed length */
176 this->attribute_format = FALSE;
177 }
178 else
179 {
180 memcpy(&(this->attribute_length_or_value),value.ptr,value.len);
181 }
182 }
183
184 /**
185 * Implementation of transform_attribute_t.set_value.
186 */
187 static void set_value(private_transform_attribute_t *this, u_int16_t value)
188 {
189 if (this->attribute_value.ptr != NULL)
190 {
191 /* free existing value */
192 free(this->attribute_value.ptr);
193 this->attribute_value.ptr = NULL;
194 this->attribute_value.len = 0;
195
196 }
197 this->attribute_length_or_value = value;
198 }
199
200 /**
201 * Implementation of transform_attribute_t.get_value_chunk.
202 */
203 static chunk_t get_value_chunk (private_transform_attribute_t *this)
204 {
205 chunk_t value;
206
207 if (this->attribute_format == FALSE)
208 {
209 value.ptr = this->attribute_value.ptr;
210 value.len = this->attribute_value.len;
211 }
212 else
213 {
214 value.ptr = (void *) &(this->attribute_length_or_value);
215 value.len = 2;
216 }
217
218 return value;
219 }
220
221 /**
222 * Implementation of transform_attribute_t.get_value.
223 */
224 static u_int16_t get_value (private_transform_attribute_t *this)
225 {
226 return this->attribute_length_or_value;
227 }
228
229
230 /**
231 * Implementation of transform_attribute_t.set_attribute_type.
232 */
233 static void set_attribute_type (private_transform_attribute_t *this, u_int16_t type)
234 {
235 this->attribute_type = type & 0x7FFF;
236 }
237
238 /**
239 * Implementation of transform_attribute_t.get_attribute_type.
240 */
241 static u_int16_t get_attribute_type (private_transform_attribute_t *this)
242 {
243 return this->attribute_type;
244 }
245
246 /**
247 * Implementation of transform_attribute_t.clone.
248 */
249 static transform_attribute_t * _clone(private_transform_attribute_t *this)
250 {
251 private_transform_attribute_t *new_clone;
252
253 new_clone = (private_transform_attribute_t *) transform_attribute_create();
254
255 new_clone->attribute_format = this->attribute_format;
256 new_clone->attribute_type = this->attribute_type;
257 new_clone->attribute_length_or_value = this->attribute_length_or_value;
258
259 if (!new_clone->attribute_format)
260 {
261 new_clone->attribute_value.ptr = clalloc(this->attribute_value.ptr,this->attribute_value.len);
262 new_clone->attribute_value.len = this->attribute_value.len;
263 }
264
265 return (transform_attribute_t *) new_clone;
266 }
267
268 /**
269 * Implementation of transform_attribute_t.destroy and payload_t.destroy.
270 */
271 static void destroy(private_transform_attribute_t *this)
272 {
273 if (this->attribute_value.ptr != NULL)
274 {
275 free(this->attribute_value.ptr);
276 }
277 free(this);
278 }
279
280 /*
281 * Described in header.
282 */
283 transform_attribute_t *transform_attribute_create()
284 {
285 private_transform_attribute_t *this = malloc_thing(private_transform_attribute_t);
286
287 /* payload interface */
288 this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
289 this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
290 this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
291 this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
292 this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
293 this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_type;
294 this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
295
296 /* public functions */
297 this->public.set_value_chunk = (void (*) (transform_attribute_t *,chunk_t)) set_value_chunk;
298 this->public.set_value = (void (*) (transform_attribute_t *,u_int16_t)) set_value;
299 this->public.get_value_chunk = (chunk_t (*) (transform_attribute_t *)) get_value_chunk;
300 this->public.get_value = (u_int16_t (*) (transform_attribute_t *)) get_value;
301 this->public.set_attribute_type = (void (*) (transform_attribute_t *,u_int16_t type)) set_attribute_type;
302 this->public.get_attribute_type = (u_int16_t (*) (transform_attribute_t *)) get_attribute_type;
303 this->public.clone = (transform_attribute_t * (*) (transform_attribute_t *)) _clone;
304 this->public.destroy = (void (*) (transform_attribute_t *)) destroy;
305
306 /* set default values of the fields */
307 this->attribute_format = TRUE;
308 this->attribute_type = 0;
309 this->attribute_length_or_value = 0;
310 this->attribute_value.ptr = NULL;
311 this->attribute_value.len = 0;
312
313 return (&(this->public));
314 }
315
316 /*
317 * Described in header.
318 */
319 transform_attribute_t *transform_attribute_create_key_length(u_int16_t key_length)
320 {
321 transform_attribute_t *attribute = transform_attribute_create();
322 attribute->set_attribute_type(attribute,KEY_LENGTH);
323 attribute->set_value(attribute,key_length);
324 return attribute;
325 }