4 * @brief Implementation of ike_header_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
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>.
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
26 #include "ike_header.h"
28 #include <encoding/payloads/encodings.h>
31 typedef struct private_ike_header_t private_ike_header_t
;
34 * Private data of an ike_header_t object.
37 struct private_ike_header_t
{
44 * SPI of the initiator.
46 u_int64_t initiator_spi
;
49 * SPI of the responder.
51 u_int64_t responder_spi
;
56 u_int8_t next_payload
;
70 u_int8_t exchange_type
;
73 * Flags of the Message.
78 * Sender is initiator of the associated IKE_SA_INIT-Exchange.
83 * Is protocol supporting higher version?
88 * TRUE, if this is a response, FALSE if its a Request.
94 * Associated Message-ID.
99 * Length of the whole IKEv2-Message (header and all payloads).
105 * Mappings used to get strings for exchange_type_t.
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"}
117 * Encoding rules to parse or generate a IKEv2-Header.
119 * The defined offsets are the positions in a object of type
123 encoding_rule_t ike_header_encodings
[] = {
124 /* 8 Byte SPI, stored in the field initiator_spi */
125 { IKE_SPI
, offsetof(private_ike_header_t
, initiator_spi
) },
126 /* 8 Byte SPI, stored in the field responder_spi */
127 { IKE_SPI
, offsetof(private_ike_header_t
, responder_spi
) },
128 /* 1 Byte next payload type, stored in the field next_payload */
129 { U_INT_8
, offsetof(private_ike_header_t
, next_payload
) },
130 /* 4 Bit major version, stored in the field maj_version */
131 { U_INT_4
, offsetof(private_ike_header_t
, maj_version
) },
132 /* 4 Bit minor version, stored in the field min_version */
133 { U_INT_4
, offsetof(private_ike_header_t
, min_version
) },
134 /* 8 Bit for the exchange type */
135 { U_INT_8
, offsetof(private_ike_header_t
, exchange_type
) },
136 /* 2 Bit reserved bits, nowhere stored */
139 /* 3 Bit flags, stored in the fields response, version and initiator */
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
) },
143 /* 3 Bit reserved bits, nowhere stored */
147 /* 4 Byte message id, stored in the field message_id */
148 { U_INT_32
, offsetof(private_ike_header_t
, message_id
) },
149 /* 4 Byte length fied, stored in the field length */
150 { HEADER_LENGTH
, offsetof(private_ike_header_t
, length
) }
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 !
159 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
160 ! IKE_SA Responder's SPI !
162 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
163 ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
164 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
166 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
168 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173 * Implementation of payload_t.verify.
175 static status_t
verify(private_ike_header_t
*this)
177 if ((this->exchange_type
< IKE_SA_INIT
) || (this->exchange_type
> INFORMATIONAL
))
179 /* unsupported exchange type */
182 if (this->initiator_spi
== 0)
184 /* initiator spi not set */
188 /* verification of version is not done in here */
194 * Implementation of payload_t.set_next_type.
196 static void set_next_type(payload_t
*this,payload_type_t type
)
198 ((private_ike_header_t
*)this)->next_payload
= type
;
201 * Implementation of ike_header_t.get_initiator_spi.
203 static u_int64_t
get_initiator_spi(private_ike_header_t
*this)
205 return this->initiator_spi
;
209 * Implementation of ike_header_t.set_initiator_spi.
211 static void set_initiator_spi(private_ike_header_t
*this, u_int64_t initiator_spi
)
213 this->initiator_spi
= initiator_spi
;
217 * Implementation of ike_header_t.get_responder_spi.
219 static u_int64_t
get_responder_spi(private_ike_header_t
*this)
221 return this->responder_spi
;
225 * Implementation of ike_header_t.set_responder_spi.
227 static void set_responder_spi(private_ike_header_t
*this, u_int64_t responder_spi
)
229 this->responder_spi
= responder_spi
;
233 * Implementation of ike_header_t.get_maj_version.
235 static u_int8_t
get_maj_version(private_ike_header_t
*this)
237 return this->maj_version
;
241 * Implementation of ike_header_t.get_min_version.
243 static u_int8_t
get_min_version(private_ike_header_t
*this)
245 return this->min_version
;
249 * Implementation of ike_header_t.get_response_flag.
251 static bool get_response_flag(private_ike_header_t
*this)
253 return this->flags
.response
;
257 * Implementation of ike_header_t.set_response_flag.
259 static void set_response_flag(private_ike_header_t
*this, bool response
)
261 this->flags
.response
= response
;
265 * Implementation of ike_header_t.get_version_flag.
267 static bool get_version_flag(private_ike_header_t
*this)
269 return this->flags
.version
;
273 * Implementation of ike_header_t.get_initiator_flag.
275 static bool get_initiator_flag(private_ike_header_t
*this)
277 return this->flags
.initiator
;
281 * Implementation of ike_header_t.set_initiator_flag.
283 static void set_initiator_flag(private_ike_header_t
*this, bool initiator
)
285 this->flags
.initiator
= initiator
;
289 * Implementation of ike_header_t.get_exchange_type.
291 static u_int8_t
get_exchange_type(private_ike_header_t
*this)
293 return this->exchange_type
;
297 * Implementation of ike_header_t.set_exchange_type.
299 static void set_exchange_type(private_ike_header_t
*this, u_int8_t exchange_type
)
301 this->exchange_type
= exchange_type
;
305 * Implements ike_header_t's get_message_id function.
306 * See #ike_header_t.get_message_id for description.
308 static u_int32_t
get_message_id(private_ike_header_t
*this)
310 return this->message_id
;
314 * Implementation of ike_header_t.set_message_id.
316 static void set_message_id(private_ike_header_t
*this, u_int32_t message_id
)
318 this->message_id
= message_id
;
322 * Implementation of ike_header_t.destroy and payload_t.destroy.
324 static void destroy(ike_header_t
*this)
330 * Implementation of payload_t.get_encoding_rules.
332 static void get_encoding_rules(payload_t
*this, encoding_rule_t
**rules
, size_t *rule_count
)
334 *rules
= ike_header_encodings
;
335 *rule_count
= sizeof(ike_header_encodings
) / sizeof(encoding_rule_t
);
339 * Implementation of payload_t.get_type.
341 static payload_type_t
get_type(payload_t
*this)
347 * Implementation of payload_t.get_next_type.
349 static payload_type_t
get_next_type(payload_t
*this)
351 return (((private_ike_header_t
*)this)->next_payload
);
355 * Implementation of payload_t.get_length.
357 static size_t get_length(payload_t
*this)
359 return (((private_ike_header_t
*)this)->length
);
363 * Described in header.
365 ike_header_t
*ike_header_create()
367 private_ike_header_t
*this = malloc_thing(private_ike_header_t
);
369 this->public.payload_interface
.verify
= (status_t (*) (payload_t
*))verify
;
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
;
373 this->public.payload_interface
.set_next_type
= set_next_type
;
374 this->public.payload_interface
.get_type
= get_type
;
375 this->public.payload_interface
.destroy
= (void (*) (payload_t
*))destroy
;
376 this->public.destroy
= destroy
;
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
;
385 this->public.set_response_flag
= (void (*) (ike_header_t
*,bool))set_response_flag
;
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
;
388 this->public.set_initiator_flag
= (void (*) (ike_header_t
*,bool))set_initiator_flag
;
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
;
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
;
400 this->exchange_type
= EXCHANGE_TYPE_UNDEFINED
;
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
;
407 return (ike_header_t
*)this;