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