cleaned up parser code
[strongswan.git] / src / charon / encoding / parser.c
1 /*
2 * Copyright (C) 2005-2009 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include <stdlib.h>
18 #include <arpa/inet.h>
19 #include <string.h>
20
21 #include "parser.h"
22
23 #include <library.h>
24 #include <daemon.h>
25 #include <utils/linked_list.h>
26 #include <encoding/payloads/encodings.h>
27 #include <encoding/payloads/payload.h>
28 #include <encoding/payloads/sa_payload.h>
29 #include <encoding/payloads/proposal_substructure.h>
30 #include <encoding/payloads/transform_substructure.h>
31 #include <encoding/payloads/transform_attribute.h>
32 #include <encoding/payloads/ke_payload.h>
33 #include <encoding/payloads/nonce_payload.h>
34 #include <encoding/payloads/id_payload.h>
35 #include <encoding/payloads/notify_payload.h>
36 #include <encoding/payloads/encryption_payload.h>
37 #include <encoding/payloads/auth_payload.h>
38 #include <encoding/payloads/cert_payload.h>
39 #include <encoding/payloads/certreq_payload.h>
40 #include <encoding/payloads/ts_payload.h>
41 #include <encoding/payloads/delete_payload.h>
42 #include <encoding/payloads/vendor_id_payload.h>
43 #include <encoding/payloads/cp_payload.h>
44 #include <encoding/payloads/configuration_attribute.h>
45 #include <encoding/payloads/eap_payload.h>
46 #include <encoding/payloads/unknown_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 * Current bit for reading in input data.
64 */
65 u_int8_t bit_pos;
66
67 /**
68 * Current byte for reading in input data.
69 */
70 u_int8_t *byte_pos;
71
72 /**
73 * Input data to parse.
74 */
75 u_int8_t *input;
76
77 /**
78 * Roof of input, used for length-checking.
79 */
80 u_int8_t *input_roof;
81
82 /**
83 * Set of encoding rules for this parsing session.
84 */
85 encoding_rule_t *rules;
86 };
87
88 /**
89 * Forward declaration
90 */
91 static status_t parse_payload(private_parser_t *this,
92 payload_type_t payload_type, payload_t **payload);
93
94 /**
95 * Log invalid length error
96 */
97 static bool short_input(private_parser_t *this, int number)
98 {
99 DBG1(DBG_ENC, " not enough input to parse rule %d %N",
100 number, encoding_type_names, this->rules[number].type);
101 return FALSE;
102 }
103
104 /**
105 * Log unaligned rules
106 */
107 static bool bad_bitpos(private_parser_t *this, int number)
108 {
109 DBG1(DBG_ENC, " found rule %d %N on bitpos %d",
110 number, encoding_type_names, this->rules[number].type, this->bit_pos);
111 return FALSE;
112 }
113
114 /**
115 * Parse a 4-Bit unsigned integer from the current parsing position.
116 */
117 static bool parse_uint4(private_parser_t *this, int rule_number,
118 u_int8_t *output_pos)
119 {
120 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
121 {
122 return short_input(this, rule_number);
123 }
124 switch (this->bit_pos)
125 {
126 case 0:
127 if (output_pos)
128 {
129 *output_pos = *(this->byte_pos) >> 4;
130 }
131 this->bit_pos = 4;
132 break;
133 case 4:
134 if (output_pos)
135 {
136 *output_pos = *(this->byte_pos) & 0x0F;
137 }
138 this->bit_pos = 0;
139 this->byte_pos++;
140 break;
141 default:
142 return bad_bitpos(this, rule_number);
143 }
144 if (output_pos)
145 {
146 DBG3(DBG_ENC, " => %d", *output_pos);
147 }
148 return TRUE;
149 }
150
151 /**
152 * Parse a 8-Bit unsigned integer from the current parsing position.
153 */
154 static bool parse_uint8(private_parser_t *this, int rule_number,
155 u_int8_t *output_pos)
156 {
157 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
158 {
159 return short_input(this, rule_number);
160 }
161 if (this->bit_pos)
162 {
163 return bad_bitpos(this, rule_number);
164 }
165 if (output_pos)
166 {
167 *output_pos = *(this->byte_pos);
168 DBG3(DBG_ENC, " => %d", *output_pos);
169 }
170 this->byte_pos++;
171 return TRUE;
172 }
173
174 /**
175 * Parse a 15-Bit unsigned integer from the current parsing position.
176 */
177 static bool parse_uint15(private_parser_t *this, int rule_number,
178 u_int16_t *output_pos)
179 {
180 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
181 {
182 return short_input(this, rule_number);
183 }
184 if (this->bit_pos != 1)
185 {
186 return bad_bitpos(this, rule_number);
187 }
188 if (output_pos)
189 {
190 *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000;
191 DBG3(DBG_ENC, " => %d", *output_pos);
192 }
193 this->byte_pos += 2;
194 this->bit_pos = 0;
195 return TRUE;
196 }
197
198 /**
199 * Parse a 16-Bit unsigned integer from the current parsing position.
200 */
201 static bool parse_uint16(private_parser_t *this, int rule_number,
202 u_int16_t *output_pos)
203 {
204 if (this->byte_pos + sizeof(u_int16_t) > this->input_roof)
205 {
206 return short_input(this, rule_number);
207 }
208 if (this->bit_pos)
209 {
210 return bad_bitpos(this, rule_number);
211 }
212 if (output_pos)
213 {
214 *output_pos = ntohs(*((u_int16_t*)this->byte_pos));
215 DBG3(DBG_ENC, " => %d", *output_pos);
216 }
217 this->byte_pos += 2;
218 return TRUE;
219 }
220 /**
221 * Parse a 32-Bit unsigned integer from the current parsing position.
222 */
223 static bool parse_uint32(private_parser_t *this, int rule_number,
224 u_int32_t *output_pos)
225 {
226 if (this->byte_pos + sizeof(u_int32_t) > this->input_roof)
227 {
228 return short_input(this, rule_number);
229 }
230 if (this->bit_pos)
231 {
232 return bad_bitpos(this, rule_number);
233 }
234 if (output_pos)
235 {
236 *output_pos = ntohl(*((u_int32_t*)this->byte_pos));
237 DBG3(DBG_ENC, " => %d", *output_pos);
238 }
239 this->byte_pos += 4;
240 return TRUE;
241 }
242
243 /**
244 * Parse a 64-Bit unsigned integer from the current parsing position.
245 */
246 static bool parse_uint64(private_parser_t *this, int rule_number,
247 u_int64_t *output_pos)
248 {
249 if (this->byte_pos + sizeof(u_int64_t) > this->input_roof)
250 {
251 return short_input(this, rule_number);
252 }
253 if (this->bit_pos)
254 {
255 return bad_bitpos(this, rule_number);
256 }
257 if (output_pos)
258 {
259 /* assuming little endian host order */
260 *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos));
261 *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1));
262 DBG3(DBG_ENC, " => %b", output_pos, sizeof(u_int64_t));
263 }
264 this->byte_pos += 8;
265 return TRUE;
266 }
267
268 /**
269 * Parse a given amount of bytes and writes them to a specific location
270 */
271 static bool parse_bytes (private_parser_t *this, int rule_number,
272 u_int8_t *output_pos, size_t bytes)
273 {
274 if (this->byte_pos + bytes > this->input_roof)
275 {
276 return short_input(this, rule_number);
277 }
278 if (this->bit_pos)
279 {
280 return bad_bitpos(this, rule_number);
281 }
282 if (output_pos)
283 {
284 memcpy(output_pos,this->byte_pos,bytes);
285 DBG3(DBG_ENC, " => %b", output_pos, bytes);
286 }
287 this->byte_pos += bytes;
288 return TRUE;
289 }
290
291 /**
292 * Parse a single Bit from the current parsing position
293 */
294 static bool parse_bit(private_parser_t *this, int rule_number,
295 bool *output_pos)
296 {
297 if (this->byte_pos + sizeof(u_int8_t) > this->input_roof)
298 {
299 return short_input(this, rule_number);
300 }
301 if (output_pos)
302 {
303 u_int8_t mask;
304 mask = 0x01 << (7 - this->bit_pos);
305 *output_pos = *this->byte_pos & mask;
306
307 if (*output_pos)
308 { /* set to a "clean", comparable true */
309 *output_pos = TRUE;
310 }
311 DBG3(DBG_ENC, " => %d", *output_pos);
312 }
313 this->bit_pos = (this->bit_pos + 1) % 8;
314 if (this->bit_pos == 0)
315 {
316 this->byte_pos++;
317 }
318 return TRUE;
319 }
320
321 /**
322 * Parse substructures in a list.
323 */
324 static bool parse_list(private_parser_t *this, int rule_number,
325 linked_list_t **output_pos, payload_type_t payload_type, size_t length)
326 {
327 linked_list_t *list = *output_pos;
328
329 if (length < 0)
330 {
331 return short_input(this, rule_number);
332 }
333 if (this->bit_pos)
334 {
335 return bad_bitpos(this, rule_number);
336 }
337 while (length > 0)
338 {
339 u_int8_t *pos_before = this->byte_pos;
340 payload_t *payload;
341
342 DBG2(DBG_ENC, " %d bytes left, parsing recursively %N",
343 length, payload_type_names, payload_type);
344
345 if (parse_payload(this, payload_type, &payload) != SUCCESS)
346 {
347 DBG1(DBG_ENC, " parsing of a %N substructure failed",
348 payload_type_names, payload_type);
349 return FALSE;
350 }
351 list->insert_last(list, payload);
352 length -= this->byte_pos - pos_before;
353 }
354 *output_pos = list;
355 return TRUE;
356 }
357
358 /**
359 * Parse data from current parsing position in a chunk.
360 */
361 static bool parse_chunk(private_parser_t *this, int rule_number,
362 chunk_t *output_pos, size_t length)
363 {
364 if (this->byte_pos + length > this->input_roof)
365 {
366 return short_input(this, rule_number);
367 }
368 if (this->bit_pos)
369 {
370 return bad_bitpos(this, rule_number);
371 }
372 if (output_pos)
373 {
374 *output_pos = chunk_alloc(length);
375 memcpy(output_pos->ptr, this->byte_pos, length);
376 DBG3(DBG_ENC, " => %b", output_pos->ptr, length);
377 }
378 this->byte_pos += length;
379 return TRUE;
380 }
381
382 /**
383 * Implementation of parser_t.parse_payload.
384 */
385 static status_t parse_payload(private_parser_t *this,
386 payload_type_t payload_type, payload_t **payload)
387 {
388 payload_t *pld;
389 void *output;
390 size_t rule_count, payload_length = 0, spi_size = 0, attribute_length = 0;
391 u_int16_t ts_type = 0;
392 bool attribute_format = FALSE;
393 int rule_number;
394 encoding_rule_t *rule;
395
396 /* create instance of the payload to parse */
397 pld = payload_create(payload_type);
398
399 DBG2(DBG_ENC, "parsing %N payload, %d bytes left",
400 payload_type_names, payload_type, this->input_roof - this->byte_pos);
401
402 DBG3(DBG_ENC, "parsing payload from %b",
403 this->byte_pos, this->input_roof-this->byte_pos);
404
405 if (pld->get_type(pld) == UNKNOWN_PAYLOAD)
406 {
407 DBG1(DBG_ENC, " payload type %d is unknown, handling as %N",
408 payload_type, payload_type_names, UNKNOWN_PAYLOAD);
409 }
410
411 /* base pointer for output, avoids casting in every rule */
412 output = pld;
413
414 /* parse the payload with its own rulse */
415 pld->get_encoding_rules(pld, &(this->rules), &rule_count);
416 for (rule_number = 0; rule_number < rule_count; rule_number++)
417 {
418 rule = &(this->rules[rule_number]);
419 DBG2(DBG_ENC, " parsing rule %d %N",
420 rule_number, encoding_type_names, rule->type);
421 switch (rule->type)
422 {
423 case U_INT_4:
424 {
425 if (!parse_uint4(this, rule_number, output + rule->offset))
426 {
427 pld->destroy(pld);
428 return PARSE_ERROR;
429 }
430 break;
431 }
432 case U_INT_8:
433 {
434 if (!parse_uint8(this, rule_number, output + rule->offset))
435 {
436 pld->destroy(pld);
437 return PARSE_ERROR;
438 }
439 break;
440 }
441 case U_INT_16:
442 {
443 if (!parse_uint16(this, rule_number, output + rule->offset))
444 {
445 pld->destroy(pld);
446 return PARSE_ERROR;
447 }
448 break;
449 }
450 case U_INT_32:
451 {
452 if (!parse_uint32(this, rule_number, output + rule->offset))
453 {
454 pld->destroy(pld);
455 return PARSE_ERROR;
456 }
457 break;
458 }
459 case U_INT_64:
460 {
461 if (!parse_uint64(this, rule_number, output + rule->offset))
462 {
463 pld->destroy(pld);
464 return PARSE_ERROR;
465 }
466 break;
467 }
468 case IKE_SPI:
469 {
470 if (!parse_bytes(this, rule_number, output + rule->offset, 8))
471 {
472 pld->destroy(pld);
473 return PARSE_ERROR;
474 }
475 break;
476 }
477 case RESERVED_BIT:
478 {
479 if (!parse_bit(this, rule_number, NULL))
480 {
481 pld->destroy(pld);
482 return PARSE_ERROR;
483 }
484 break;
485 }
486 case RESERVED_BYTE:
487 {
488 if (!parse_uint8(this, rule_number, NULL))
489 {
490 pld->destroy(pld);
491 return PARSE_ERROR;
492 }
493 break;
494 }
495 case FLAG:
496 {
497 if (!parse_bit(this, rule_number, output + rule->offset))
498 {
499 pld->destroy(pld);
500 return PARSE_ERROR;
501 }
502 break;
503 }
504 case PAYLOAD_LENGTH:
505 {
506 if (!parse_uint16(this, rule_number, output + rule->offset))
507 {
508 pld->destroy(pld);
509 return PARSE_ERROR;
510 }
511 payload_length = *(u_int16_t*)(output + rule->offset);
512 if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH)
513 {
514 pld->destroy(pld);
515 return PARSE_ERROR;
516 }
517 break;
518 }
519 case HEADER_LENGTH:
520 {
521 if (!parse_uint32(this, rule_number, output + rule->offset))
522 {
523 pld->destroy(pld);
524 return PARSE_ERROR;
525 }
526 break;
527 }
528 case SPI_SIZE:
529 {
530 if (!parse_uint8(this, rule_number, output + rule->offset))
531 {
532 pld->destroy(pld);
533 return PARSE_ERROR;
534 }
535 spi_size = *(u_int8_t*)(output + rule->offset);
536 break;
537 }
538 case SPI:
539 {
540 if (!parse_chunk(this, rule_number, output + rule->offset,
541 spi_size))
542 {
543 pld->destroy(pld);
544 return PARSE_ERROR;
545 }
546 break;
547 }
548 case PROPOSALS:
549 {
550 if (payload_length < SA_PAYLOAD_HEADER_LENGTH ||
551 !parse_list(this, rule_number, output + rule->offset,
552 PROPOSAL_SUBSTRUCTURE,
553 payload_length - SA_PAYLOAD_HEADER_LENGTH))
554 {
555 pld->destroy(pld);
556 return PARSE_ERROR;
557 }
558 break;
559 }
560 case TRANSFORMS:
561 {
562 if (payload_length <
563 spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH ||
564 !parse_list(this, rule_number, output + rule->offset,
565 TRANSFORM_SUBSTRUCTURE, payload_length - spi_size -
566 PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH))
567 {
568 pld->destroy(pld);
569 return PARSE_ERROR;
570 }
571 break;
572 }
573 case TRANSFORM_ATTRIBUTES:
574 {
575 if (payload_length < TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH ||
576 !parse_list(this, rule_number, output + rule->offset,
577 TRANSFORM_ATTRIBUTE,
578 payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH))
579 {
580 pld->destroy(pld);
581 return PARSE_ERROR;
582 }
583 break;
584 }
585 case CONFIGURATION_ATTRIBUTES:
586 {
587 if (payload_length < CP_PAYLOAD_HEADER_LENGTH ||
588 !parse_list(this, rule_number, output + rule->offset,
589 CONFIGURATION_ATTRIBUTE,
590 payload_length - CP_PAYLOAD_HEADER_LENGTH))
591 {
592 pld->destroy(pld);
593 return PARSE_ERROR;
594 }
595 break;
596 }
597 case ATTRIBUTE_FORMAT:
598 {
599 if (!parse_bit(this, rule_number, output + rule->offset))
600 {
601 pld->destroy(pld);
602 return PARSE_ERROR;
603 }
604 attribute_format = *(bool*)(output + rule->offset);
605 break;
606 }
607 case ATTRIBUTE_TYPE:
608 {
609 if (!parse_uint15(this, rule_number, output + rule->offset))
610 {
611 pld->destroy(pld);
612 return PARSE_ERROR;
613 }
614 attribute_format = *(bool*)(output + rule->offset);
615 break;
616 }
617 case CONFIGURATION_ATTRIBUTE_LENGTH:
618 {
619 if (!parse_uint16(this, rule_number, output + rule->offset))
620 {
621 pld->destroy(pld);
622 return PARSE_ERROR;
623 }
624 attribute_length = *(u_int16_t*)(output + rule->offset);
625 break;
626 }
627 case ATTRIBUTE_LENGTH_OR_VALUE:
628 {
629 if (!parse_uint16(this, rule_number, output + rule->offset))
630 {
631 pld->destroy(pld);
632 return PARSE_ERROR;
633 }
634 attribute_length = *(u_int16_t*)(output + rule->offset);
635 break;
636 }
637 case ATTRIBUTE_VALUE:
638 {
639 if (attribute_format == FALSE &&
640 !parse_chunk(this, rule_number, output + rule->offset,
641 attribute_length))
642 {
643 pld->destroy(pld);
644 return PARSE_ERROR;
645 }
646 break;
647 }
648 case NONCE_DATA:
649 {
650 if (payload_length < NONCE_PAYLOAD_HEADER_LENGTH ||
651 !parse_chunk(this, rule_number, output + rule->offset,
652 payload_length - NONCE_PAYLOAD_HEADER_LENGTH))
653 {
654 pld->destroy(pld);
655 return PARSE_ERROR;
656 }
657 break;
658 }
659 case ID_DATA:
660 {
661 if (payload_length < ID_PAYLOAD_HEADER_LENGTH ||
662 !parse_chunk(this, rule_number, output + rule->offset,
663 payload_length - ID_PAYLOAD_HEADER_LENGTH))
664 {
665 pld->destroy(pld);
666 return PARSE_ERROR;
667 }
668 break;
669 }
670 case AUTH_DATA:
671 {
672 if (payload_length < AUTH_PAYLOAD_HEADER_LENGTH ||
673 !parse_chunk(this, rule_number, output + rule->offset,
674 payload_length - AUTH_PAYLOAD_HEADER_LENGTH))
675 {
676 pld->destroy(pld);
677 return PARSE_ERROR;
678 }
679 break;
680 }
681 case CERT_DATA:
682 {
683 if (payload_length < CERT_PAYLOAD_HEADER_LENGTH ||
684 !parse_chunk(this, rule_number, output + rule->offset,
685 payload_length - CERT_PAYLOAD_HEADER_LENGTH))
686 {
687 pld->destroy(pld);
688 return PARSE_ERROR;
689 }
690 break;
691 }
692 case CERTREQ_DATA:
693 {
694 if (payload_length < CERTREQ_PAYLOAD_HEADER_LENGTH ||
695 !parse_chunk(this, rule_number, output + rule->offset,
696 payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH))
697 {
698 pld->destroy(pld);
699 return PARSE_ERROR;
700 }
701 break;
702 }
703 case EAP_DATA:
704 {
705 if (payload_length < EAP_PAYLOAD_HEADER_LENGTH ||
706 !parse_chunk(this, rule_number, output + rule->offset,
707 payload_length - EAP_PAYLOAD_HEADER_LENGTH))
708 {
709 pld->destroy(pld);
710 return PARSE_ERROR;
711 }
712 break;
713 }
714 case SPIS:
715 {
716 if (payload_length < DELETE_PAYLOAD_HEADER_LENGTH ||
717 !parse_chunk(this, rule_number, output + rule->offset,
718 payload_length - DELETE_PAYLOAD_HEADER_LENGTH))
719 {
720 pld->destroy(pld);
721 return PARSE_ERROR;
722 }
723 break;
724 }
725 case VID_DATA:
726 {
727 if (payload_length < VENDOR_ID_PAYLOAD_HEADER_LENGTH ||
728 !parse_chunk(this, rule_number, output + rule->offset,
729 payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH))
730 {
731 pld->destroy(pld);
732 return PARSE_ERROR;
733 }
734 break;
735 }
736 case CONFIGURATION_ATTRIBUTE_VALUE:
737 {
738 if (!parse_chunk(this, rule_number, output + rule->offset,
739 attribute_length))
740 {
741 pld->destroy(pld);
742 return PARSE_ERROR;
743 }
744 break;
745 }
746 case KEY_EXCHANGE_DATA:
747 {
748 if (payload_length < KE_PAYLOAD_HEADER_LENGTH ||
749 !parse_chunk(this, rule_number, output + rule->offset,
750 payload_length - KE_PAYLOAD_HEADER_LENGTH))
751 {
752 pld->destroy(pld);
753 return PARSE_ERROR;
754 }
755 break;
756 }
757 case NOTIFICATION_DATA:
758 {
759 if (payload_length < NOTIFY_PAYLOAD_HEADER_LENGTH + spi_size ||
760 !parse_chunk(this, rule_number, output + rule->offset,
761 payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size))
762 {
763 pld->destroy(pld);
764 return PARSE_ERROR;
765 }
766 break;
767 }
768 case ENCRYPTED_DATA:
769 {
770 if (payload_length < ENCRYPTION_PAYLOAD_HEADER_LENGTH ||
771 !parse_chunk(this, rule_number, output + rule->offset,
772 payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH))
773 {
774 pld->destroy(pld);
775 return PARSE_ERROR;
776 }
777 break;
778 }
779 case TS_TYPE:
780 {
781 if (!parse_uint8(this, rule_number, output + rule->offset))
782 {
783 pld->destroy(pld);
784 return PARSE_ERROR;
785 }
786 ts_type = *(u_int8_t*)(output + rule->offset);
787 break;
788 }
789 case ADDRESS:
790 {
791 size_t address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16;
792
793 if (!parse_chunk(this, rule_number, output + rule->offset,
794 address_length))
795 {
796 pld->destroy(pld);
797 return PARSE_ERROR;
798 }
799 break;
800 }
801 case TRAFFIC_SELECTORS:
802 {
803 if (payload_length < TS_PAYLOAD_HEADER_LENGTH ||
804 !parse_list(this, rule_number, output + rule->offset,
805 TRAFFIC_SELECTOR_SUBSTRUCTURE,
806 payload_length - TS_PAYLOAD_HEADER_LENGTH))
807 {
808 pld->destroy(pld);
809 return PARSE_ERROR;
810 }
811 break;
812 }
813 case UNKNOWN_DATA:
814 {
815 if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH ||
816 !parse_chunk(this, rule_number, output + rule->offset,
817 payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH))
818 {
819 pld->destroy(pld);
820 return PARSE_ERROR;
821 }
822 break;
823 }
824 default:
825 {
826 DBG1(DBG_ENC, " no rule to parse rule %d %N",
827 rule_number, encoding_type_names, rule->type);
828 pld->destroy(pld);
829 return PARSE_ERROR;
830 }
831 }
832 /* process next rulue */
833 rule++;
834 }
835
836 *payload = pld;
837 DBG2(DBG_ENC, "parsing %N payload finished",
838 payload_type_names, payload_type);
839 return SUCCESS;
840 }
841
842 /**
843 * Implementation of parser_t.get_remaining_byte_count.
844 */
845 static int get_remaining_byte_count (private_parser_t *this)
846 {
847 return this->input_roof - this->byte_pos;
848 }
849
850 /**
851 * Implementation of parser_t.reset_context.
852 */
853 static void reset_context (private_parser_t *this)
854 {
855 this->byte_pos = this->input;
856 this->bit_pos = 0;
857 }
858
859 /**
860 * Implementation of parser_t.destroy.
861 */
862 static void destroy(private_parser_t *this)
863 {
864 free(this);
865 }
866
867 /*
868 * Described in header.
869 */
870 parser_t *parser_create(chunk_t data)
871 {
872 private_parser_t *this = malloc_thing(private_parser_t);
873
874 this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**))parse_payload;
875 this->public.reset_context = (void(*)(parser_t*)) reset_context;
876 this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count;
877 this->public.destroy = (void(*)(parser_t*)) destroy;
878
879 this->input = data.ptr;
880 this->byte_pos = data.ptr;
881 this->bit_pos = 0;
882 this->input_roof = data.ptr + data.len;
883
884 return &this->public;
885 }
886