code of message_t cleaned and added more logs
[strongswan.git] / Source / charon / encoding / parser.c
1 /**
2 * @file parser.c
3 *
4 * @brief Implementation of parser_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
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>.
16 *
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
20 * for more details.
21 */
22
23 #include <stdlib.h>
24 #include <arpa/inet.h>
25
26 #include "parser.h"
27
28 #include <types.h>
29 #include <definitions.h>
30 #include <daemon.h>
31 #include <utils/allocator.h>
32 #include <utils/logger.h>
33 #include <utils/linked_list.h>
34 #include <encoding/payloads/encodings.h>
35 #include <encoding/payloads/payload.h>
36 #include <encoding/payloads/sa_payload.h>
37 #include <encoding/payloads/proposal_substructure.h>
38 #include <encoding/payloads/transform_substructure.h>
39 #include <encoding/payloads/transform_attribute.h>
40 #include <encoding/payloads/ke_payload.h>
41 #include <encoding/payloads/nonce_payload.h>
42 #include <encoding/payloads/id_payload.h>
43 #include <encoding/payloads/notify_payload.h>
44 #include <encoding/payloads/encryption_payload.h>
45 #include <encoding/payloads/auth_payload.h>
46 #include <encoding/payloads/ts_payload.h>
47
48
49 typedef struct private_parser_t private_parser_t;
50
51 /**
52 * Private data stored in a context.
53 *
54 * Contains pointers and counters to store current state.
55 */
56 struct private_parser_t {
57 /**
58 * Public members, see parser_t.
59 */
60 parser_t public;
61
62 /**
63 * @brief Parse a 4-Bit unsigned integer from the current parsing position.
64 *
65 * @param this parser_t object
66 * @param rule_number number of current rule
67 * @param[out] output_pos pointer where to write the parsed result
68 * @return
69 * - SUCCESS or
70 * - PARSE_ERROR when not successful
71 */
72 status_t (*parse_uint4) (private_parser_t *this, int rule_number, u_int8_t *output_pos);
73
74 /**
75 * @brief Parse a 8-Bit unsigned integer from the current parsing position.
76 *
77 * @param this parser_t object
78 * @param rule_number number of current rule
79 * @param[out] output_pos pointer where to write the parsed result
80 * @return
81 * - SUCCESS or
82 * - PARSE_ERROR when not successful
83 */
84 status_t (*parse_uint8) (private_parser_t *this, int rule_number, u_int8_t *output_pos);
85
86 /**
87 * @brief Parse a 15-Bit unsigned integer from the current parsing position.
88 *
89 * This is a special case used for ATTRIBUTE_TYPE.
90 * Big-/Little-endian conversion is done here.
91 *
92 * @param this parser_t object
93 * @param rule_number number of current rule
94 * @param[out] output_pos pointer where to write the parsed result
95 * @return
96 * - SUCCESS or
97 * - PARSE_ERROR when not successful
98 */
99 status_t (*parse_uint15) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
100
101 /**
102 * @brief Parse a 16-Bit unsigned integer from the current parsing position.
103 *
104 * Big-/Little-endian conversion is done here.
105 *
106 * @param this parser_t object
107 * @param rule_number number of current rule
108 * @param[out] output_pos pointer where to write the parsed result
109 * @return
110 * - SUCCESS or
111 * - PARSE_ERROR when not successful
112 */
113 status_t (*parse_uint16) (private_parser_t *this, int rule_number, u_int16_t *output_pos);
114
115 /**
116 * @brief Parse a 32-Bit unsigned integer from the current parsing position.
117 *
118 * Big-/Little-endian conversion is done here.
119 *
120 * @param this parser_t object
121 * @param rule_number number of current rule
122 * @param[out] output_pos pointer where to write the parsed result
123 * @return
124 * - SUCCESS or
125 * - PARSE_ERROR when not successful
126 */
127 status_t (*parse_uint32) (private_parser_t *this, int rule_number, u_int32_t *output_pos);
128
129 /**
130 * @brief Parse a 64-Bit unsigned integer from the current parsing position.
131 *
132 * @todo add support for big-endian machines.
133 *
134 * @param this parser_t object
135 * @param rule_number number of current rule
136 * @param[out] output_pos pointer where to write the parsed result
137 * @return
138 * - SUCCESS or
139 * - PARSE_ERROR when not successful
140 */
141 status_t (*parse_uint64) (private_parser_t *this, int rule_number, u_int64_t *output_pos);
142
143 /**
144 * @brief Parse a given amount of bytes and writes them to a specific location
145 *
146 * @param this parser_t object
147 * @param rule_number number of current rule
148 * @param[out] output_pos pointer where to write the parsed result
149 * @param bytes number of bytes to parse
150 * @return
151 * - SUCCESS or
152 * - PARSE_ERROR when not successful
153 */
154 status_t (*parse_bytes) (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes);
155
156 /**
157 * @brief Parse a single Bit from the current parsing position
158 *
159 * @param this parser_t object
160 * @param rule_number number of current rule
161 * @param[out] output_pos pointer where to write the parsed result
162 * @return
163 * - SUCCESS or
164 * - PARSE_ERROR when not successful
165 */
166 status_t (*parse_bit) (private_parser_t *this, int rule_number, bool *output_pos);
167
168 /**
169 * @brief Parse substructures in a list
170 *
171 * This function calls the parser recursivly to parse contained substructures
172 * in a linked_list_t. The list must already be created. Payload defines
173 * the type of the substructures. parsing is continued until the specified length
174 * is completely parsed.
175 *
176 * @param this parser_t object
177 * @param rule_number number of current rule
178 * @param[out] output_pos pointer of a linked_list where substructures are added
179 * @param payload_type type of the contained substructures to parse
180 * @param length number of bytes to parse in this list
181 * @return
182 * - SUCCESS or
183 * - PARSE_ERROR when not successful
184 */
185 status_t (*parse_list) (private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_ype, size_t length);
186
187 /**
188 * @brief Parse data from current parsing position in a chunk.
189 *
190 * This function clones length number of bytes to output_pos, without
191 * modifiyng them. Space will be allocated and must be freed by caller.
192 *
193 * @param this parser_t object
194 * @param rule_number number of current rule
195 * @param[out] output_pos pointer of a chunk which will point to the allocated data
196 * @param length number of bytes to clone
197 * @return
198 * - SUCCESS or
199 * - PARSE_ERROR when not successful
200 */
201 status_t (*parse_chunk) (private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length);
202
203 /**
204 * Current bit for reading in input data.
205 */
206 u_int8_t bit_pos;
207
208 /**
209 * Current byte for reading in input data.
210 */
211 u_int8_t *byte_pos;
212
213 /**
214 * Input data to parse.
215 */
216 u_int8_t *input;
217
218 /**
219 * Roof of input, used for length-checking.
220 */
221 u_int8_t *input_roof;
222
223 /**
224 * Set of encoding rules for this parsing session.
225 */
226 encoding_rule_t *rules;
227
228 /**
229 * Assigned logger_t object.
230 */
231 logger_t *logger;
232 };
233
234 /**
235 * Implementation of private_parser_t.parse_uint4.
236 */
237 static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *output_pos)
238 {
239 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
240 {
241 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
242 rule_number, mapping_find(encoding_type_m,
243 this->rules[rule_number].type));
244 return PARSE_ERROR;
245 }
246 switch (this->bit_pos)
247 {
248 case 0:
249 /* caller interested in result ? */
250 if (output_pos != NULL)
251 {
252 *output_pos = *(this->byte_pos) >> 4;
253 }
254 this->bit_pos = 4;
255 break;
256 case 4:
257 /* caller interested in result ? */
258 if (output_pos != NULL)
259 {
260 *output_pos = *(this->byte_pos) & 0x0F;
261 }
262 this->bit_pos = 0;
263 this->byte_pos++;
264 break;
265 default:
266 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
267 rule_number, mapping_find(encoding_type_m,
268 this->rules[rule_number].type), this->bit_pos);
269 return PARSE_ERROR;
270 }
271
272 if (output_pos != NULL)
273 {
274 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
275 }
276
277 return SUCCESS;
278 }
279
280 /**
281 * Implementation of private_parser_t.parse_uint8.
282 */
283 static status_t parse_uint8(private_parser_t *this, int rule_number, u_int8_t *output_pos)
284 {
285 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
286 {
287 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
288 rule_number, mapping_find(encoding_type_m,
289 this->rules[rule_number].type));
290 return PARSE_ERROR;
291 }
292 if (this->bit_pos)
293 {
294 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
295 rule_number, mapping_find(encoding_type_m,
296 this->rules[rule_number].type), this->bit_pos);
297 return PARSE_ERROR;
298 }
299
300 /* caller interested in result ? */
301 if (output_pos != NULL)
302 {
303 *output_pos = *(this->byte_pos);
304 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
305 }
306 this->byte_pos++;
307
308 return SUCCESS;
309 }
310
311 /**
312 * Implementation of private_parser_t.parse_uint15.
313 */
314 static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t *output_pos)
315 {
316 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
317 {
318 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
319 rule_number, mapping_find(encoding_type_m,
320 this->rules[rule_number].type));
321 return PARSE_ERROR;
322 }
323 if (this->bit_pos != 1)
324 {
325 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
326 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
327 this->bit_pos);
328 return PARSE_ERROR;
329 }
330 /* caller interested in result ? */
331 if (output_pos != NULL)
332 {
333 *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000;
334 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
335 }
336 this->byte_pos += 2;
337 this->bit_pos = 0;
338
339 return SUCCESS;
340 }
341
342 /**
343 * Implementation of private_parser_t.parse_uint16.
344 */
345 static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t *output_pos)
346 {
347 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
348 {
349 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
350 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
351 return PARSE_ERROR;
352 }
353 if (this->bit_pos)
354 {
355 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
356 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
357 this->bit_pos);
358 return PARSE_ERROR;
359 }
360 /* caller interested in result ? */
361 if (output_pos != NULL)
362 {
363 *output_pos = ntohs(*((u_int16_t*)this->byte_pos));
364
365 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
366 }
367 this->byte_pos += 2;
368
369 return SUCCESS;
370 }
371 /**
372 * Implementation of private_parser_t.parse_uint32.
373 */
374 static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t *output_pos)
375 {
376 if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
377 {
378 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
379 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
380 return PARSE_ERROR;
381 }
382 if (this->bit_pos)
383 {
384 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
385 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
386 this->bit_pos);
387 return PARSE_ERROR;
388 }
389 /* caller interested in result ? */
390 if (output_pos != NULL)
391 {
392 *output_pos = ntohl(*((u_int32_t*)this->byte_pos));
393
394 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
395 }
396 this->byte_pos += 4;
397
398 return SUCCESS;
399 }
400
401 /**
402 * Implementation of private_parser_t.parse_uint64.
403 */
404 static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t *output_pos)
405 {
406 if (this->byte_pos + sizeof(u_int64_t) > this->input_roof)
407 {
408 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
409 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
410 return PARSE_ERROR;
411 }
412 if (this->bit_pos)
413 {
414 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
415 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
416 this->bit_pos);
417 return PARSE_ERROR;
418 }
419 /* caller interested in result ? */
420 if (output_pos != NULL)
421 {
422 /* assuming little endian host order */
423 *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos));
424 *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1));
425
426 this->logger->log_bytes(this->logger, RAW|MOST, " =>", (void*)output_pos, 8);
427 }
428 this->byte_pos += 8;
429
430 return SUCCESS;
431 }
432
433 /**
434 * Implementation of private_parser_t.parse_bytes.
435 */
436 static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes)
437 {
438 if (this->byte_pos + bytes > this->input_roof)
439 {
440 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
441 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
442 return PARSE_ERROR;
443 }
444 if (this->bit_pos)
445 {
446 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
447 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type),
448 this->bit_pos);
449 return PARSE_ERROR;
450 }
451
452 /* caller interested in result ? */
453 if (output_pos != NULL)
454 {
455 memcpy(output_pos,this->byte_pos,bytes);
456
457 this->logger->log_bytes(this->logger, RAW|MOST, " =>", (void*)output_pos, bytes);
458 }
459 this->byte_pos += bytes;
460
461 return SUCCESS;
462 }
463
464 /**
465 * Implementation of private_parser_t.parse_bit.
466 */
467 static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_pos)
468 {
469 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
470 {
471 this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s",
472 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
473 return PARSE_ERROR;
474 }
475 /* caller interested in result ? */
476 if (output_pos != NULL)
477 {
478 u_int8_t mask;
479 mask = 0x01 << (7 - this->bit_pos);
480 *output_pos = *this->byte_pos & mask;
481
482 if (*output_pos)
483 {
484 /* set to a "clean", comparable true */
485 *output_pos = TRUE;
486 }
487
488 this->logger->log(this->logger, RAW|MOST, " => %d", *output_pos);
489 }
490 this->bit_pos = (this->bit_pos + 1) % 8;
491 if (this->bit_pos == 0)
492 {
493 this->byte_pos++;
494 }
495
496 return SUCCESS;
497 }
498
499 /**
500 * Implementation of private_parser_t.parse_list.
501 */
502 static status_t parse_list(private_parser_t *this, int rule_number, linked_list_t **output_pos, payload_type_t payload_type, size_t length)
503 {
504 linked_list_t * list = *output_pos;
505
506 if (length < 0)
507 {
508 this->logger->log(this->logger, ERROR, " invalid length for rule %d %s",
509 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
510 return PARSE_ERROR;
511 }
512
513 if (this->bit_pos)
514 {
515 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
516 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos);
517 return PARSE_ERROR;
518 }
519
520 while (length > 0)
521 {
522 u_int8_t *pos_before = this->byte_pos;
523 payload_t *payload;
524 status_t status;
525 this->logger->log(this->logger, CONTROL|MORE, " %d bytes left, parsing recursivly %s",
526 length, mapping_find(payload_type_m, payload_type));
527 status = this->public.parse_payload((parser_t*)this, payload_type, &payload);
528 if (status != SUCCESS)
529 {
530 this->logger->log(this->logger, ERROR, " parsing of a %s substructure failed",
531 mapping_find(payload_type_m, payload_type));
532 return status;
533 }
534 list->insert_last(list, payload);
535 length -= this->byte_pos - pos_before;
536 }
537 *output_pos = list;
538 return SUCCESS;
539 }
540
541 /**
542 * Implementation of private_parser_t.parse_chunk.
543 */
544 static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length)
545 {
546 if (this->byte_pos + length > this->input_roof)
547 {
548 this->logger->log(this->logger, ERROR, " not enough input (%d bytes) to parse rule %d %s",
549 length, rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type));
550 return PARSE_ERROR;
551 }
552 if (this->bit_pos)
553 {
554 this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d",
555 rule_number, mapping_find(encoding_type_m, this->rules[rule_number].type), this->bit_pos);
556 return PARSE_ERROR;
557 }
558 if (output_pos != NULL)
559 {
560 output_pos->len = length;
561 output_pos->ptr = allocator_alloc(length);
562 memcpy(output_pos->ptr, this->byte_pos, length);
563 }
564 this->byte_pos += length;
565 this->logger->log_bytes(this->logger, RAW|MOST, " =>", (void*)output_pos->ptr, length);
566
567 return SUCCESS;
568 }
569
570 /**
571 * Implementation of parser_t.parse_payload.
572 */
573 static status_t parse_payload(private_parser_t *this, payload_type_t payload_type, payload_t **payload)
574 {
575 payload_t *pld;
576 void *output;
577 size_t rule_count, payload_length, spi_size, attribute_length;
578 u_int16_t ts_type;
579 bool attribute_format;
580 int rule_number;
581 encoding_rule_t *rule;
582
583 this->logger->log(this->logger, CONTROL, "parsing %s payload, %d bytes left",
584 mapping_find(payload_type_m, payload_type),
585 this->input_roof-this->byte_pos);
586
587 this->logger->log_bytes(this->logger, RAW, "parsing payload from", this->byte_pos,
588 this->input_roof-this->byte_pos);
589
590 /* ok, do the parsing */
591 pld = payload_create(payload_type);
592 if (pld == NULL)
593 {
594 this->logger->log(this->logger, ERROR, " payload %s not supported", mapping_find(payload_type_m, payload_type));
595 return NOT_SUPPORTED;
596 }
597 /* base pointer for output, avoids casting in every rule */
598 output = pld;
599
600 pld->get_encoding_rules(pld, &(this->rules), &rule_count);
601
602 for (rule_number = 0; rule_number < rule_count; rule_number++)
603 {
604 rule = &(this->rules[rule_number]);
605 this->logger->log(this->logger, CONTROL|MORE, " parsing rule %d %s",
606 rule_number, mapping_find(encoding_type_m, rule->type));
607 switch (rule->type)
608 {
609 case U_INT_4:
610 {
611 if (this->parse_uint4(this, rule_number, output + rule->offset) != SUCCESS)
612 {
613 pld->destroy(pld);
614 return PARSE_ERROR;
615 }
616 break;
617 }
618 case U_INT_8:
619 {
620 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
621 {
622 pld->destroy(pld);
623 return PARSE_ERROR;
624 }
625 break;
626 }
627 case U_INT_16:
628 {
629 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
630 {
631 pld->destroy(pld);
632 return PARSE_ERROR;
633 }
634 break;
635 }
636 case U_INT_32:
637 {
638 if (this->parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
639 {
640 pld->destroy(pld);
641 return PARSE_ERROR;
642 }
643 break;
644 }
645 case U_INT_64:
646 {
647 if (this->parse_uint64(this, rule_number, output + rule->offset) != SUCCESS)
648 {
649 pld->destroy(pld);
650 return PARSE_ERROR;
651 }
652 break;
653 }
654 case IKE_SPI:
655 {
656 if (this->parse_bytes(this, rule_number, output + rule->offset,8) != SUCCESS)
657 {
658 pld->destroy(pld);
659 return PARSE_ERROR;
660 }
661 break;
662 }
663 case RESERVED_BIT:
664 {
665 if (this->parse_bit(this, rule_number, NULL) != SUCCESS)
666 {
667 pld->destroy(pld);
668 return PARSE_ERROR;
669 }
670 break;
671 }
672 case RESERVED_BYTE:
673 {
674 if (this->parse_uint8(this, rule_number, NULL) != SUCCESS)
675 {
676 pld->destroy(pld);
677 return PARSE_ERROR;
678 }
679 break;
680 }
681 case FLAG:
682 {
683 if (this->parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
684 {
685 pld->destroy(pld);
686 return PARSE_ERROR;
687 }
688 break;
689 }
690 case PAYLOAD_LENGTH:
691 {
692 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
693 {
694 pld->destroy(pld);
695 return PARSE_ERROR;
696 }
697 payload_length = *(u_int16_t*)(output + rule->offset);
698 break;
699 }
700 case HEADER_LENGTH:
701 {
702 if (this->parse_uint32(this, rule_number, output + rule->offset) != SUCCESS)
703 {
704 pld->destroy(pld);
705 return PARSE_ERROR;
706 }
707 break;
708 }
709 case SPI_SIZE:
710 {
711 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
712 {
713 pld->destroy(pld);
714 return PARSE_ERROR;
715 }
716 spi_size = *(u_int8_t*)(output + rule->offset);
717 break;
718 }
719 case SPI:
720 {
721 if (this->parse_chunk(this, rule_number, output + rule->offset, spi_size) != SUCCESS)
722 {
723 pld->destroy(pld);
724 return PARSE_ERROR;
725 }
726 break;
727 }
728 case PROPOSALS:
729 {
730 size_t proposals_length = payload_length - SA_PAYLOAD_HEADER_LENGTH;
731 if (this->parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, proposals_length) != SUCCESS)
732 {
733 pld->destroy(pld);
734 return PARSE_ERROR;
735 }
736 break;
737 }
738 case TRANSFORMS:
739 {
740 size_t transforms_length = payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH;
741 if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, transforms_length) != SUCCESS)
742 {
743 pld->destroy(pld);
744 return PARSE_ERROR;
745 }
746 break;
747 }
748 case TRANSFORM_ATTRIBUTES:
749 {
750 size_t transform_a_length = payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH;
751 if (this->parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, transform_a_length) != SUCCESS)
752 {
753 pld->destroy(pld);
754 return PARSE_ERROR;
755 }
756 break;
757 }
758 case ATTRIBUTE_FORMAT:
759 {
760 if (this->parse_bit(this, rule_number, output + rule->offset) != SUCCESS)
761 {
762 pld->destroy(pld);
763 return PARSE_ERROR;
764 }
765 attribute_format = *(bool*)(output + rule->offset);
766 break;
767 }
768 case ATTRIBUTE_TYPE:
769 {
770 if (this->parse_uint15(this, rule_number, output + rule->offset) != SUCCESS)
771 {
772 pld->destroy(pld);
773 return PARSE_ERROR;
774 }
775 attribute_format = *(bool*)(output + rule->offset);
776 break;
777 }
778 case ATTRIBUTE_LENGTH_OR_VALUE:
779 {
780 if (this->parse_uint16(this, rule_number, output + rule->offset) != SUCCESS)
781 {
782 pld->destroy(pld);
783 return PARSE_ERROR;
784 }
785 attribute_length = *(u_int16_t*)(output + rule->offset);
786 break;
787 }
788 case ATTRIBUTE_VALUE:
789 {
790 if (attribute_format == FALSE)
791 {
792 if (this->parse_chunk(this, rule_number, output + rule->offset, attribute_length) != SUCCESS)
793 {
794 pld->destroy(pld);
795 return PARSE_ERROR;
796 }
797 }
798 break;
799 }
800 case NONCE_DATA:
801 {
802 size_t nonce_length = payload_length - NONCE_PAYLOAD_HEADER_LENGTH;
803 if (this->parse_chunk(this, rule_number, output + rule->offset, nonce_length) != SUCCESS)
804 {
805 pld->destroy(pld);
806 return PARSE_ERROR;
807 }
808 break;
809 }
810 case ID_DATA:
811 {
812 size_t data_length = payload_length - ID_PAYLOAD_HEADER_LENGTH;
813 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
814 {
815 pld->destroy(pld);
816 return PARSE_ERROR;
817 }
818 break;
819 }
820 case AUTH_DATA:
821 {
822 size_t data_length = payload_length - AUTH_PAYLOAD_HEADER_LENGTH;
823 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
824 {
825 pld->destroy(pld);
826 return PARSE_ERROR;
827 }
828 break;
829 }
830 case KEY_EXCHANGE_DATA:
831 {
832 size_t keydata_length = payload_length - KE_PAYLOAD_HEADER_LENGTH;
833 if (this->parse_chunk(this, rule_number, output + rule->offset, keydata_length) != SUCCESS)
834 {
835 pld->destroy(pld);
836 return PARSE_ERROR;
837 }
838 break;
839 }
840 case NOTIFICATION_DATA:
841 {
842 size_t notify_length = payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size;
843 if (this->parse_chunk(this, rule_number, output + rule->offset, notify_length) != SUCCESS)
844 {
845 pld->destroy(pld);
846 return PARSE_ERROR;
847 }
848 break;
849 }
850 case ENCRYPTED_DATA:
851 {
852 size_t data_length = payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH;
853 if (this->parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS)
854 {
855 pld->destroy(pld);
856 return PARSE_ERROR;
857 }
858 break;
859 }
860 case TS_TYPE:
861 {
862 if (this->parse_uint8(this, rule_number, output + rule->offset) != SUCCESS)
863 {
864 pld->destroy(pld);
865 return PARSE_ERROR;
866 }
867 ts_type = *(u_int8_t*)(output + rule->offset);
868 break;
869 }
870 case ADDRESS:
871 {
872 size_t address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
873 if (this->parse_chunk(this, rule_number, output + rule->offset,address_length) != SUCCESS)
874 {
875 pld->destroy(pld);
876 return PARSE_ERROR;
877 }
878 break;
879 }
880 case TRAFFIC_SELECTORS:
881 {
882 size_t traffic_selectors_length = payload_length - TS_PAYLOAD_HEADER_LENGTH;
883 if (this->parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, traffic_selectors_length) != SUCCESS)
884 {
885 pld->destroy(pld);
886 return PARSE_ERROR;
887 }
888 break;
889 }
890 default:
891 {
892 this->logger->log(this->logger, ERROR, " no rule to parse rule %d %s (%d)", rule_number, mapping_find(encoding_type_m, rule->type), rule->type);
893 pld->destroy(pld);
894 return PARSE_ERROR;
895 }
896 }
897 /* process next rulue */
898 rule++;
899 }
900
901 *payload = pld;
902
903 return SUCCESS;
904 }
905
906 /**
907 * Implementation of parser_t.get_remaining_byte_count.
908 */
909 static int get_remaining_byte_count (private_parser_t *this)
910 {
911 int count = (this->input_roof - this->byte_pos);
912 return count;
913 }
914
915 /**
916 * Implementation of parser_t.reset_context.
917 */
918 static void reset_context (private_parser_t *this)
919 {
920 this->byte_pos = this->input;
921 this->bit_pos = 0;
922 }
923
924 /**
925 * Implementation of parser_t.destroy.
926 */
927 static void destroy(private_parser_t *this)
928 {
929 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
930 allocator_free(this);
931 }
932
933 /*
934 * Described in header.
935 */
936 parser_t *parser_create(chunk_t data)
937 {
938 private_parser_t *this = allocator_alloc_thing(private_parser_t);
939
940 this->logger = charon->logger_manager->create_logger(charon->logger_manager, PARSER, NULL);
941
942 this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload;
943 this->public.reset_context = (void(*)(parser_t*)) reset_context;
944 this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
945 this->public.destroy = (void(*)(parser_t*)) destroy;
946
947
948 this->parse_uint4 = parse_uint4;
949 this->parse_uint8 = parse_uint8;
950 this->parse_uint15 = parse_uint15;
951 this->parse_uint16 = parse_uint16;
952 this->parse_uint32 = parse_uint32;
953 this->parse_uint64 = parse_uint64;
954 this->parse_bytes = parse_bytes;
955 this->parse_bit = parse_bit;
956 this->parse_list = parse_list;
957 this->parse_chunk = parse_chunk;
958
959 this->input = data.ptr;
960 this->byte_pos = data.ptr;
961 this->bit_pos = 0;
962 this->input_roof = data.ptr + data.len;
963
964 return (parser_t*)this;
965 }
966