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