4 * @brief Declaration of the class ike_header_t.
6 * An object of this type represents an ike header and is used to
7 * generate and parse ike headers.
12 * Copyright (C) 2005 Jan Hutter, Martin Willi
13 * Hochschule fuer Technik Rapperswil
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>.
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
29 #include "ike_header.h"
31 #include <payloads/encodings.h>
32 #include <utils/allocator.h>
34 typedef struct private_ike_header_s private_ike_header_t
;
36 struct private_ike_header_s
{
43 * SPI of the initiator
45 u_int64_t initiator_spi
;
47 * SPI of the responder
49 u_int64_t responder_spi
;
53 u_int8_t next_payload
;
67 u_int8_t exchange_type
;
70 * Flags of the Message
75 * Sender is initiator of the associated IKE_SA_INIT-Exchange
79 * is protocol supporting higher version?
83 * TRUE, if this is a response, FALSE if its a Request
88 * Associated Message-ID
92 * Length of the whole IKEv2-Message (header and all payloads)
98 * mappings used to get strings for exchange_type_t
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"}
110 * Encoding rules to parse or generate a IKEv2-Header
112 * The defined offsets are the positions in a object of type
116 encoding_rule_t ike_header_encodings
[] = {
117 /* 8 Byte SPI, stored in the field initiator_spi */
118 { IKE_SPI
, offsetof(private_ike_header_t
, initiator_spi
) },
119 /* 8 Byte SPI, stored in the field responder_spi */
120 { IKE_SPI
, offsetof(private_ike_header_t
, responder_spi
) },
121 /* 1 Byte next payload type, stored in the field next_payload */
122 { U_INT_8
, offsetof(private_ike_header_t
, next_payload
) },
123 /* 4 Bit major version, stored in the field maj_version */
124 { U_INT_4
, offsetof(private_ike_header_t
, maj_version
) },
125 /* 4 Bit minor version, stored in the field min_version */
126 { U_INT_4
, offsetof(private_ike_header_t
, min_version
) },
127 /* 8 Bit for the exchange type */
128 { U_INT_8
, offsetof(private_ike_header_t
, exchange_type
) },
129 /* 2 Bit reserved bits, nowhere stored */
132 /* 3 Bit flags, stored in the fields response, version and initiator */
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
) },
136 /* 3 Bit reserved bits, nowhere stored */
140 /* 4 Byte message id, stored in the field message_id */
141 { U_INT_32
, offsetof(private_ike_header_t
, message_id
) },
142 /* 4 Byte length fied, stored in the field length */
143 { HEADER_LENGTH
, offsetof(private_ike_header_t
, length
) }
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 !
152 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
153 ! IKE_SA Responder's SPI !
155 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156 ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
157 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 * Implements payload_t's verify function.
167 * See #payload_s.verify for description.
169 static status_t
verify(private_ike_header_t
*this)
171 if ((this->exchange_type
< IKE_SA_INIT
) || (this->exchange_type
> INFORMATIONAL
))
173 /* unsupported exchange type */
176 if (this->initiator_spi
== 0)
178 /* initiator spi not set */
182 if ((this->responder_spi
== 0) && (!this->flags
.initiator
))
184 /* must be original initiator*/
188 if ((this->responder_spi
== 0) && (this->flags
.response
))
194 /* verification of version is not done in here */
200 * Implements payload_t's set_next_type function.
201 * See #payload_s.set_next_type for description.
203 static status_t
set_next_type(payload_t
*this,payload_type_t type
)
205 ((private_ike_header_t
*)this)->next_payload
= type
;
209 * Implements ike_header_t's get_initiator_spi fuction.
210 * See #ike_header_t.get_initiator_spi for description.
212 static u_int64_t
get_initiator_spi(private_ike_header_t
*this)
214 return this->initiator_spi
;
218 * Implements ike_header_t's set_initiator_spi fuction.
219 * See #ike_header_t.set_initiator_spi for description.
221 static void set_initiator_spi(private_ike_header_t
*this, u_int64_t initiator_spi
)
223 this->initiator_spi
= initiator_spi
;
227 * Implements ike_header_t's get_responder_spi fuction.
228 * See #ike_header_t.get_responder_spi for description.
230 static u_int64_t
get_responder_spi(private_ike_header_t
*this)
232 return this->responder_spi
;
236 * Implements ike_header_t's set_responder_spi fuction.
237 * See #ike_header_t.set_responder_spi for description.
239 static void set_responder_spi(private_ike_header_t
*this, u_int64_t responder_spi
)
241 this->responder_spi
= responder_spi
;
245 * Implements ike_header_t's get_maj_version fuction.
246 * See #ike_header_t.get_maj_version for description.
248 static u_int8_t
get_maj_version(private_ike_header_t
*this)
250 return this->maj_version
;
254 * Implements ike_header_t's get_min_version fuction.
255 * See #ike_header_t.get_min_version for description.
257 static u_int8_t
get_min_version(private_ike_header_t
*this)
259 return this->min_version
;
263 * Implements ike_header_t's get_response_flag fuction.
264 * See #ike_header_t.get_response_flag for description.
266 static bool get_response_flag(private_ike_header_t
*this)
268 return this->flags
.response
;
272 * Implements ike_header_t's set_response_flag fuction.
273 * See #ike_header_t.set_response_flag for description.
275 static void set_response_flag(private_ike_header_t
*this, bool response
)
277 this->flags
.response
= response
;
281 * Implements ike_header_t's get_version_flag fuction.
282 * See #ike_header_t.get_version_flag for description.
284 static bool get_version_flag(private_ike_header_t
*this)
286 return this->flags
.version
;
290 * Implements ike_header_t's get_initiator_flag fuction.
291 * See #ike_header_t.get_initiator_flag for description.
293 static bool get_initiator_flag(private_ike_header_t
*this)
295 return this->flags
.initiator
;
299 * Implements ike_header_t's set_initiator_flag fuction.
300 * See #ike_header_t.set_initiator_flag for description.
302 static void set_initiator_flag(private_ike_header_t
*this, bool initiator
)
304 this->flags
.initiator
= initiator
;
308 * Implements ike_header_t's get_exchange_type function
309 * See #ike_header_t.get_exchange_type for description.
311 static u_int8_t
get_exchange_type(private_ike_header_t
*this)
313 return this->exchange_type
;
317 * Implements ike_header_t's set_exchange_type function.
318 * See #ike_header_t.set_exchange_type for description.
320 static void set_exchange_type(private_ike_header_t
*this, u_int8_t exchange_type
)
322 this->exchange_type
= exchange_type
;
326 * Implements ike_header_t's get_message_id function.
327 * See #ike_header_t.get_message_id for description.
329 static u_int32_t
get_message_id(private_ike_header_t
*this)
331 return this->message_id
;
335 * Implements ike_header_t's set_message_id function.
336 * See #ike_header_t.set_message_id for description.
338 static void set_message_id(private_ike_header_t
*this, u_int32_t message_id
)
340 this->message_id
= message_id
;
344 * Implements payload_t's and ike_header_t's destroy function.
345 * See #payload_s.destroy or ike_header_s.destroy for description.
347 static status_t
destroy(ike_header_t
*this)
349 allocator_free(this);
355 * Implements payload_t's get_encoding_rules function.
356 * See #payload_s.get_encoding_rules for description.
358 static status_t
get_encoding_rules(payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
360 *rules
= ike_header_encodings
;
361 *rule_count
= sizeof(ike_header_encodings
) / sizeof(encoding_rule_t
);
367 * Implements payload_t's get_type function.
368 * See #payload_s.get_type for description.
370 static payload_type_t
get_type(payload_t
*this)
376 * Implements payload_t's get_next_type function.
377 * See #payload_s.get_next_type for description.
379 static payload_type_t
get_next_type(payload_t
*this)
381 return (((private_ike_header_t
*)this)->next_payload
);
385 * Implements payload_t's get_length function.
386 * See #payload_s.get_length for description.
388 static size_t get_length(payload_t
*this)
390 return (((private_ike_header_t
*)this)->length
);
394 * Described in header
396 ike_header_t
*ike_header_create()
398 private_ike_header_t
*this = allocator_alloc_thing(private_ike_header_t
);
404 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
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
;
408 this->public.payload_interface
.set_next_type
= set_next_type
;
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
;
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
;
420 this->public.set_response_flag
= (void (*) (ike_header_t
*,bool))set_response_flag
;
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
;
423 this->public.set_initiator_flag
= (void (*) (ike_header_t
*,bool))set_initiator_flag
;
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
;
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
;
435 this->exchange_type
= EXCHANGE_TYPE_UNDEFINED
;
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
;
443 return (ike_header_t
*)this;