fixed some byte-order issues
[strongswan.git] / src / charon / encoding / generator.c
1 /**
2 * @file generator.c
3 *
4 * @brief Implementation of generator_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <arpa/inet.h>
27 #include <stdio.h>
28
29
30 #include "generator.h"
31
32 #include <library.h>
33 #include <daemon.h>
34 #include <utils/linked_list.h>
35 #include <encoding/payloads/payload.h>
36 #include <encoding/payloads/proposal_substructure.h>
37 #include <encoding/payloads/transform_substructure.h>
38 #include <encoding/payloads/sa_payload.h>
39 #include <encoding/payloads/ke_payload.h>
40 #include <encoding/payloads/notify_payload.h>
41 #include <encoding/payloads/nonce_payload.h>
42 #include <encoding/payloads/id_payload.h>
43 #include <encoding/payloads/auth_payload.h>
44 #include <encoding/payloads/cert_payload.h>
45 #include <encoding/payloads/certreq_payload.h>
46 #include <encoding/payloads/ts_payload.h>
47 #include <encoding/payloads/delete_payload.h>
48 #include <encoding/payloads/vendor_id_payload.h>
49 #include <encoding/payloads/cp_payload.h>
50 #include <encoding/payloads/configuration_attribute.h>
51 #include <encoding/payloads/eap_payload.h>
52
53
54 typedef struct private_generator_t private_generator_t;
55
56 /**
57 * Private part of a generator_t object.
58 */
59 struct private_generator_t {
60 /**
61 * Public part of a generator_t object.
62 */
63 generator_t public;
64
65 /**
66 * Generates a U_INT-Field type and writes it to buffer.
67 *
68 * @param this private_generator_t object
69 * @param int_type type of U_INT field (U_INT_4, U_INT_8, etc.)
70 * ATTRIBUTE_TYPE is also generated in this function
71 * @param offset offset of value in data struct
72 * @param generator_contexts generator_contexts_t object where the context is written or read from
73 * @return
74 * - SUCCESS
75 * - FAILED if allignment is wrong
76 */
77 void (*generate_u_int_type) (private_generator_t *this,encoding_type_t int_type,u_int32_t offset);
78
79 /**
80 * Get size of current buffer in bytes.
81 *
82 * @param this private_generator_t object
83 * @return Size of buffer in bytes
84 */
85 size_t (*get_current_buffer_size) (private_generator_t *this);
86
87 /**
88 * Get free space of current buffer in bytes.
89 *
90 * @param this private_generator_t object
91 * @return space in buffer in bytes
92 */
93 size_t (*get_current_buffer_space) (private_generator_t *this);
94
95 /**
96 * Get length of data in buffer (in bytes).
97 *
98 * @param this private_generator_t object
99 * @return length of data in bytes
100 */
101 size_t (*get_current_data_length) (private_generator_t *this);
102
103 /**
104 * Get current offset in buffer (in bytes).
105 *
106 * @param this private_generator_t object
107 * @return offset in bytes
108 */
109 u_int32_t (*get_current_buffer_offset) (private_generator_t *this);
110
111 /**
112 * Generates a RESERVED BIT field or a RESERVED BYTE field and writes
113 * it to the buffer.
114 *
115 * @param this private_generator_t object
116 * @param generator_contexts generator_contexts_t object where the context is written or read from
117 * @param bits number of bits to generate
118 */
119 void (*generate_reserved_field) (private_generator_t *this,int bits);
120
121 /**
122 * Generates a FLAG field.
123 *
124 * @param this private_generator_t object
125 * @param generator_contexts generator_contexts_t object where the context is written or read from
126 * @param offset offset of flag value in data struct
127 */
128 void (*generate_flag) (private_generator_t *this,u_int32_t offset);
129
130 /**
131 * Writes the current buffer content into a chunk_t.
132 *
133 * Memory of specific chunk_t gets allocated.
134 *
135 * @param this calling private_generator_t object
136 * @param data pointer of chunk_t to write to
137 */
138 void (*write_chunk) (private_generator_t *this,chunk_t *data);
139
140 /**
141 * Generates a bytestream from a chunk_t.
142 *
143 * @param this private_generator_t object
144 * @param offset offset of chunk_t value in data struct
145 */
146 void (*generate_from_chunk) (private_generator_t *this,u_int32_t offset);
147
148 /**
149 * Makes sure enough space is available in buffer to store amount of bits.
150 *
151 * If buffer is to small to hold the specific amount of bits it
152 * is increased using reallocation function of allocator.
153 *
154 * @param this calling private_generator_t object
155 * @param bits number of bits to make available in buffer
156 */
157 void (*make_space_available) (private_generator_t *this,size_t bits);
158
159 /**
160 * Writes a specific amount of byte into the buffer.
161 *
162 * If buffer is to small to hold the specific amount of bytes it
163 * is increased.
164 *
165 * @param this calling private_generator_t object
166 * @param bytes pointer to bytes to write
167 * @param number_of_bytes number of bytes to write into buffer
168 */
169 void (*write_bytes_to_buffer) (private_generator_t *this,void * bytes,size_t number_of_bytes);
170
171
172 /**
173 * Writes a specific amount of byte into the buffer at a specific offset.
174 *
175 * @warning buffer size is not check to hold the data if offset is to large.
176 *
177 * @param this calling private_generator_t object
178 * @param bytes pointer to bytes to write
179 * @param number_of_bytes number of bytes to write into buffer
180 * @param offset offset to write the data into
181 */
182 void (*write_bytes_to_buffer_at_offset) (private_generator_t *this,void * bytes,size_t number_of_bytes,u_int32_t offset);
183
184 /**
185 * Buffer used to generate the data into.
186 */
187 u_int8_t *buffer;
188
189 /**
190 * Current write position in buffer (one byte aligned).
191 */
192 u_int8_t *out_position;
193
194 /**
195 * Position of last byte in buffer.
196 */
197 u_int8_t *roof_position;
198
199 /**
200 * Current bit writing to in current byte (between 0 and 7).
201 */
202 size_t current_bit;
203
204 /**
205 * Associated data struct to read informations from.
206 */
207 void * data_struct;
208
209 /*
210 * Last payload length position offset in the buffer.
211 */
212 u_int32_t last_payload_length_position_offset;
213
214 /**
215 * Offset of the header length field in the buffer.
216 */
217 u_int32_t header_length_position_offset;
218
219 /**
220 * Last SPI size.
221 */
222 u_int8_t last_spi_size;
223
224 /**
225 * Attribute format of the last generated transform attribute.
226 *
227 * Used to check if a variable value field is used or not for
228 * the transform attribute value.
229 */
230 bool attribute_format;
231
232 /**
233 * Depending on the value of attribute_format this field is used
234 * to hold the length of the transform attribute in bytes.
235 */
236 u_int16_t attribute_length;
237 };
238
239 /**
240 * Implementation of private_generator_t.get_current_buffer_size.
241 */
242 static size_t get_current_buffer_size (private_generator_t *this)
243 {
244 return ((this->roof_position) - (this->buffer));
245 }
246
247 /**
248 * Implementation of private_generator_t.get_current_buffer_space.
249 */
250 static size_t get_current_buffer_space (private_generator_t *this)
251 {
252 /* we know, one byte more */
253 size_t space = (this->roof_position) - (this->out_position);
254 return (space);
255 }
256
257 /**
258 * Implementation of private_generator_t.get_current_data_length.
259 */
260 static size_t get_current_data_length (private_generator_t *this)
261 {
262 return (this->out_position - this->buffer);
263 }
264
265 /**
266 * Implementation of private_generator_t.get_current_buffer_offset.
267 */
268 static u_int32_t get_current_buffer_offset (private_generator_t *this)
269 {
270 return (this->out_position - this->buffer);
271 }
272
273 /**
274 * Implementation of private_generator_t.generate_u_int_type.
275 */
276 static void generate_u_int_type (private_generator_t *this,encoding_type_t int_type,u_int32_t offset)
277 {
278 size_t number_of_bits = 0;
279
280 /* find out number of bits of each U_INT type to check for enough space
281 in buffer */
282 switch (int_type)
283 {
284 case U_INT_4:
285 number_of_bits = 4;
286 break;
287 case TS_TYPE:
288 case U_INT_8:
289 number_of_bits = 8;
290 break;
291 case U_INT_16:
292 case CONFIGURATION_ATTRIBUTE_LENGTH:
293 number_of_bits = 16;
294 break;
295 case U_INT_32:
296 number_of_bits = 32;
297 break;
298 case U_INT_64:
299 number_of_bits = 64;
300 break;
301 case ATTRIBUTE_TYPE:
302 number_of_bits = 15;
303 break;
304 case IKE_SPI:
305 number_of_bits = 64;
306 break;
307
308 default:
309 DBG1(DBG_ENC, "U_INT Type %N is not supported",
310 encoding_type_names, int_type);
311
312 return;
313 }
314 /* U_INT Types of multiple then 8 bits must be aligned */
315 if (((number_of_bits % 8) == 0) && (this->current_bit != 0))
316 {
317 DBG1(DBG_ENC, "U_INT Type %N is not 8 Bit aligned",
318 encoding_type_names, int_type);
319 /* current bit has to be zero for values multiple of 8 bits */
320 return;
321 }
322
323 /* make sure enough space is available in buffer */
324 this->make_space_available(this,number_of_bits);
325 /* now handle each u int type differently */
326 switch (int_type)
327 {
328 case U_INT_4:
329 {
330 if (this->current_bit == 0)
331 {
332 /* highval of current byte in buffer has to be set to the new value*/
333 u_int8_t high_val = *((u_int8_t *)(this->data_struct + offset)) << 4;
334 /* lowval in buffer is not changed */
335 u_int8_t low_val = *(this->out_position) & 0x0F;
336 /* highval is set, low_val is not changed */
337 *(this->out_position) = high_val | low_val;
338 DBG3(DBG_ENC, " => %d", *(this->out_position));
339 /* write position is not changed, just bit position is moved */
340 this->current_bit = 4;
341 }
342 else if (this->current_bit == 4)
343 {
344 /* highval in buffer is not changed */
345 u_int high_val = *(this->out_position) & 0xF0;
346 /* lowval of current byte in buffer has to be set to the new value*/
347 u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
348 *(this->out_position) = high_val | low_val;
349 DBG3(DBG_ENC, " => %d", *(this->out_position));
350 this->out_position++;
351 this->current_bit = 0;
352
353 }
354 else
355 {
356 DBG1(DBG_ENC, "U_INT_4 Type is not 4 Bit aligned");
357 /* 4 Bit integers must have a 4 bit alignment */
358 return;
359 };
360 break;
361 }
362 case TS_TYPE:
363 case U_INT_8:
364 {
365 /* 8 bit values are written as they are */
366 *this->out_position = *((u_int8_t *)(this->data_struct + offset));
367 DBG3(DBG_ENC, " => %d", *(this->out_position));
368 this->out_position++;
369 break;
370
371 }
372 case ATTRIBUTE_TYPE:
373 {
374 /* attribute type must not change first bit uf current byte ! */
375 if (this->current_bit != 1)
376 {
377 DBG1(DBG_ENC, "ATTRIBUTE FORMAT flag is not set");
378 /* first bit has to be set! */
379 return;
380 }
381 /* get value of attribute format flag */
382 u_int8_t attribute_format_flag = *(this->out_position) & 0x80;
383 /* get attribute type value as 16 bit integer*/
384 u_int16_t int16_val = *((u_int16_t*)(this->data_struct + offset));
385 /* unset most significant bit */
386 int16_val &= 0x7FFF;
387 if (attribute_format_flag)
388 {
389 int16_val |= 0x8000;
390 }
391 int16_val = htons(int16_val);
392 DBG3(DBG_ENC, " => %d", int16_val);
393 /* write bytes to buffer (set bit is overwritten)*/
394 this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
395 this->current_bit = 0;
396 break;
397
398 }
399 case U_INT_16:
400 case CONFIGURATION_ATTRIBUTE_LENGTH:
401 {
402 u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset)));
403 DBG3(DBG_ENC, " => %b", (void*)&int16_val, sizeof(int16_val));
404 this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
405 break;
406 }
407 case U_INT_32:
408 {
409 u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset)));
410 DBG3(DBG_ENC, " => %b", (void*)&int32_val, sizeof(int32_val));
411 this->write_bytes_to_buffer(this,&int32_val,sizeof(u_int32_t));
412 break;
413 }
414 case U_INT_64:
415 {
416 /* 64 bit integers are written as two 32 bit integers */
417 u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset)));
418 u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1));
419 DBG3(DBG_ENC, " => %b %b",
420 (void*)&int32_val_low, sizeof(int32_val_low),
421 (void*)&int32_val_high, sizeof(int32_val_high));
422 /* TODO add support for big endian machines */
423 this->write_bytes_to_buffer(this,&int32_val_high,sizeof(u_int32_t));
424 this->write_bytes_to_buffer(this,&int32_val_low,sizeof(u_int32_t));
425 break;
426 }
427
428 case IKE_SPI:
429 {
430 /* 64 bit are written as they come :-) */
431 this->write_bytes_to_buffer(this,(this->data_struct + offset),sizeof(u_int64_t));
432 DBG3(DBG_ENC, " => %b", (void*)(this->data_struct + offset), sizeof(u_int64_t));
433 break;
434 }
435 default:
436 {
437 DBG1(DBG_ENC, "U_INT Type %N is not supported",
438 encoding_type_names, int_type);
439 return;
440 }
441 }
442 }
443
444 /**
445 * Implementation of private_generator_t.generate_reserved_field.
446 */
447 static void generate_reserved_field(private_generator_t *this,int bits)
448 {
449 /* only one bit or 8 bit fields are supported */
450 if ((bits != 1) && (bits != 8))
451 {
452 DBG1(DBG_ENC, "reserved field of %d bits cannot be generated", bits);
453 return ;
454 }
455 /* make sure enough space is available in buffer */
456 this->make_space_available(this,bits);
457
458 if (bits == 1)
459 {
460 /* one bit processing */
461 u_int8_t reserved_bit = ~(1 << (7 - this->current_bit));
462 *(this->out_position) = *(this->out_position) & reserved_bit;
463 if (this->current_bit == 0)
464 {
465 /* memory must be zero */
466 *(this->out_position) = 0x00;
467 }
468
469
470 this->current_bit++;
471 if (this->current_bit >= 8)
472 {
473 this->current_bit = this->current_bit % 8;
474 this->out_position++;
475 }
476 }
477 else
478 {
479 /* one byte processing*/
480 if (this->current_bit > 0)
481 {
482 DBG1(DBG_ENC, "reserved field cannot be written cause "
483 "alignement of current bit is %d", this->current_bit);
484 return;
485 }
486 *(this->out_position) = 0x00;
487 this->out_position++;
488 }
489 }
490
491 /**
492 * Implementation of private_generator_t.generate_flag.
493 */
494 static void generate_flag (private_generator_t *this,u_int32_t offset)
495 {
496 /* value of current flag */
497 u_int8_t flag_value;
498 /* position of flag in current byte */
499 u_int8_t flag;
500
501 /* if the value in the data_struct is TRUE, flag_value is set to 1, 0 otherwise */
502 flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
503 /* get flag position */
504 flag = (flag_value << (7 - this->current_bit));
505
506 /* make sure one bit is available in buffer */
507 this->make_space_available(this,1);
508 if (this->current_bit == 0)
509 {
510 /* memory must be zero */
511 *(this->out_position) = 0x00;
512 }
513
514 *(this->out_position) = *(this->out_position) | flag;
515
516
517 DBG3(DBG_ENC, " => %d", *(this->out_position));
518
519 this->current_bit++;
520 if (this->current_bit >= 8)
521 {
522 this->current_bit = this->current_bit % 8;
523 this->out_position++;
524 }
525 }
526
527 /**
528 * Implementation of private_generator_t.generate_from_chunk.
529 */
530 static void generate_from_chunk (private_generator_t *this,u_int32_t offset)
531 {
532 if (this->current_bit != 0)
533 {
534 DBG1(DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
535 return ;
536 }
537
538 /* position in buffer */
539 chunk_t *attribute_value = (chunk_t *)(this->data_struct + offset);
540
541 DBG3(DBG_ENC, " => %B", attribute_value);
542
543 /* use write_bytes_to_buffer function to do the job */
544 this->write_bytes_to_buffer(this,attribute_value->ptr,attribute_value->len);
545 }
546
547 /**
548 * Implementation of private_generator_t.make_space_available.
549 */
550 static void make_space_available (private_generator_t *this, size_t bits)
551 {
552 while (((this->get_current_buffer_space(this) * 8) - this->current_bit) < bits)
553 {
554 /* must increase buffer */
555 size_t old_buffer_size = this->get_current_buffer_size(this);
556 size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
557 size_t out_position_offset = ((this->out_position) - (this->buffer));
558
559 DBG2(DBG_ENC, "increased gen buffer from %d to %d byte",
560 old_buffer_size, new_buffer_size);
561
562 /* Reallocate space for new buffer */
563 this->buffer = realloc(this->buffer,new_buffer_size);
564
565 this->out_position = (this->buffer + out_position_offset);
566 this->roof_position = (this->buffer + new_buffer_size);
567 }
568 }
569
570 /**
571 * Implementation of private_generator_t.write_bytes_to_buffer.
572 */
573 static void write_bytes_to_buffer (private_generator_t *this,void * bytes, size_t number_of_bytes)
574 {
575 int i;
576 u_int8_t *read_position = (u_int8_t *) bytes;
577
578 this->make_space_available(this,number_of_bytes * 8);
579
580 for (i = 0; i < number_of_bytes; i++)
581 {
582 *(this->out_position) = *(read_position);
583 read_position++;
584 this->out_position++;
585 }
586 }
587
588 /**
589 * Implementation of private_generator_t.write_bytes_to_buffer_at_offset.
590 */
591 static void write_bytes_to_buffer_at_offset (private_generator_t *this,void * bytes,size_t number_of_bytes,u_int32_t offset)
592 {
593 int i;
594 u_int8_t *read_position = (u_int8_t *) bytes;
595 u_int8_t *write_position;
596 u_int32_t free_space_after_offset = (this->get_current_buffer_size(this) - offset);
597
598 /* check first if enough space for new data is available */
599 if (number_of_bytes > free_space_after_offset)
600 {
601 this->make_space_available(this,(number_of_bytes - free_space_after_offset) * 8);
602 }
603
604 write_position = this->buffer + offset;
605 for (i = 0; i < number_of_bytes; i++)
606 {
607 *(write_position) = *(read_position);
608 read_position++;
609 write_position++;
610 }
611 }
612
613 /**
614 * Implementation of private_generator_t.write_to_chunk.
615 */
616 static void write_to_chunk (private_generator_t *this,chunk_t *data)
617 {
618 size_t data_length = this->get_current_data_length(this);
619 u_int32_t header_length_field = data_length;
620
621 /* write length into header length field */
622 if (this->header_length_position_offset > 0)
623 {
624 u_int32_t int32_val = htonl(header_length_field);
625 this->write_bytes_to_buffer_at_offset(this,&int32_val,sizeof(u_int32_t),this->header_length_position_offset);
626 }
627
628 if (this->current_bit > 0)
629 data_length++;
630 data->ptr = malloc(data_length);
631 memcpy(data->ptr,this->buffer,data_length);
632 data->len = data_length;
633
634 DBG3(DBG_ENC, "generated data of this generator %B", data);
635 }
636
637 /**
638 * Implementation of private_generator_t.generate_payload.
639 */
640 static void generate_payload (private_generator_t *this,payload_t *payload)
641 {
642 int i;
643 this->data_struct = payload;
644 size_t rule_count;
645 encoding_rule_t *rules;
646 payload_type_t payload_type;
647 u_int8_t *payload_start;
648
649 /* get payload type */
650 payload_type = payload->get_type(payload);
651 /* spi size has to get reseted */
652 this->last_spi_size = 0;
653
654 payload_start = this->out_position;
655
656 DBG2(DBG_ENC, "generating payload of type %N",
657 payload_type_names, payload_type);
658
659 /* each payload has its own encoding rules */
660 payload->get_encoding_rules(payload,&rules,&rule_count);
661
662 for (i = 0; i < rule_count;i++)
663 {
664 DBG2(DBG_ENC, " generating rule %d %N",
665 i, encoding_type_names, rules[i].type);
666 switch (rules[i].type)
667 {
668 /* all u int values, IKE_SPI,TS_TYPE and ATTRIBUTE_TYPE are generated in generate_u_int_type */
669 case U_INT_4:
670 case U_INT_8:
671 case U_INT_16:
672 case U_INT_32:
673 case U_INT_64:
674 case IKE_SPI:
675 case TS_TYPE:
676 case ATTRIBUTE_TYPE:
677 case CONFIGURATION_ATTRIBUTE_LENGTH:
678 {
679 this->generate_u_int_type(this,rules[i].type,rules[i].offset);
680 break;
681 }
682 case RESERVED_BIT:
683 {
684 this->generate_reserved_field(this,1);
685 break;
686 }
687 case RESERVED_BYTE:
688 {
689 this->generate_reserved_field(this,8);
690 break;
691 }
692 case FLAG:
693 {
694 this->generate_flag(this,rules[i].offset);
695 break;
696 }
697 case PAYLOAD_LENGTH:
698 {
699 /* position of payload lenght field is temporary stored */
700 this->last_payload_length_position_offset = this->get_current_buffer_offset(this);
701 /* payload length is generated like an U_INT_16 */
702 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
703 break;
704 }
705 case HEADER_LENGTH:
706 {
707 /* position of header length field is temporary stored */
708 this->header_length_position_offset = this->get_current_buffer_offset(this);
709 /* header length is generated like an U_INT_32 */
710 this->generate_u_int_type(this,U_INT_32,rules[i].offset);
711 break;
712 }
713 case SPI_SIZE:
714 /* spi size is handled as 8 bit unsigned integer */
715 this->generate_u_int_type(this,U_INT_8,rules[i].offset);
716 /* last spi size is temporary stored */
717 this->last_spi_size = *((u_int8_t *)(this->data_struct + rules[i].offset));
718 break;
719 case ADDRESS:
720 {
721 /* the Address value is generated from chunk */
722 this->generate_from_chunk(this,rules[i].offset);
723 break;
724 }
725 case SPI:
726 {
727 /* the SPI value is generated from chunk */
728 this->generate_from_chunk(this,rules[i].offset);
729 break;
730 }
731 case KEY_EXCHANGE_DATA:
732 case NOTIFICATION_DATA:
733 case NONCE_DATA:
734 case ID_DATA:
735 case AUTH_DATA:
736 case CERT_DATA:
737 case CERTREQ_DATA:
738 case SPIS:
739 case CONFIGURATION_ATTRIBUTE_VALUE:
740 case VID_DATA:
741 case EAP_MESSAGE:
742 {
743 u_int32_t payload_length_position_offset;
744 u_int16_t length_of_payload;
745 u_int16_t header_length = 0;
746 u_int16_t length_in_network_order;
747
748 switch(rules[i].type)
749 {
750 case KEY_EXCHANGE_DATA:
751 header_length = KE_PAYLOAD_HEADER_LENGTH;
752 break;
753 case NOTIFICATION_DATA:
754 header_length = NOTIFY_PAYLOAD_HEADER_LENGTH + this->last_spi_size ;
755 break;
756 case NONCE_DATA:
757 header_length = NONCE_PAYLOAD_HEADER_LENGTH;
758 break;
759 case ID_DATA:
760 header_length = ID_PAYLOAD_HEADER_LENGTH;
761 break;
762 case AUTH_DATA:
763 header_length = AUTH_PAYLOAD_HEADER_LENGTH;
764 break;
765 case CERT_DATA:
766 header_length = CERT_PAYLOAD_HEADER_LENGTH;
767 break;
768 case CERTREQ_DATA:
769 header_length = CERTREQ_PAYLOAD_HEADER_LENGTH;
770 break;
771 case SPIS:
772 header_length = DELETE_PAYLOAD_HEADER_LENGTH;
773 break;
774 case VID_DATA:
775 header_length = VENDOR_ID_PAYLOAD_HEADER_LENGTH;
776 break;
777 case CONFIGURATION_ATTRIBUTE_VALUE:
778 header_length = CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
779 break;
780 case EAP_MESSAGE:
781 header_length = EAP_PAYLOAD_HEADER_LENGTH;
782 break;
783 default:
784 break;
785 }
786
787 /* the data value is generated from chunk */
788 this->generate_from_chunk(this,rules[i].offset);
789
790 payload_length_position_offset = this->last_payload_length_position_offset;
791
792
793 /* Length of payload is calculated */
794 length_of_payload = header_length + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
795
796 length_in_network_order = htons(length_of_payload);
797 this->write_bytes_to_buffer_at_offset(this,&length_in_network_order,sizeof(u_int16_t),payload_length_position_offset);
798 break;
799 }
800 case PROPOSALS:
801 {
802 /* before iterative generate the transforms, store the current payload length position */
803 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
804 /* Length of SA_PAYLOAD is calculated */
805 u_int16_t length_of_sa_payload = SA_PAYLOAD_HEADER_LENGTH;
806 u_int16_t int16_val;
807 /* proposals are stored in a linked list and so accessed */
808 linked_list_t *proposals = *((linked_list_t **)(this->data_struct + rules[i].offset));
809 iterator_t *iterator;
810 payload_t *current_proposal;
811
812 /* create forward iterator */
813 iterator = proposals->create_iterator(proposals,TRUE);
814 /* every proposal is processed (iterative call )*/
815 while (iterator->iterate(iterator, (void**)&current_proposal))
816 {
817 u_int32_t before_generate_position_offset;
818 u_int32_t after_generate_position_offset;
819
820 before_generate_position_offset = this->get_current_buffer_offset(this);
821 this->public.generate_payload(&(this->public),current_proposal);
822 after_generate_position_offset = this->get_current_buffer_offset(this);
823
824 /* increase size of transform */
825 length_of_sa_payload += (after_generate_position_offset - before_generate_position_offset);
826 }
827 iterator->destroy(iterator);
828
829 int16_val = htons(length_of_sa_payload);
830 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
831 break;
832 }
833 case TRANSFORMS:
834 {
835 /* before iterative generate the transforms, store the current length position */
836 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
837 u_int16_t length_of_proposal = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH + this->last_spi_size;
838 u_int16_t int16_val;
839 linked_list_t *transforms = *((linked_list_t **)(this->data_struct + rules[i].offset));
840 iterator_t *iterator;
841 payload_t *current_transform;
842
843 /* create forward iterator */
844 iterator = transforms->create_iterator(transforms,TRUE);
845 while (iterator->iterate(iterator, (void**)&current_transform))
846 {
847 u_int32_t before_generate_position_offset;
848 u_int32_t after_generate_position_offset;
849
850 before_generate_position_offset = this->get_current_buffer_offset(this);
851 this->public.generate_payload(&(this->public),current_transform);
852 after_generate_position_offset = this->get_current_buffer_offset(this);
853
854 /* increase size of transform */
855 length_of_proposal += (after_generate_position_offset - before_generate_position_offset);
856 }
857
858 iterator->destroy(iterator);
859
860 int16_val = htons(length_of_proposal);
861 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
862
863 break;
864 }
865 case TRANSFORM_ATTRIBUTES:
866 {
867 /* before iterative generate the transform attributes, store the current length position */
868 u_int32_t transform_length_position_offset = this->last_payload_length_position_offset;
869 u_int16_t length_of_transform = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
870 u_int16_t int16_val;
871 linked_list_t *transform_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
872 iterator_t *iterator;
873 payload_t *current_attribute;
874
875 /* create forward iterator */
876 iterator = transform_attributes->create_iterator(transform_attributes,TRUE);
877 while (iterator->iterate(iterator, (void**)&current_attribute))
878 {
879 u_int32_t before_generate_position_offset;
880 u_int32_t after_generate_position_offset;
881
882 before_generate_position_offset = this->get_current_buffer_offset(this);
883 this->public.generate_payload(&(this->public),current_attribute);
884 after_generate_position_offset = this->get_current_buffer_offset(this);
885
886 /* increase size of transform */
887 length_of_transform += (after_generate_position_offset - before_generate_position_offset);
888 }
889
890 iterator->destroy(iterator);
891
892 int16_val = htons(length_of_transform);
893 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),transform_length_position_offset);
894
895 break;
896 }
897 case CONFIGURATION_ATTRIBUTES:
898 {
899 /* before iterative generate the configuration attributes, store the current length position */
900 u_int32_t configurations_length_position_offset = this->last_payload_length_position_offset;
901 u_int16_t length_of_configurations = CP_PAYLOAD_HEADER_LENGTH;
902 u_int16_t int16_val;
903 linked_list_t *configuration_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
904 iterator_t *iterator;
905 payload_t *current_attribute;
906
907 /* create forward iterator */
908 iterator = configuration_attributes->create_iterator(configuration_attributes,TRUE);
909 while (iterator->iterate(iterator, (void**)&current_attribute))
910 {
911 u_int32_t before_generate_position_offset;
912 u_int32_t after_generate_position_offset;
913
914 before_generate_position_offset = this->get_current_buffer_offset(this);
915 this->public.generate_payload(&(this->public),current_attribute);
916 after_generate_position_offset = this->get_current_buffer_offset(this);
917
918 /* increase size of transform */
919 length_of_configurations += (after_generate_position_offset - before_generate_position_offset);
920 }
921
922 iterator->destroy(iterator);
923
924 int16_val = htons(length_of_configurations);
925 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),configurations_length_position_offset);
926
927 break;
928 }
929 case ATTRIBUTE_FORMAT:
930 {
931 this->generate_flag(this,rules[i].offset);
932 /* Attribute format is a flag which is stored in context*/
933 this->attribute_format = *((bool *) (this->data_struct + rules[i].offset));
934 break;
935 }
936
937 case ATTRIBUTE_LENGTH_OR_VALUE:
938 {
939 if (this->attribute_format == FALSE)
940 {
941 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
942 /* this field hold the length of the attribute */
943 this->attribute_length = *((u_int16_t *)(this->data_struct + rules[i].offset));
944 }
945 else
946 {
947 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
948 }
949 break;
950 }
951 case ATTRIBUTE_VALUE:
952 {
953 if (this->attribute_format == FALSE)
954 {
955 DBG2(DBG_ENC, "attribute value has not fixed size");
956 /* the attribute value is generated */
957 this->generate_from_chunk(this,rules[i].offset);
958 }
959 break;
960 }
961 case TRAFFIC_SELECTORS:
962 {
963 /* before iterative generate the traffic_selectors, store the current payload length position */
964 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
965 /* Length of SA_PAYLOAD is calculated */
966 u_int16_t length_of_ts_payload = TS_PAYLOAD_HEADER_LENGTH;
967 u_int16_t int16_val;
968 /* traffic selectors are stored in a linked list and so accessed */
969 linked_list_t *traffic_selectors = *((linked_list_t **)(this->data_struct + rules[i].offset));
970 iterator_t *iterator;
971 payload_t *current_traffic_selector_substructure;
972
973 /* create forward iterator */
974 iterator = traffic_selectors->create_iterator(traffic_selectors,TRUE);
975 /* every proposal is processed (iterative call )*/
976 while (iterator->iterate(iterator, (void **)&current_traffic_selector_substructure))
977 {
978 u_int32_t before_generate_position_offset;
979 u_int32_t after_generate_position_offset;
980
981 before_generate_position_offset = this->get_current_buffer_offset(this);
982 this->public.generate_payload(&(this->public),current_traffic_selector_substructure);
983 after_generate_position_offset = this->get_current_buffer_offset(this);
984
985 /* increase size of transform */
986 length_of_ts_payload += (after_generate_position_offset - before_generate_position_offset);
987 }
988 iterator->destroy(iterator);
989
990 int16_val = htons(length_of_ts_payload);
991 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
992 break;
993 }
994
995 case ENCRYPTED_DATA:
996 {
997 this->generate_from_chunk(this, rules[i].offset);
998 break;
999 }
1000 default:
1001 DBG1(DBG_ENC, "field type %N is not supported",
1002 encoding_type_names, rules[i].type);
1003 return;
1004 }
1005 }
1006 DBG2(DBG_ENC, "generating %N payload finished",
1007 payload_type_names, payload_type);
1008 DBG3(DBG_ENC, "generated data for this payload %b",
1009 payload_start, this->out_position-payload_start);
1010 }
1011
1012 /**
1013 * Implementation of generator_t.destroy.
1014 */
1015 static status_t destroy(private_generator_t *this)
1016 {
1017 free(this->buffer);
1018 free(this);
1019 return SUCCESS;
1020 }
1021
1022 /*
1023 * Described in header
1024 */
1025 generator_t *generator_create()
1026 {
1027 private_generator_t *this;
1028
1029 this = malloc_thing(private_generator_t);
1030
1031 /* initiate public functions */
1032 this->public.generate_payload = (void(*)(generator_t*, payload_t *)) generate_payload;
1033 this->public.destroy = (void(*)(generator_t*)) destroy;
1034 this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *)) write_to_chunk;
1035
1036
1037 /* initiate private functions */
1038 this->get_current_buffer_size = get_current_buffer_size;
1039 this->get_current_buffer_space = get_current_buffer_space;
1040 this->get_current_data_length = get_current_data_length;
1041 this->get_current_buffer_offset = get_current_buffer_offset;
1042 this->generate_u_int_type = generate_u_int_type;
1043 this->generate_reserved_field = generate_reserved_field;
1044 this->generate_flag = generate_flag;
1045 this->generate_from_chunk = generate_from_chunk;
1046 this->make_space_available = make_space_available;
1047 this->write_bytes_to_buffer = write_bytes_to_buffer;
1048 this->write_bytes_to_buffer_at_offset = write_bytes_to_buffer_at_offset;
1049
1050
1051 /* allocate memory for buffer */
1052 this->buffer = malloc(GENERATOR_DATA_BUFFER_SIZE);
1053
1054 /* initiate private variables */
1055 this->out_position = this->buffer;
1056 this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
1057 this->data_struct = NULL;
1058 this->current_bit = 0;
1059 this->last_payload_length_position_offset = 0;
1060 this->header_length_position_offset = 0;
1061
1062 return &(this->public);
1063 }