]>
Commit | Line | Data |
---|---|---|
c0211a29 MW |
1 | /** |
2 | * @file ike_header.c | |
3 | * | |
63b200ab JH |
4 | * @brief Declaration of the class ike_header_t. |
5 | * | |
6 | * An object of this type represents an ike header and is used to | |
7 | * generate and parse ike headers. | |
8 | * | |
c0211a29 MW |
9 | */ |
10 | ||
11 | /* | |
12 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
13 | * Hochschule fuer Technik Rapperswil | |
14 | * | |
15 | * This program is free software; you can redistribute it and/or modify it | |
16 | * under the terms of the GNU General Public License as published by the | |
17 | * Free Software Foundation; either version 2 of the License, or (at your | |
18 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
19 | * | |
20 | * This program is distributed in the hope that it will be useful, but | |
21 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
22 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
23 | * for more details. | |
24 | */ | |
25 | ||
26 | /* offsetof macro */ | |
27 | #include <stddef.h> | |
28 | ||
cc0fbc3c MW |
29 | #include "ike_header.h" |
30 | ||
4a962238 | 31 | #include <encoding/payloads/encodings.h> |
696be022 | 32 | #include <utils/allocator.h> |
c0211a29 | 33 | |
a9d0fa62 MW |
34 | typedef struct private_ike_header_s private_ike_header_t; |
35 | ||
36 | struct private_ike_header_s { | |
37 | /** | |
38 | * public interface | |
39 | */ | |
40 | ike_header_t public; | |
41 | ||
42 | /** | |
43 | * SPI of the initiator | |
44 | */ | |
45 | u_int64_t initiator_spi; | |
46 | /** | |
47 | * SPI of the responder | |
48 | */ | |
49 | u_int64_t responder_spi; | |
50 | /** | |
51 | * next payload type | |
52 | */ | |
53 | u_int8_t next_payload; | |
54 | /** | |
55 | * IKE major version | |
56 | */ | |
57 | u_int8_t maj_version; | |
58 | ||
59 | /** | |
60 | * IKE minor version | |
61 | */ | |
62 | u_int8_t min_version; | |
63 | ||
64 | /** | |
65 | * Exchange type | |
66 | */ | |
67 | u_int8_t exchange_type; | |
68 | ||
69 | /** | |
70 | * Flags of the Message | |
71 | * | |
72 | */ | |
73 | struct { | |
74 | /** | |
75 | * Sender is initiator of the associated IKE_SA_INIT-Exchange | |
76 | */ | |
77 | bool initiator; | |
78 | /** | |
79 | * is protocol supporting higher version? | |
80 | */ | |
81 | bool version; | |
82 | /** | |
83 | * TRUE, if this is a response, FALSE if its a Request | |
84 | */ | |
85 | bool response; | |
86 | } flags; | |
87 | /** | |
88 | * Associated Message-ID | |
89 | */ | |
90 | u_int32_t message_id; | |
91 | /** | |
92 | * Length of the whole IKEv2-Message (header and all payloads) | |
93 | */ | |
94 | u_int32_t length; | |
95 | }; | |
02d3cba7 MW |
96 | |
97 | /** | |
98 | * mappings used to get strings for exchange_type_t | |
99 | */ | |
100 | mapping_t exchange_type_m[] = { | |
101 | {EXCHANGE_TYPE_UNDEFINED, "EXCHANGE_TYPE_UNDEFINED"}, | |
102 | {IKE_SA_INIT, "IKE_SA_INIT"}, | |
103 | {IKE_AUTH, "IKE_AUTH"}, | |
104 | {CREATE_CHILD_SA, "CREATE_CHILD_SA"}, | |
105 | {INFORMATIONAL, "INFORMATIONAL"} | |
106 | }; | |
a9d0fa62 MW |
107 | |
108 | ||
c0211a29 MW |
109 | /** |
110 | * Encoding rules to parse or generate a IKEv2-Header | |
111 | * | |
0063dae5 | 112 | * The defined offsets are the positions in a object of type |
c0211a29 MW |
113 | * ike_header_t. |
114 | * | |
115 | */ | |
116 | encoding_rule_t ike_header_encodings[] = { | |
117 | /* 8 Byte SPI, stored in the field initiator_spi */ | |
cef4bce9 | 118 | { IKE_SPI, offsetof(private_ike_header_t, initiator_spi) }, |
c0211a29 | 119 | /* 8 Byte SPI, stored in the field responder_spi */ |
cef4bce9 | 120 | { IKE_SPI, offsetof(private_ike_header_t, responder_spi) }, |
c0211a29 | 121 | /* 1 Byte next payload type, stored in the field next_payload */ |
a9d0fa62 | 122 | { U_INT_8, offsetof(private_ike_header_t, next_payload) }, |
c0211a29 | 123 | /* 4 Bit major version, stored in the field maj_version */ |
a9d0fa62 | 124 | { U_INT_4, offsetof(private_ike_header_t, maj_version) }, |
c0211a29 | 125 | /* 4 Bit minor version, stored in the field min_version */ |
a9d0fa62 | 126 | { U_INT_4, offsetof(private_ike_header_t, min_version) }, |
c0211a29 | 127 | /* 8 Bit for the exchange type */ |
a9d0fa62 | 128 | { U_INT_8, offsetof(private_ike_header_t, exchange_type) }, |
c0211a29 MW |
129 | /* 2 Bit reserved bits, nowhere stored */ |
130 | { RESERVED_BIT, 0 }, | |
131 | { RESERVED_BIT, 0 }, | |
132 | /* 3 Bit flags, stored in the fields response, version and initiator */ | |
a9d0fa62 MW |
133 | { FLAG, offsetof(private_ike_header_t, flags.response) }, |
134 | { FLAG, offsetof(private_ike_header_t, flags.version) }, | |
135 | { FLAG, offsetof(private_ike_header_t, flags.initiator) }, | |
c0211a29 MW |
136 | /* 3 Bit reserved bits, nowhere stored */ |
137 | { RESERVED_BIT, 0 }, | |
138 | { RESERVED_BIT, 0 }, | |
139 | { RESERVED_BIT, 0 }, | |
140 | /* 4 Byte message id, stored in the field message_id */ | |
a9d0fa62 | 141 | { U_INT_32, offsetof(private_ike_header_t, message_id) }, |
c0211a29 | 142 | /* 4 Byte length fied, stored in the field length */ |
a9d0fa62 | 143 | { HEADER_LENGTH, offsetof(private_ike_header_t, length) } |
c0211a29 MW |
144 | }; |
145 | ||
e31eb71e JH |
146 | |
147 | /* 1 2 3 | |
148 | 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 | |
149 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
150 | ! IKE_SA Initiator's SPI ! | |
151 | ! ! | |
152 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
153 | ! IKE_SA Responder's SPI ! | |
154 | ! ! | |
155 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
156 | ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags ! | |
157 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
158 | ! Message ID ! | |
159 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
160 | ! Length ! | |
161 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
162 | */ | |
163 | ||
164 | ||
165 | /** | |
166 | * Implements payload_t's verify function. | |
167 | * See #payload_s.verify for description. | |
168 | */ | |
169 | static status_t verify(private_ike_header_t *this) | |
170 | { | |
171 | if ((this->exchange_type < IKE_SA_INIT) || (this->exchange_type > INFORMATIONAL)) | |
172 | { | |
173 | /* unsupported exchange type */ | |
174 | return FAILED; | |
175 | } | |
7b3d1389 | 176 | if (this->initiator_spi == 0) |
e31eb71e JH |
177 | { |
178 | /* initiator spi not set */ | |
179 | return FAILED; | |
180 | } | |
181 | ||
7b3d1389 MW |
182 | if ((this->responder_spi == 0) && (!this->flags.initiator)) |
183 | { | |
184 | /* must be original initiator*/ | |
185 | return FAILED; | |
186 | } | |
187 | ||
188 | if ((this->responder_spi == 0) && (this->flags.response)) | |
189 | { | |
190 | /* must be request*/ | |
191 | return FAILED; | |
192 | } | |
193 | ||
e31eb71e JH |
194 | /* verification of version is not done in here */ |
195 | ||
196 | return SUCCESS; | |
197 | } | |
198 | ||
2b9dd467 | 199 | /** |
32cbc7bc JH |
200 | * Implements payload_t's set_next_type function. |
201 | * See #payload_s.set_next_type for description. | |
2b9dd467 | 202 | */ |
32cbc7bc | 203 | static status_t set_next_type(payload_t *this,payload_type_t type) |
2b9dd467 | 204 | { |
32cbc7bc JH |
205 | ((private_ike_header_t *)this)->next_payload = type; |
206 | return SUCCESS; | |
2b9dd467 | 207 | } |
a9d0fa62 MW |
208 | /** |
209 | * Implements ike_header_t's get_initiator_spi fuction. | |
210 | * See #ike_header_t.get_initiator_spi for description. | |
211 | */ | |
212 | static u_int64_t get_initiator_spi(private_ike_header_t *this) | |
213 | { | |
214 | return this->initiator_spi; | |
215 | } | |
216 | ||
217 | /** | |
218 | * Implements ike_header_t's set_initiator_spi fuction. | |
219 | * See #ike_header_t.set_initiator_spi for description. | |
220 | */ | |
221 | static void set_initiator_spi(private_ike_header_t *this, u_int64_t initiator_spi) | |
222 | { | |
223 | this->initiator_spi = initiator_spi; | |
224 | } | |
225 | ||
226 | /** | |
227 | * Implements ike_header_t's get_responder_spi fuction. | |
228 | * See #ike_header_t.get_responder_spi for description. | |
229 | */ | |
230 | static u_int64_t get_responder_spi(private_ike_header_t *this) | |
231 | { | |
232 | return this->responder_spi; | |
233 | } | |
234 | ||
235 | /** | |
236 | * Implements ike_header_t's set_responder_spi fuction. | |
237 | * See #ike_header_t.set_responder_spi for description. | |
238 | */ | |
239 | static void set_responder_spi(private_ike_header_t *this, u_int64_t responder_spi) | |
240 | { | |
241 | this->responder_spi = responder_spi; | |
242 | } | |
243 | ||
244 | /** | |
245 | * Implements ike_header_t's get_maj_version fuction. | |
246 | * See #ike_header_t.get_maj_version for description. | |
247 | */ | |
248 | static u_int8_t get_maj_version(private_ike_header_t *this) | |
249 | { | |
250 | return this->maj_version; | |
251 | } | |
252 | ||
253 | /** | |
254 | * Implements ike_header_t's get_min_version fuction. | |
255 | * See #ike_header_t.get_min_version for description. | |
256 | */ | |
257 | static u_int8_t get_min_version(private_ike_header_t *this) | |
258 | { | |
259 | return this->min_version; | |
260 | } | |
261 | ||
262 | /** | |
263 | * Implements ike_header_t's get_response_flag fuction. | |
264 | * See #ike_header_t.get_response_flag for description. | |
265 | */ | |
266 | static bool get_response_flag(private_ike_header_t *this) | |
267 | { | |
268 | return this->flags.response; | |
269 | } | |
270 | ||
2b9dd467 JH |
271 | /** |
272 | * Implements ike_header_t's set_response_flag fuction. | |
273 | * See #ike_header_t.set_response_flag for description. | |
274 | */ | |
275 | static void set_response_flag(private_ike_header_t *this, bool response) | |
276 | { | |
277 | this->flags.response = response; | |
278 | } | |
279 | ||
a9d0fa62 MW |
280 | /** |
281 | * Implements ike_header_t's get_version_flag fuction. | |
282 | * See #ike_header_t.get_version_flag for description. | |
283 | */ | |
284 | static bool get_version_flag(private_ike_header_t *this) | |
285 | { | |
286 | return this->flags.version; | |
287 | } | |
288 | ||
289 | /** | |
290 | * Implements ike_header_t's get_initiator_flag fuction. | |
291 | * See #ike_header_t.get_initiator_flag for description. | |
292 | */ | |
293 | static bool get_initiator_flag(private_ike_header_t *this) | |
294 | { | |
295 | return this->flags.initiator; | |
296 | } | |
297 | ||
2b9dd467 JH |
298 | /** |
299 | * Implements ike_header_t's set_initiator_flag fuction. | |
300 | * See #ike_header_t.set_initiator_flag for description. | |
301 | */ | |
302 | static void set_initiator_flag(private_ike_header_t *this, bool initiator) | |
303 | { | |
304 | this->flags.initiator = initiator; | |
305 | } | |
306 | ||
a9d0fa62 MW |
307 | /** |
308 | * Implements ike_header_t's get_exchange_type function | |
309 | * See #ike_header_t.get_exchange_type for description. | |
310 | */ | |
311 | static u_int8_t get_exchange_type(private_ike_header_t *this) | |
312 | { | |
313 | return this->exchange_type; | |
314 | } | |
315 | ||
316 | /** | |
317 | * Implements ike_header_t's set_exchange_type function. | |
318 | * See #ike_header_t.set_exchange_type for description. | |
319 | */ | |
320 | static void set_exchange_type(private_ike_header_t *this, u_int8_t exchange_type) | |
321 | { | |
322 | this->exchange_type = exchange_type; | |
323 | } | |
324 | ||
325 | /** | |
326 | * Implements ike_header_t's get_message_id function. | |
327 | * See #ike_header_t.get_message_id for description. | |
328 | */ | |
329 | static u_int32_t get_message_id(private_ike_header_t *this) | |
330 | { | |
331 | return this->message_id; | |
332 | } | |
333 | ||
334 | /** | |
335 | * Implements ike_header_t's set_message_id function. | |
336 | * See #ike_header_t.set_message_id for description. | |
337 | */ | |
338 | static void set_message_id(private_ike_header_t *this, u_int32_t message_id) | |
339 | { | |
340 | this->message_id = message_id; | |
341 | } | |
c0211a29 | 342 | |
0063dae5 JH |
343 | /** |
344 | * Implements payload_t's and ike_header_t's destroy function. | |
345 | * See #payload_s.destroy or ike_header_s.destroy for description. | |
346 | */ | |
1e8bb886 | 347 | static status_t destroy(ike_header_t *this) |
cc0fbc3c MW |
348 | { |
349 | allocator_free(this); | |
350 | ||
351 | return SUCCESS; | |
352 | } | |
0063dae5 JH |
353 | |
354 | /** | |
355 | * Implements payload_t's get_encoding_rules function. | |
356 | * See #payload_s.get_encoding_rules for description. | |
357 | */ | |
1e8bb886 | 358 | static status_t get_encoding_rules(payload_t *this, encoding_rule_t **rules, size_t *rule_count) |
cc0fbc3c MW |
359 | { |
360 | *rules = ike_header_encodings; | |
361 | *rule_count = sizeof(ike_header_encodings) / sizeof(encoding_rule_t); | |
362 | ||
363 | return SUCCESS; | |
364 | } | |
365 | ||
0063dae5 JH |
366 | /** |
367 | * Implements payload_t's get_type function. | |
368 | * See #payload_s.get_type for description. | |
369 | */ | |
1e8bb886 | 370 | static payload_type_t get_type(payload_t *this) |
cc0fbc3c MW |
371 | { |
372 | return HEADER; | |
373 | } | |
374 | ||
0063dae5 JH |
375 | /** |
376 | * Implements payload_t's get_next_type function. | |
377 | * See #payload_s.get_next_type for description. | |
378 | */ | |
1e8bb886 | 379 | static payload_type_t get_next_type(payload_t *this) |
cc0fbc3c | 380 | { |
a9d0fa62 | 381 | return (((private_ike_header_t*)this)->next_payload); |
cc0fbc3c MW |
382 | } |
383 | ||
0063dae5 JH |
384 | /** |
385 | * Implements payload_t's get_length function. | |
386 | * See #payload_s.get_length for description. | |
387 | */ | |
1e8bb886 | 388 | static size_t get_length(payload_t *this) |
cc0fbc3c | 389 | { |
a9d0fa62 | 390 | return (((private_ike_header_t*)this)->length); |
cc0fbc3c MW |
391 | } |
392 | ||
0063dae5 JH |
393 | /* |
394 | * Described in header | |
395 | */ | |
cc0fbc3c MW |
396 | ike_header_t *ike_header_create() |
397 | { | |
a9d0fa62 | 398 | private_ike_header_t *this = allocator_alloc_thing(private_ike_header_t); |
cc0fbc3c MW |
399 | if (this == NULL) |
400 | { | |
401 | return NULL; | |
402 | } | |
403 | ||
e31eb71e | 404 | this->public.payload_interface.verify = (status_t (*) (payload_t *))verify; |
a9d0fa62 MW |
405 | this->public.payload_interface.get_encoding_rules = get_encoding_rules; |
406 | this->public.payload_interface.get_length = get_length; | |
407 | this->public.payload_interface.get_next_type = get_next_type; | |
32cbc7bc | 408 | this->public.payload_interface.set_next_type = set_next_type; |
a9d0fa62 MW |
409 | this->public.payload_interface.get_type = get_type; |
410 | this->public.payload_interface.destroy = (status_t (*) (payload_t *))destroy; | |
411 | this->public.destroy = destroy; | |
412 | ||
413 | this->public.get_initiator_spi = (u_int64_t (*) (ike_header_t*))get_initiator_spi; | |
414 | this->public.set_initiator_spi = (void (*) (ike_header_t*,u_int64_t))set_initiator_spi; | |
415 | this->public.get_responder_spi = (u_int64_t (*) (ike_header_t*))get_responder_spi; | |
416 | this->public.set_responder_spi = (void (*) (ike_header_t *,u_int64_t))set_responder_spi; | |
417 | this->public.get_maj_version = (u_int8_t (*) (ike_header_t*))get_maj_version; | |
418 | this->public.get_min_version = (u_int8_t (*) (ike_header_t*))get_min_version; | |
419 | this->public.get_response_flag = (bool (*) (ike_header_t*))get_response_flag; | |
2b9dd467 | 420 | this->public.set_response_flag = (void (*) (ike_header_t*,bool))set_response_flag; |
a9d0fa62 MW |
421 | this->public.get_version_flag = (bool (*) (ike_header_t*))get_version_flag; |
422 | this->public.get_initiator_flag = (bool (*) (ike_header_t*))get_initiator_flag; | |
2b9dd467 | 423 | this->public.set_initiator_flag = (void (*) (ike_header_t*,bool))set_initiator_flag; |
a9d0fa62 MW |
424 | this->public.get_exchange_type = (u_int8_t (*) (ike_header_t*))get_exchange_type; |
425 | this->public.set_exchange_type = (void (*) (ike_header_t*,u_int8_t))set_exchange_type; | |
426 | this->public.get_message_id = (u_int32_t (*) (ike_header_t*))get_message_id; | |
427 | this->public.set_message_id = (void (*) (ike_header_t*,u_int32_t))set_message_id; | |
cc0fbc3c | 428 | |
0063dae5 JH |
429 | /* set default values of the fields */ |
430 | this->initiator_spi = 0; | |
431 | this->responder_spi = 0; | |
432 | this->next_payload = 0; | |
433 | this->maj_version = IKE_MAJOR_VERSION; | |
434 | this->min_version = IKE_MINOR_VERSION; | |
02d3cba7 | 435 | this->exchange_type = EXCHANGE_TYPE_UNDEFINED; |
0063dae5 JH |
436 | this->flags.initiator = TRUE; |
437 | this->flags.version = HIGHER_VERSION_SUPPORTED_FLAG; | |
438 | this->flags.response = FALSE; | |
439 | this->message_id = 0; | |
440 | this->length = IKE_HEADER_LENGTH; | |
441 | ||
442 | ||
a9d0fa62 | 443 | return (ike_header_t*)this; |
cc0fbc3c MW |
444 | } |
445 | ||
446 |