removed deprecated iterator methods (has_next & current)
[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 <types.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(SIG_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(SIG_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(SIG_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(SIG_DBG_ENC, " => %d", *(this->out_position));
350 this->out_position++;
351 this->current_bit = 0;
352
353 }
354 else
355 {
356 DBG1(SIG_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(SIG_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(SIG_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 = htons(*((u_int16_t*)(this->data_struct + offset)));
385 /* last bit must be unset */
386 int16_val = int16_val & 0xFF7F;
387
388 int16_val = int16_val | attribute_format_flag;
389 DBG3(SIG_DBG_ENC, " => %d", int16_val);
390 /* write bytes to buffer (set bit is overwritten)*/
391 this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
392 this->current_bit = 0;
393 break;
394
395 }
396 case U_INT_16:
397 case CONFIGURATION_ATTRIBUTE_LENGTH:
398 {
399 u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset)));
400 DBG3(SIG_DBG_ENC, " => %b", (void*)&int16_val, sizeof(int16_val));
401 this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
402 break;
403 }
404 case U_INT_32:
405 {
406 u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset)));
407 DBG3(SIG_DBG_ENC, " => %b", (void*)&int32_val, sizeof(int32_val));
408 this->write_bytes_to_buffer(this,&int32_val,sizeof(u_int32_t));
409 break;
410 }
411 case U_INT_64:
412 {
413 /* 64 bit integers are written as two 32 bit integers */
414 u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset)));
415 u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1));
416 DBG3(SIG_DBG_ENC, " => %b %b",
417 (void*)&int32_val_low, sizeof(int32_val_low),
418 (void*)&int32_val_high, sizeof(int32_val_high));
419 /* TODO add support for big endian machines */
420 this->write_bytes_to_buffer(this,&int32_val_high,sizeof(u_int32_t));
421 this->write_bytes_to_buffer(this,&int32_val_low,sizeof(u_int32_t));
422 break;
423 }
424
425 case IKE_SPI:
426 {
427 /* 64 bit are written as they come :-) */
428 this->write_bytes_to_buffer(this,(this->data_struct + offset),sizeof(u_int64_t));
429 DBG3(SIG_DBG_ENC, " => %b", (void*)(this->data_struct + offset), sizeof(u_int64_t));
430 break;
431 }
432 default:
433 {
434 DBG1(SIG_DBG_ENC, "U_INT Type %N is not supported",
435 encoding_type_names, int_type);
436 return;
437 }
438 }
439 }
440
441 /**
442 * Implementation of private_generator_t.generate_reserved_field.
443 */
444 static void generate_reserved_field(private_generator_t *this,int bits)
445 {
446 /* only one bit or 8 bit fields are supported */
447 if ((bits != 1) && (bits != 8))
448 {
449 DBG1(SIG_DBG_ENC, "reserved field of %d bits cannot be generated", bits);
450 return ;
451 }
452 /* make sure enough space is available in buffer */
453 this->make_space_available(this,bits);
454
455 if (bits == 1)
456 {
457 /* one bit processing */
458 u_int8_t reserved_bit = ~(1 << (7 - this->current_bit));
459 *(this->out_position) = *(this->out_position) & reserved_bit;
460 if (this->current_bit == 0)
461 {
462 /* memory must be zero */
463 *(this->out_position) = 0x00;
464 }
465
466
467 this->current_bit++;
468 if (this->current_bit >= 8)
469 {
470 this->current_bit = this->current_bit % 8;
471 this->out_position++;
472 }
473 }
474 else
475 {
476 /* one byte processing*/
477 if (this->current_bit > 0)
478 {
479 DBG1(SIG_DBG_ENC, "reserved field cannot be written cause "
480 "alignement of current bit is %d", this->current_bit);
481 return;
482 }
483 *(this->out_position) = 0x00;
484 this->out_position++;
485 }
486 }
487
488 /**
489 * Implementation of private_generator_t.generate_flag.
490 */
491 static void generate_flag (private_generator_t *this,u_int32_t offset)
492 {
493 /* value of current flag */
494 u_int8_t flag_value;
495 /* position of flag in current byte */
496 u_int8_t flag;
497
498 /* if the value in the data_struct is TRUE, flag_value is set to 1, 0 otherwise */
499 flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0;
500 /* get flag position */
501 flag = (flag_value << (7 - this->current_bit));
502
503 /* make sure one bit is available in buffer */
504 this->make_space_available(this,1);
505 if (this->current_bit == 0)
506 {
507 /* memory must be zero */
508 *(this->out_position) = 0x00;
509 }
510
511 *(this->out_position) = *(this->out_position) | flag;
512
513
514 DBG3(SIG_DBG_ENC, " => %d", *(this->out_position));
515
516 this->current_bit++;
517 if (this->current_bit >= 8)
518 {
519 this->current_bit = this->current_bit % 8;
520 this->out_position++;
521 }
522 }
523
524 /**
525 * Implementation of private_generator_t.generate_from_chunk.
526 */
527 static void generate_from_chunk (private_generator_t *this,u_int32_t offset)
528 {
529 if (this->current_bit != 0)
530 {
531 DBG1(SIG_DBG_ENC, "can not generate a chunk at Bitpos %d", this->current_bit);
532 return ;
533 }
534
535 /* position in buffer */
536 chunk_t *attribute_value = (chunk_t *)(this->data_struct + offset);
537
538 DBG3(SIG_DBG_ENC, " => %B", attribute_value);
539
540 /* use write_bytes_to_buffer function to do the job */
541 this->write_bytes_to_buffer(this,attribute_value->ptr,attribute_value->len);
542 }
543
544 /**
545 * Implementation of private_generator_t.make_space_available.
546 */
547 static void make_space_available (private_generator_t *this, size_t bits)
548 {
549 while (((this->get_current_buffer_space(this) * 8) - this->current_bit) < bits)
550 {
551 /* must increase buffer */
552 size_t old_buffer_size = this->get_current_buffer_size(this);
553 size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE;
554 size_t out_position_offset = ((this->out_position) - (this->buffer));
555
556 DBG2(SIG_DBG_ENC, "increased gen buffer from %d to %d byte",
557 old_buffer_size, new_buffer_size);
558
559 /* Reallocate space for new buffer */
560 this->buffer = realloc(this->buffer,new_buffer_size);
561
562 this->out_position = (this->buffer + out_position_offset);
563 this->roof_position = (this->buffer + new_buffer_size);
564 }
565 }
566
567 /**
568 * Implementation of private_generator_t.write_bytes_to_buffer.
569 */
570 static void write_bytes_to_buffer (private_generator_t *this,void * bytes, size_t number_of_bytes)
571 {
572 int i;
573 u_int8_t *read_position = (u_int8_t *) bytes;
574
575 this->make_space_available(this,number_of_bytes * 8);
576
577 for (i = 0; i < number_of_bytes; i++)
578 {
579 *(this->out_position) = *(read_position);
580 read_position++;
581 this->out_position++;
582 }
583 }
584
585 /**
586 * Implementation of private_generator_t.write_bytes_to_buffer_at_offset.
587 */
588 static void write_bytes_to_buffer_at_offset (private_generator_t *this,void * bytes,size_t number_of_bytes,u_int32_t offset)
589 {
590 int i;
591 u_int8_t *read_position = (u_int8_t *) bytes;
592 u_int8_t *write_position;
593 u_int32_t free_space_after_offset = (this->get_current_buffer_size(this) - offset);
594
595 /* check first if enough space for new data is available */
596 if (number_of_bytes > free_space_after_offset)
597 {
598 this->make_space_available(this,(number_of_bytes - free_space_after_offset) * 8);
599 }
600
601 write_position = this->buffer + offset;
602 for (i = 0; i < number_of_bytes; i++)
603 {
604 *(write_position) = *(read_position);
605 read_position++;
606 write_position++;
607 }
608 }
609
610 /**
611 * Implementation of private_generator_t.write_to_chunk.
612 */
613 static void write_to_chunk (private_generator_t *this,chunk_t *data)
614 {
615 size_t data_length = this->get_current_data_length(this);
616 u_int32_t header_length_field = data_length;
617
618 /* write length into header length field */
619 if (this->header_length_position_offset > 0)
620 {
621 u_int32_t int32_val = htonl(header_length_field);
622 this->write_bytes_to_buffer_at_offset(this,&int32_val,sizeof(u_int32_t),this->header_length_position_offset);
623 }
624
625 if (this->current_bit > 0)
626 data_length++;
627 data->ptr = malloc(data_length);
628 memcpy(data->ptr,this->buffer,data_length);
629 data->len = data_length;
630
631 DBG3(SIG_DBG_ENC, "generated data of this generator %B", data);
632 }
633
634 /**
635 * Implementation of private_generator_t.generate_payload.
636 */
637 static void generate_payload (private_generator_t *this,payload_t *payload)
638 {
639 int i;
640 this->data_struct = payload;
641 size_t rule_count;
642 encoding_rule_t *rules;
643 payload_type_t payload_type;
644 u_int8_t *payload_start;
645
646 /* get payload type */
647 payload_type = payload->get_type(payload);
648 /* spi size has to get reseted */
649 this->last_spi_size = 0;
650
651 payload_start = this->out_position;
652
653 DBG2(SIG_DBG_ENC, "generating payload of type %N",
654 payload_type_names, payload_type);
655
656 /* each payload has its own encoding rules */
657 payload->get_encoding_rules(payload,&rules,&rule_count);
658
659 for (i = 0; i < rule_count;i++)
660 {
661 DBG2(SIG_DBG_ENC, " generating rule %d %N",
662 i, encoding_type_names, rules[i].type);
663 switch (rules[i].type)
664 {
665 /* all u int values, IKE_SPI,TS_TYPE and ATTRIBUTE_TYPE are generated in generate_u_int_type */
666 case U_INT_4:
667 case U_INT_8:
668 case U_INT_16:
669 case U_INT_32:
670 case U_INT_64:
671 case IKE_SPI:
672 case TS_TYPE:
673 case ATTRIBUTE_TYPE:
674 case CONFIGURATION_ATTRIBUTE_LENGTH:
675 {
676 this->generate_u_int_type(this,rules[i].type,rules[i].offset);
677 break;
678 }
679 case RESERVED_BIT:
680 {
681 this->generate_reserved_field(this,1);
682 break;
683 }
684 case RESERVED_BYTE:
685 {
686 this->generate_reserved_field(this,8);
687 break;
688 }
689 case FLAG:
690 {
691 this->generate_flag(this,rules[i].offset);
692 break;
693 }
694 case PAYLOAD_LENGTH:
695 {
696 /* position of payload lenght field is temporary stored */
697 this->last_payload_length_position_offset = this->get_current_buffer_offset(this);
698 /* payload length is generated like an U_INT_16 */
699 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
700 break;
701 }
702 case HEADER_LENGTH:
703 {
704 /* position of header length field is temporary stored */
705 this->header_length_position_offset = this->get_current_buffer_offset(this);
706 /* header length is generated like an U_INT_32 */
707 this->generate_u_int_type(this,U_INT_32,rules[i].offset);
708 break;
709 }
710 case SPI_SIZE:
711 /* spi size is handled as 8 bit unsigned integer */
712 this->generate_u_int_type(this,U_INT_8,rules[i].offset);
713 /* last spi size is temporary stored */
714 this->last_spi_size = *((u_int8_t *)(this->data_struct + rules[i].offset));
715 break;
716 case ADDRESS:
717 {
718 /* the Address value is generated from chunk */
719 this->generate_from_chunk(this,rules[i].offset);
720 break;
721 }
722 case SPI:
723 {
724 /* the SPI value is generated from chunk */
725 this->generate_from_chunk(this,rules[i].offset);
726 break;
727 }
728 case KEY_EXCHANGE_DATA:
729 case NOTIFICATION_DATA:
730 case NONCE_DATA:
731 case ID_DATA:
732 case AUTH_DATA:
733 case CERT_DATA:
734 case CERTREQ_DATA:
735 case SPIS:
736 case CONFIGURATION_ATTRIBUTE_VALUE:
737 case VID_DATA:
738 case EAP_MESSAGE:
739 {
740 u_int32_t payload_length_position_offset;
741 u_int16_t length_of_payload;
742 u_int16_t header_length = 0;
743 u_int16_t length_in_network_order;
744
745 switch(rules[i].type)
746 {
747 case KEY_EXCHANGE_DATA:
748 header_length = KE_PAYLOAD_HEADER_LENGTH;
749 break;
750 case NOTIFICATION_DATA:
751 header_length = NOTIFY_PAYLOAD_HEADER_LENGTH + this->last_spi_size ;
752 break;
753 case NONCE_DATA:
754 header_length = NONCE_PAYLOAD_HEADER_LENGTH;
755 break;
756 case ID_DATA:
757 header_length = ID_PAYLOAD_HEADER_LENGTH;
758 break;
759 case AUTH_DATA:
760 header_length = AUTH_PAYLOAD_HEADER_LENGTH;
761 break;
762 case CERT_DATA:
763 header_length = CERT_PAYLOAD_HEADER_LENGTH;
764 break;
765 case CERTREQ_DATA:
766 header_length = CERTREQ_PAYLOAD_HEADER_LENGTH;
767 break;
768 case SPIS:
769 header_length = DELETE_PAYLOAD_HEADER_LENGTH;
770 break;
771 case VID_DATA:
772 header_length = VENDOR_ID_PAYLOAD_HEADER_LENGTH;
773 break;
774 case CONFIGURATION_ATTRIBUTE_VALUE:
775 header_length = CONFIGURATION_ATTRIBUTE_HEADER_LENGTH;
776 break;
777 case EAP_MESSAGE:
778 header_length = EAP_PAYLOAD_HEADER_LENGTH;
779 break;
780 default:
781 break;
782 }
783
784 /* the data value is generated from chunk */
785 this->generate_from_chunk(this,rules[i].offset);
786
787 payload_length_position_offset = this->last_payload_length_position_offset;
788
789
790 /* Length of payload is calculated */
791 length_of_payload = header_length + ((chunk_t *)(this->data_struct + rules[i].offset))->len;
792
793 length_in_network_order = htons(length_of_payload);
794 this->write_bytes_to_buffer_at_offset(this,&length_in_network_order,sizeof(u_int16_t),payload_length_position_offset);
795 break;
796 }
797 case PROPOSALS:
798 {
799 /* before iterative generate the transforms, store the current payload length position */
800 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
801 /* Length of SA_PAYLOAD is calculated */
802 u_int16_t length_of_sa_payload = SA_PAYLOAD_HEADER_LENGTH;
803 u_int16_t int16_val;
804 /* proposals are stored in a linked list and so accessed */
805 linked_list_t *proposals = *((linked_list_t **)(this->data_struct + rules[i].offset));
806 iterator_t *iterator;
807 payload_t *current_proposal;
808
809 /* create forward iterator */
810 iterator = proposals->create_iterator(proposals,TRUE);
811 /* every proposal is processed (iterative call )*/
812 while (iterator->iterate(iterator, (void**)&current_proposal))
813 {
814 u_int32_t before_generate_position_offset;
815 u_int32_t after_generate_position_offset;
816
817 before_generate_position_offset = this->get_current_buffer_offset(this);
818 this->public.generate_payload(&(this->public),current_proposal);
819 after_generate_position_offset = this->get_current_buffer_offset(this);
820
821 /* increase size of transform */
822 length_of_sa_payload += (after_generate_position_offset - before_generate_position_offset);
823 }
824 iterator->destroy(iterator);
825
826 int16_val = htons(length_of_sa_payload);
827 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
828 break;
829 }
830 case TRANSFORMS:
831 {
832 /* before iterative generate the transforms, store the current length position */
833 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
834 u_int16_t length_of_proposal = PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH + this->last_spi_size;
835 u_int16_t int16_val;
836 linked_list_t *transforms = *((linked_list_t **)(this->data_struct + rules[i].offset));
837 iterator_t *iterator;
838 payload_t *current_transform;
839
840 /* create forward iterator */
841 iterator = transforms->create_iterator(transforms,TRUE);
842 while (iterator->iterate(iterator, (void**)&current_transform))
843 {
844 u_int32_t before_generate_position_offset;
845 u_int32_t after_generate_position_offset;
846
847 before_generate_position_offset = this->get_current_buffer_offset(this);
848 this->public.generate_payload(&(this->public),current_transform);
849 after_generate_position_offset = this->get_current_buffer_offset(this);
850
851 /* increase size of transform */
852 length_of_proposal += (after_generate_position_offset - before_generate_position_offset);
853 }
854
855 iterator->destroy(iterator);
856
857 int16_val = htons(length_of_proposal);
858 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
859
860 break;
861 }
862 case TRANSFORM_ATTRIBUTES:
863 {
864 /* before iterative generate the transform attributes, store the current length position */
865 u_int32_t transform_length_position_offset = this->last_payload_length_position_offset;
866 u_int16_t length_of_transform = TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
867 u_int16_t int16_val;
868 linked_list_t *transform_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
869 iterator_t *iterator;
870 payload_t *current_attribute;
871
872 /* create forward iterator */
873 iterator = transform_attributes->create_iterator(transform_attributes,TRUE);
874 while (iterator->iterate(iterator, (void**)&current_attribute))
875 {
876 u_int32_t before_generate_position_offset;
877 u_int32_t after_generate_position_offset;
878
879 before_generate_position_offset = this->get_current_buffer_offset(this);
880 this->public.generate_payload(&(this->public),current_attribute);
881 after_generate_position_offset = this->get_current_buffer_offset(this);
882
883 /* increase size of transform */
884 length_of_transform += (after_generate_position_offset - before_generate_position_offset);
885 }
886
887 iterator->destroy(iterator);
888
889 int16_val = htons(length_of_transform);
890 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),transform_length_position_offset);
891
892 break;
893 }
894 case CONFIGURATION_ATTRIBUTES:
895 {
896 /* before iterative generate the configuration attributes, store the current length position */
897 u_int32_t configurations_length_position_offset = this->last_payload_length_position_offset;
898 u_int16_t length_of_configurations = CP_PAYLOAD_HEADER_LENGTH;
899 u_int16_t int16_val;
900 linked_list_t *configuration_attributes =*((linked_list_t **)(this->data_struct + rules[i].offset));
901 iterator_t *iterator;
902 payload_t *current_attribute;
903
904 /* create forward iterator */
905 iterator = configuration_attributes->create_iterator(configuration_attributes,TRUE);
906 while (iterator->iterate(iterator, (void**)&current_attribute))
907 {
908 u_int32_t before_generate_position_offset;
909 u_int32_t after_generate_position_offset;
910
911 before_generate_position_offset = this->get_current_buffer_offset(this);
912 this->public.generate_payload(&(this->public),current_attribute);
913 after_generate_position_offset = this->get_current_buffer_offset(this);
914
915 /* increase size of transform */
916 length_of_configurations += (after_generate_position_offset - before_generate_position_offset);
917 }
918
919 iterator->destroy(iterator);
920
921 int16_val = htons(length_of_configurations);
922 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),configurations_length_position_offset);
923
924 break;
925 }
926 case ATTRIBUTE_FORMAT:
927 {
928 this->generate_flag(this,rules[i].offset);
929 /* Attribute format is a flag which is stored in context*/
930 this->attribute_format = *((bool *) (this->data_struct + rules[i].offset));
931 break;
932 }
933
934 case ATTRIBUTE_LENGTH_OR_VALUE:
935 {
936 if (this->attribute_format == FALSE)
937 {
938 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
939 /* this field hold the length of the attribute */
940 this->attribute_length = *((u_int16_t *)(this->data_struct + rules[i].offset));
941 }
942 else
943 {
944 this->generate_u_int_type(this,U_INT_16,rules[i].offset);
945 }
946 break;
947 }
948 case ATTRIBUTE_VALUE:
949 {
950 if (this->attribute_format == FALSE)
951 {
952 DBG2(SIG_DBG_ENC, "attribute value has not fixed size");
953 /* the attribute value is generated */
954 this->generate_from_chunk(this,rules[i].offset);
955 }
956 break;
957 }
958 case TRAFFIC_SELECTORS:
959 {
960 /* before iterative generate the traffic_selectors, store the current payload length position */
961 u_int32_t payload_length_position_offset = this->last_payload_length_position_offset;
962 /* Length of SA_PAYLOAD is calculated */
963 u_int16_t length_of_ts_payload = TS_PAYLOAD_HEADER_LENGTH;
964 u_int16_t int16_val;
965 /* traffic selectors are stored in a linked list and so accessed */
966 linked_list_t *traffic_selectors = *((linked_list_t **)(this->data_struct + rules[i].offset));
967 iterator_t *iterator;
968 payload_t *current_traffic_selector_substructure;
969
970 /* create forward iterator */
971 iterator = traffic_selectors->create_iterator(traffic_selectors,TRUE);
972 /* every proposal is processed (iterative call )*/
973 while (iterator->iterate(iterator, (void **)&current_traffic_selector_substructure))
974 {
975 u_int32_t before_generate_position_offset;
976 u_int32_t after_generate_position_offset;
977
978 before_generate_position_offset = this->get_current_buffer_offset(this);
979 this->public.generate_payload(&(this->public),current_traffic_selector_substructure);
980 after_generate_position_offset = this->get_current_buffer_offset(this);
981
982 /* increase size of transform */
983 length_of_ts_payload += (after_generate_position_offset - before_generate_position_offset);
984 }
985 iterator->destroy(iterator);
986
987 int16_val = htons(length_of_ts_payload);
988 this->write_bytes_to_buffer_at_offset(this,&int16_val,sizeof(u_int16_t),payload_length_position_offset);
989 break;
990 }
991
992 case ENCRYPTED_DATA:
993 {
994 this->generate_from_chunk(this, rules[i].offset);
995 break;
996 }
997 default:
998 DBG1(SIG_DBG_ENC, "field type %N is not supported",
999 encoding_type_names, rules[i].type);
1000 return;
1001 }
1002 }
1003 DBG2(SIG_DBG_ENC, "generating %N payload finished",
1004 payload_type_names, payload_type);
1005 DBG3(SIG_DBG_ENC, "generated data for this payload %b",
1006 payload_start, this->out_position-payload_start);
1007 }
1008
1009 /**
1010 * Implementation of generator_t.destroy.
1011 */
1012 static status_t destroy(private_generator_t *this)
1013 {
1014 free(this->buffer);
1015 free(this);
1016 return SUCCESS;
1017 }
1018
1019 /*
1020 * Described in header
1021 */
1022 generator_t *generator_create()
1023 {
1024 private_generator_t *this;
1025
1026 this = malloc_thing(private_generator_t);
1027
1028 /* initiate public functions */
1029 this->public.generate_payload = (void(*)(generator_t*, payload_t *)) generate_payload;
1030 this->public.destroy = (void(*)(generator_t*)) destroy;
1031 this->public.write_to_chunk = (void (*) (generator_t *,chunk_t *)) write_to_chunk;
1032
1033
1034 /* initiate private functions */
1035 this->get_current_buffer_size = get_current_buffer_size;
1036 this->get_current_buffer_space = get_current_buffer_space;
1037 this->get_current_data_length = get_current_data_length;
1038 this->get_current_buffer_offset = get_current_buffer_offset;
1039 this->generate_u_int_type = generate_u_int_type;
1040 this->generate_reserved_field = generate_reserved_field;
1041 this->generate_flag = generate_flag;
1042 this->generate_from_chunk = generate_from_chunk;
1043 this->make_space_available = make_space_available;
1044 this->write_bytes_to_buffer = write_bytes_to_buffer;
1045 this->write_bytes_to_buffer_at_offset = write_bytes_to_buffer_at_offset;
1046
1047
1048 /* allocate memory for buffer */
1049 this->buffer = malloc(GENERATOR_DATA_BUFFER_SIZE);
1050
1051 /* initiate private variables */
1052 this->out_position = this->buffer;
1053 this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE;
1054 this->data_struct = NULL;
1055 this->current_bit = 0;
1056 this->last_payload_length_position_offset = 0;
1057 this->header_length_position_offset = 0;
1058
1059 return &(this->public);
1060 }