eee5e92db0a2840d99c023f11a7d5937a2d088fc
[strongswan.git] / src / charon / encoding / payloads / id_payload.c
1 /**
2 * @file id_payload.h
3 *
4 * @brief Interface of id_payload_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Tobias Brunner
10 * Copyright (C) 2005-2006 Martin Willi
11 * Copyright (C) 2005 Jan Hutter
12 * Hochschule fuer Technik Rapperswil
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 */
24
25 #include <stddef.h>
26
27 #include "id_payload.h"
28
29 #include <daemon.h>
30 #include <encoding/payloads/encodings.h>
31
32 typedef struct private_id_payload_t private_id_payload_t;
33
34 /**
35 * Private data of an id_payload_t object.
36 *
37 */
38 struct private_id_payload_t {
39 /**
40 * Public id_payload_t interface.
41 */
42 id_payload_t public;
43
44 /**
45 * one of ID_INITIATOR, ID_RESPONDER
46 */
47 payload_type_t payload_type;
48
49 /**
50 * Next payload type.
51 */
52 payload_type_t next_payload;
53
54 /**
55 * Critical flag.
56 */
57 bool critical;
58
59 /**
60 * Length of this payload.
61 */
62 u_int16_t payload_length;
63
64 /**
65 * Type of the ID Data.
66 */
67 u_int8_t id_type;
68
69 /**
70 * The contained id data value.
71 */
72 chunk_t id_data;
73 };
74
75 /**
76 * Encoding rules to parse or generate a ID payload
77 *
78 * The defined offsets are the positions in a object of type
79 * private_id_payload_t.
80 *
81 */
82 encoding_rule_t id_payload_encodings[] = {
83 /* 1 Byte next payload type, stored in the field next_payload */
84 { U_INT_8, offsetof(private_id_payload_t, next_payload) },
85 /* the critical bit */
86 { FLAG, offsetof(private_id_payload_t, critical) },
87 /* 7 Bit reserved bits, nowhere stored */
88 { RESERVED_BIT, 0 },
89 { RESERVED_BIT, 0 },
90 { RESERVED_BIT, 0 },
91 { RESERVED_BIT, 0 },
92 { RESERVED_BIT, 0 },
93 { RESERVED_BIT, 0 },
94 { RESERVED_BIT, 0 },
95 /* Length of the whole payload*/
96 { PAYLOAD_LENGTH, offsetof(private_id_payload_t, payload_length) },
97 /* 1 Byte ID type*/
98 { U_INT_8, offsetof(private_id_payload_t, id_type) },
99 /* 3 reserved bytes */
100 { RESERVED_BYTE, 0 },
101 { RESERVED_BYTE, 0 },
102 { RESERVED_BYTE, 0 },
103 /* some id data bytes, length is defined in PAYLOAD_LENGTH */
104 { ID_DATA, offsetof(private_id_payload_t, id_data) }
105 };
106
107 /*
108 1 2 3
109 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
110 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
111 ! Next Payload !C! RESERVED ! Payload Length !
112 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
113 ! ID Type ! RESERVED |
114 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
115 ! !
116 ~ Identification Data ~
117 ! !
118 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
119 */
120
121 /**
122 * Implementation of payload_t.verify.
123 */
124 static status_t verify(private_id_payload_t *this)
125 {
126 if ((this->id_type == 0) ||
127 (this->id_type == 4) ||
128 ((this->id_type >= 6) && (this->id_type <= 8)) ||
129 ((this->id_type >= 12) && (this->id_type <= 200)))
130 {
131 /* reserved IDs */
132 DBG1(DBG_ENC, "received ID with reserved type %d", this->id_type);
133 return FAILED;
134 }
135
136 return SUCCESS;
137 }
138
139 /**
140 * Implementation of id_payload_t.get_encoding_rules.
141 */
142 static void get_encoding_rules(private_id_payload_t *this, encoding_rule_t **rules, size_t *rule_count)
143 {
144 *rules = id_payload_encodings;
145 *rule_count = sizeof(id_payload_encodings) / sizeof(encoding_rule_t);
146 }
147
148 /**
149 * Implementation of payload_t.get_type.
150 */
151 static payload_type_t get_payload_type(private_id_payload_t *this)
152 {
153 return this->payload_type;
154 }
155
156 /**
157 * Implementation of payload_t.get_next_type.
158 */
159 static payload_type_t get_next_type(private_id_payload_t *this)
160 {
161 return this->next_payload;
162 }
163
164 /**
165 * Implementation of payload_t.set_next_type.
166 */
167 static void set_next_type(private_id_payload_t *this,payload_type_t type)
168 {
169 this->next_payload = type;
170 }
171
172 /**
173 * Implementation of payload_t.get_length.
174 */
175 static size_t get_length(private_id_payload_t *this)
176 {
177 return this->payload_length;
178 }
179
180 /**
181 * Implementation of id_payload_t.set_type.
182 */
183 static void set_id_type (private_id_payload_t *this, id_type_t type)
184 {
185 this->id_type = type;
186 }
187
188 /**
189 * Implementation of id_payload_t.get_id_type.
190 */
191 static id_type_t get_id_type (private_id_payload_t *this)
192 {
193 return (this->id_type);
194 }
195
196 /**
197 * Implementation of id_payload_t.set_data.
198 */
199 static void set_data (private_id_payload_t *this, chunk_t data)
200 {
201 if (this->id_data.ptr != NULL)
202 {
203 chunk_free(&(this->id_data));
204 }
205 this->id_data.ptr = clalloc(data.ptr,data.len);
206 this->id_data.len = data.len;
207 this->payload_length = ID_PAYLOAD_HEADER_LENGTH + this->id_data.len;
208 }
209
210
211 /**
212 * Implementation of id_payload_t.get_data_clone.
213 */
214 static chunk_t get_data (private_id_payload_t *this)
215 {
216 return (this->id_data);
217 }
218
219 /**
220 * Implementation of id_payload_t.get_data_clone.
221 */
222 static chunk_t get_data_clone (private_id_payload_t *this)
223 {
224 chunk_t cloned_data;
225 if (this->id_data.ptr == NULL)
226 {
227 return (this->id_data);
228 }
229 cloned_data.ptr = clalloc(this->id_data.ptr,this->id_data.len);
230 cloned_data.len = this->id_data.len;
231 return cloned_data;
232 }
233
234 /**
235 * Implementation of id_payload_t.get_identification.
236 */
237 static identification_t *get_identification (private_id_payload_t *this)
238 {
239 return identification_create_from_encoding(this->id_type,this->id_data);
240 }
241
242 /**
243 * Implementation of payload_t.destroy and id_payload_t.destroy.
244 */
245 static void destroy(private_id_payload_t *this)
246 {
247 if (this->id_data.ptr != NULL)
248 {
249 chunk_free(&(this->id_data));
250 }
251 free(this);
252 }
253
254 /*
255 * Described in header.
256 */
257 id_payload_t *id_payload_create(payload_type_t payload_type)
258 {
259 private_id_payload_t *this = malloc_thing(private_id_payload_t);
260
261 /* interface functions */
262 this->public.payload_interface.verify = (status_t (*) (payload_t *))verify;
263 this->public.payload_interface.get_encoding_rules = (void (*) (payload_t *, encoding_rule_t **, size_t *) ) get_encoding_rules;
264 this->public.payload_interface.get_length = (size_t (*) (payload_t *)) get_length;
265 this->public.payload_interface.get_next_type = (payload_type_t (*) (payload_t *)) get_next_type;
266 this->public.payload_interface.set_next_type = (void (*) (payload_t *,payload_type_t)) set_next_type;
267 this->public.payload_interface.get_type = (payload_type_t (*) (payload_t *)) get_payload_type;
268 this->public.payload_interface.destroy = (void (*) (payload_t *))destroy;
269
270 /* public functions */
271 this->public.destroy = (void (*) (id_payload_t *)) destroy;
272 this->public.set_id_type = (void (*) (id_payload_t *,id_type_t)) set_id_type;
273 this->public.get_id_type = (id_type_t (*) (id_payload_t *)) get_id_type;
274 this->public.set_data = (void (*) (id_payload_t *,chunk_t)) set_data;
275 this->public.get_data = (chunk_t (*) (id_payload_t *)) get_data;
276 this->public.get_data_clone = (chunk_t (*) (id_payload_t *)) get_data_clone;
277
278 this->public.get_identification = (identification_t * (*) (id_payload_t *this)) get_identification;
279
280 /* private variables */
281 this->critical = FALSE;
282 this->next_payload = NO_PAYLOAD;
283 this->payload_length =ID_PAYLOAD_HEADER_LENGTH;
284 this->id_data = chunk_empty;
285 this->payload_type = payload_type;
286
287 return (&(this->public));
288 }
289
290 /*
291 * Described in header.
292 */
293 id_payload_t *id_payload_create_from_identification(payload_type_t payload_type, identification_t *identification)
294 {
295 id_payload_t *this= id_payload_create(payload_type);
296 this->set_data(this,identification->get_encoding(identification));
297 this->set_id_type(this,identification->get_type(identification));
298 return this;
299 }