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