Added member fields for reserved bits and bytes in all payloads
[strongswan.git] / src / libcharon / encoding / payloads / ike_header.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2005-2006 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 /* offsetof macro */
19 #include <stddef.h>
20
21 #include "ike_header.h"
22
23 #include <encoding/payloads/encodings.h>
24
25
26 typedef struct private_ike_header_t private_ike_header_t;
27
28 /**
29 * Private data of an ike_header_t object.
30 */
31 struct private_ike_header_t {
32 /**
33 * Public interface.
34 */
35 ike_header_t public;
36
37 /**
38 * SPI of the initiator.
39 */
40 u_int64_t initiator_spi;
41
42 /**
43 * SPI of the responder.
44 */
45 u_int64_t responder_spi;
46
47 /**
48 * Next payload type.
49 */
50 u_int8_t next_payload;
51 /**
52 * IKE major version.
53 */
54 u_int8_t maj_version;
55
56 /**
57 * IKE minor version.
58 */
59 u_int8_t min_version;
60
61 /**
62 * Exchange type .
63 */
64 u_int8_t exchange_type;
65
66 /**
67 * Flags of the Message.
68 */
69 struct {
70 /**
71 * Sender is initiator of the associated IKE_SA_INIT-Exchange.
72 */
73 bool initiator;
74
75 /**
76 * Is protocol supporting higher version?
77 */
78 bool version;
79
80 /**
81 * TRUE, if this is a response, FALSE if its a Request.
82 */
83 bool response;
84 } flags;
85
86 /**
87 * Reserved bits of IKE header
88 */
89 bool reserved[5];
90
91 /**
92 * Associated Message-ID.
93 */
94 u_int32_t message_id;
95
96 /**
97 * Length of the whole IKEv2-Message (header and all payloads).
98 */
99 u_int32_t length;
100 };
101
102 ENUM_BEGIN(exchange_type_names, EXCHANGE_TYPE_UNDEFINED, EXCHANGE_TYPE_UNDEFINED,
103 "EXCHANGE_TYPE_UNDEFINED");
104 ENUM_NEXT(exchange_type_names, IKE_SA_INIT, INFORMATIONAL, EXCHANGE_TYPE_UNDEFINED,
105 "IKE_SA_INIT",
106 "IKE_AUTH",
107 "CREATE_CHILD_SA",
108 "INFORMATIONAL");
109 #ifdef ME
110 ENUM_NEXT(exchange_type_names, ME_CONNECT, ME_CONNECT, INFORMATIONAL,
111 "ME_CONNECT");
112 ENUM_END(exchange_type_names, ME_CONNECT);
113 #else
114 ENUM_END(exchange_type_names, INFORMATIONAL);
115 #endif /* ME */
116
117 /**
118 * Encoding rules to parse or generate a IKEv2-Header.
119 *
120 * The defined offsets are the positions in a object of type
121 * ike_header_t.
122 */
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 */
137 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[0]) },
138 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[1]) },
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 */
144 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[2]) },
145 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[3]) },
146 { RESERVED_BIT, offsetof(private_ike_header_t, reserved[4]) },
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) },
151 };
152
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 METHOD(payload_t, verify, status_t,
172 private_ike_header_t *this)
173 {
174 if ((this->exchange_type < IKE_SA_INIT) ||
175 ((this->exchange_type > INFORMATIONAL)
176 #ifdef ME
177 && (this->exchange_type != ME_CONNECT)
178 #endif /* ME */
179 ))
180 {
181 /* unsupported exchange type */
182 return FAILED;
183 }
184 if (this->initiator_spi == 0
185 #ifdef ME
186 /* we allow zero spi for INFORMATIONAL exchanges,
187 * to allow connectivity checks */
188 && this->exchange_type != INFORMATIONAL
189 #endif /* ME */
190 )
191 {
192 /* initiator spi not set */
193 return FAILED;
194 }
195 return SUCCESS;
196 }
197
198 METHOD(payload_t, get_encoding_rules, void,
199 private_ike_header_t *this, encoding_rule_t **rules, size_t *rule_count)
200 {
201 *rules = ike_header_encodings;
202 *rule_count = sizeof(ike_header_encodings) / sizeof(encoding_rule_t);
203 }
204
205 METHOD(payload_t, get_type, payload_type_t,
206 private_ike_header_t *this)
207 {
208 return HEADER;
209 }
210
211 METHOD(payload_t, get_next_type, payload_type_t,
212 private_ike_header_t *this)
213 {
214 return this->next_payload;
215 }
216
217 METHOD(payload_t, set_next_type, void,
218 private_ike_header_t *this, payload_type_t type)
219 {
220 this->next_payload = type;
221 }
222
223 METHOD(payload_t, get_length, size_t,
224 private_ike_header_t *this)
225 {
226 return this->length;
227 }
228
229 METHOD(ike_header_t, get_initiator_spi, u_int64_t,
230 private_ike_header_t *this)
231 {
232 return this->initiator_spi;
233 }
234
235 METHOD(ike_header_t, set_initiator_spi, void,
236 private_ike_header_t *this, u_int64_t initiator_spi)
237 {
238 this->initiator_spi = initiator_spi;
239 }
240
241 METHOD(ike_header_t, get_responder_spi, u_int64_t,
242 private_ike_header_t *this)
243 {
244 return this->responder_spi;
245 }
246
247 METHOD(ike_header_t, set_responder_spi, void,
248 private_ike_header_t *this, u_int64_t responder_spi)
249 {
250 this->responder_spi = responder_spi;
251 }
252
253 METHOD(ike_header_t, get_maj_version, u_int8_t,
254 private_ike_header_t *this)
255 {
256 return this->maj_version;
257 }
258
259 METHOD(ike_header_t, set_maj_version, void,
260 private_ike_header_t *this, u_int8_t major)
261 {
262 this->maj_version = major;
263 }
264
265 METHOD(ike_header_t, get_min_version, u_int8_t,
266 private_ike_header_t *this)
267 {
268 return this->min_version;
269 }
270
271 METHOD(ike_header_t, set_min_version, void,
272 private_ike_header_t *this, u_int8_t minor)
273 {
274 this->min_version = minor;
275 }
276
277 METHOD(ike_header_t, get_response_flag, bool,
278 private_ike_header_t *this)
279 {
280 return this->flags.response;
281 }
282
283 METHOD(ike_header_t, set_response_flag, void,
284 private_ike_header_t *this, bool response)
285 {
286 this->flags.response = response;
287 }
288
289 METHOD(ike_header_t, get_version_flag, bool,
290 private_ike_header_t *this)
291 {
292 return this->flags.version;
293 }
294
295 METHOD(ike_header_t, get_initiator_flag, bool,
296 private_ike_header_t *this)
297 {
298 return this->flags.initiator;
299 }
300
301 METHOD(ike_header_t, set_initiator_flag, void,
302 private_ike_header_t *this, bool initiator)
303 {
304 this->flags.initiator = initiator;
305 }
306
307 METHOD(ike_header_t, get_exchange_type, u_int8_t,
308 private_ike_header_t *this)
309 {
310 return this->exchange_type;
311 }
312
313 METHOD(ike_header_t, set_exchange_type, void,
314 private_ike_header_t *this, u_int8_t exchange_type)
315 {
316 this->exchange_type = exchange_type;
317 }
318
319 METHOD(ike_header_t, get_message_id, u_int32_t,
320 private_ike_header_t *this)
321 {
322 return this->message_id;
323 }
324
325 METHOD(ike_header_t, set_message_id, void,
326 private_ike_header_t *this, u_int32_t message_id)
327 {
328 this->message_id = message_id;
329 }
330
331 METHOD2(payload_t, ike_header_t, destroy, void,
332 private_ike_header_t *this)
333 {
334 free(this);
335 }
336
337 /*
338 * Described in header.
339 */
340 ike_header_t *ike_header_create()
341 {
342 private_ike_header_t *this;
343
344 INIT(this,
345 .public = {
346 .payload_interface = {
347 .verify = _verify,
348 .get_encoding_rules = _get_encoding_rules,
349 .get_length = _get_length,
350 .get_next_type = _get_next_type,
351 .set_next_type = _set_next_type,
352 .get_type = _get_type,
353 .destroy = _destroy,
354 },
355 .get_initiator_spi = _get_initiator_spi,
356 .set_initiator_spi = _set_initiator_spi,
357 .get_responder_spi = _get_responder_spi,
358 .set_responder_spi = _set_responder_spi,
359 .get_maj_version = _get_maj_version,
360 .set_maj_version = _set_maj_version,
361 .get_min_version = _get_min_version,
362 .set_min_version = _set_min_version,
363 .get_response_flag = _get_response_flag,
364 .set_response_flag = _set_response_flag,
365 .get_version_flag = _get_version_flag,
366 .get_initiator_flag = _get_initiator_flag,
367 .set_initiator_flag = _set_initiator_flag,
368 .get_exchange_type = _get_exchange_type,
369 .set_exchange_type = _set_exchange_type,
370 .get_message_id = _get_message_id,
371 .set_message_id = _set_message_id,
372 .destroy = _destroy,
373 },
374 .maj_version = IKE_MAJOR_VERSION,
375 .min_version = IKE_MINOR_VERSION,
376 .exchange_type = EXCHANGE_TYPE_UNDEFINED,
377 .flags.initiator = TRUE,
378 .flags.version = HIGHER_VERSION_SUPPORTED_FLAG,
379 .length = IKE_HEADER_LENGTH,
380 );
381
382 return &this->public;
383 }