4 * @brief Implementation of parser_t.
9 * Copyright (C) 2005-2006 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #include <arpa/inet.h>
32 #include <utils/linked_list.h>
33 #include <encoding/payloads/encodings.h>
34 #include <encoding/payloads/payload.h>
35 #include <encoding/payloads/sa_payload.h>
36 #include <encoding/payloads/proposal_substructure.h>
37 #include <encoding/payloads/transform_substructure.h>
38 #include <encoding/payloads/transform_attribute.h>
39 #include <encoding/payloads/ke_payload.h>
40 #include <encoding/payloads/nonce_payload.h>
41 #include <encoding/payloads/id_payload.h>
42 #include <encoding/payloads/notify_payload.h>
43 #include <encoding/payloads/encryption_payload.h>
44 #include <encoding/payloads/auth_payload.h>
45 #include <encoding/payloads/cert_payload.h>
46 #include <encoding/payloads/certreq_payload.h>
47 #include <encoding/payloads/ts_payload.h>
48 #include <encoding/payloads/delete_payload.h>
49 #include <encoding/payloads/vendor_id_payload.h>
50 #include <encoding/payloads/cp_payload.h>
51 #include <encoding/payloads/configuration_attribute.h>
52 #include <encoding/payloads/eap_payload.h>
53 #include <encoding/payloads/unknown_payload.h>
56 typedef struct private_parser_t private_parser_t
;
59 * Private data stored in a context.
61 * Contains pointers and counters to store current state.
63 struct private_parser_t
{
65 * Public members, see parser_t.
70 * @brief Parse a 4-Bit unsigned integer from the current parsing position.
72 * @param this parser_t object
73 * @param rule_number number of current rule
74 * @param[out] output_pos pointer where to write the parsed result
77 * - PARSE_ERROR when not successful
79 status_t (*parse_uint4
) (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
);
82 * @brief Parse a 8-Bit unsigned integer from the current parsing position.
84 * @param this parser_t object
85 * @param rule_number number of current rule
86 * @param[out] output_pos pointer where to write the parsed result
89 * - PARSE_ERROR when not successful
91 status_t (*parse_uint8
) (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
);
94 * @brief Parse a 15-Bit unsigned integer from the current parsing position.
96 * This is a special case used for ATTRIBUTE_TYPE.
97 * Big-/Little-endian conversion is done here.
99 * @param this parser_t object
100 * @param rule_number number of current rule
101 * @param[out] output_pos pointer where to write the parsed result
104 * - PARSE_ERROR when not successful
106 status_t (*parse_uint15
) (private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
);
109 * @brief Parse a 16-Bit unsigned integer from the current parsing position.
111 * Big-/Little-endian conversion is done here.
113 * @param this parser_t object
114 * @param rule_number number of current rule
115 * @param[out] output_pos pointer where to write the parsed result
118 * - PARSE_ERROR when not successful
120 status_t (*parse_uint16
) (private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
);
123 * @brief Parse a 32-Bit unsigned integer from the current parsing position.
125 * Big-/Little-endian conversion is done here.
127 * @param this parser_t object
128 * @param rule_number number of current rule
129 * @param[out] output_pos pointer where to write the parsed result
132 * - PARSE_ERROR when not successful
134 status_t (*parse_uint32
) (private_parser_t
*this, int rule_number
, u_int32_t
*output_pos
);
137 * @brief Parse a 64-Bit unsigned integer from the current parsing position.
139 * @todo add support for big-endian machines.
141 * @param this parser_t object
142 * @param rule_number number of current rule
143 * @param[out] output_pos pointer where to write the parsed result
146 * - PARSE_ERROR when not successful
148 status_t (*parse_uint64
) (private_parser_t
*this, int rule_number
, u_int64_t
*output_pos
);
151 * @brief Parse a given amount of bytes and writes them to a specific location
153 * @param this parser_t object
154 * @param rule_number number of current rule
155 * @param[out] output_pos pointer where to write the parsed result
156 * @param bytes number of bytes to parse
159 * - PARSE_ERROR when not successful
161 status_t (*parse_bytes
) (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
,size_t bytes
);
164 * @brief Parse a single Bit from the current parsing position
166 * @param this parser_t object
167 * @param rule_number number of current rule
168 * @param[out] output_pos pointer where to write the parsed result
171 * - PARSE_ERROR when not successful
173 status_t (*parse_bit
) (private_parser_t
*this, int rule_number
, bool *output_pos
);
176 * @brief Parse substructures in a list
178 * This function calls the parser recursively to parse contained substructures
179 * in a linked_list_t. The list must already be created. Payload defines
180 * the type of the substructures. parsing is continued until the specified length
181 * is completely parsed.
183 * @param this parser_t object
184 * @param rule_number number of current rule
185 * @param[out] output_pos pointer of a linked_list where substructures are added
186 * @param payload_type type of the contained substructures to parse
187 * @param length number of bytes to parse in this list
190 * - PARSE_ERROR when not successful
192 status_t (*parse_list
) (private_parser_t
*this, int rule_number
, linked_list_t
**output_pos
, payload_type_t payload_ype
, size_t length
);
195 * @brief Parse data from current parsing position in a chunk.
197 * This function clones length number of bytes to output_pos, without
198 * modifiyng them. Space will be allocated and must be freed by caller.
200 * @param this parser_t object
201 * @param rule_number number of current rule
202 * @param[out] output_pos pointer of a chunk which will point to the allocated data
203 * @param length number of bytes to clone
206 * - PARSE_ERROR when not successful
208 status_t (*parse_chunk
) (private_parser_t
*this, int rule_number
, chunk_t
*output_pos
, size_t length
);
211 * Current bit for reading in input data.
216 * Current byte for reading in input data.
221 * Input data to parse.
226 * Roof of input, used for length-checking.
228 u_int8_t
*input_roof
;
231 * Set of encoding rules for this parsing session.
233 encoding_rule_t
*rules
;
237 * Implementation of private_parser_t.parse_uint4.
239 static status_t
parse_uint4(private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
)
241 if (this->byte_pos
+ sizeof(u_int8_t
) > this->input_roof
)
243 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
244 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
247 switch (this->bit_pos
)
250 /* caller interested in result ? */
251 if (output_pos
!= NULL
)
253 *output_pos
= *(this->byte_pos
) >> 4;
258 /* caller interested in result ? */
259 if (output_pos
!= NULL
)
261 *output_pos
= *(this->byte_pos
) & 0x0F;
267 DBG2(DBG_ENC
, " found rule %d %N on bitpos %d",
268 rule_number
, encoding_type_names
,
269 this->rules
[rule_number
].type
, this->bit_pos
);
273 if (output_pos
!= NULL
)
275 DBG3(DBG_ENC
, " => %d", *output_pos
);
282 * Implementation of private_parser_t.parse_uint8.
284 static status_t
parse_uint8(private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
)
286 if (this->byte_pos
+ sizeof(u_int8_t
) > this->input_roof
)
288 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
289 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
294 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d",
295 rule_number
, encoding_type_names
,
296 this->rules
[rule_number
].type
, this->bit_pos
);
300 /* caller interested in result ? */
301 if (output_pos
!= NULL
)
303 *output_pos
= *(this->byte_pos
);
304 DBG3(DBG_ENC
, " => %d", *output_pos
);
312 * Implementation of private_parser_t.parse_uint15.
314 static status_t
parse_uint15(private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
)
316 if (this->byte_pos
+ sizeof(u_int16_t
) > this->input_roof
)
318 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
319 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
322 if (this->bit_pos
!= 1)
324 DBG2(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
325 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
328 /* caller interested in result ? */
329 if (output_pos
!= NULL
)
331 *output_pos
= ntohs(*((u_int16_t
*)this->byte_pos
)) & ~0x8000;
332 DBG3(DBG_ENC
, " => %d", *output_pos
);
341 * Implementation of private_parser_t.parse_uint16.
343 static status_t
parse_uint16(private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
)
345 if (this->byte_pos
+ sizeof(u_int16_t
) > this->input_roof
)
347 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
348 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
353 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
354 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
357 /* caller interested in result ? */
358 if (output_pos
!= NULL
)
360 *output_pos
= ntohs(*((u_int16_t
*)this->byte_pos
));
362 DBG3(DBG_ENC
, " => %d", *output_pos
);
369 * Implementation of private_parser_t.parse_uint32.
371 static status_t
parse_uint32(private_parser_t
*this, int rule_number
, u_int32_t
*output_pos
)
373 if (this->byte_pos
+ sizeof(u_int32_t
) > this->input_roof
)
375 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
376 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
381 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
382 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
385 /* caller interested in result ? */
386 if (output_pos
!= NULL
)
388 *output_pos
= ntohl(*((u_int32_t
*)this->byte_pos
));
390 DBG3(DBG_ENC
, " => %d", *output_pos
);
398 * Implementation of private_parser_t.parse_uint64.
400 static status_t
parse_uint64(private_parser_t
*this, int rule_number
, u_int64_t
*output_pos
)
402 if (this->byte_pos
+ sizeof(u_int64_t
) > this->input_roof
)
404 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
405 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
410 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
411 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
414 /* caller interested in result ? */
415 if (output_pos
!= NULL
)
417 /* assuming little endian host order */
418 *(output_pos
+ 1) = ntohl(*((u_int32_t
*)this->byte_pos
));
419 *output_pos
= ntohl(*(((u_int32_t
*)this->byte_pos
) + 1));
421 DBG3(DBG_ENC
, " => %b", (void*)output_pos
, sizeof(u_int64_t
));
429 * Implementation of private_parser_t.parse_bytes.
431 static status_t
parse_bytes (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
,size_t bytes
)
433 if (this->byte_pos
+ bytes
> this->input_roof
)
435 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
436 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
441 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
442 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
446 /* caller interested in result ? */
447 if (output_pos
!= NULL
)
449 memcpy(output_pos
,this->byte_pos
,bytes
);
451 DBG3(DBG_ENC
, " => %b", (void*)output_pos
, bytes
);
453 this->byte_pos
+= bytes
;
459 * Implementation of private_parser_t.parse_bit.
461 static status_t
parse_bit(private_parser_t
*this, int rule_number
, bool *output_pos
)
463 if (this->byte_pos
+ sizeof(u_int8_t
) > this->input_roof
)
465 DBG1(DBG_ENC
, " not enough input to parse rule %d %N",
466 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
469 /* caller interested in result ? */
470 if (output_pos
!= NULL
)
473 mask
= 0x01 << (7 - this->bit_pos
);
474 *output_pos
= *this->byte_pos
& mask
;
478 /* set to a "clean", comparable true */
482 DBG3(DBG_ENC
, " => %d", *output_pos
);
484 this->bit_pos
= (this->bit_pos
+ 1) % 8;
485 if (this->bit_pos
== 0)
494 * Implementation of private_parser_t.parse_list.
496 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
)
498 linked_list_t
* list
= *output_pos
;
502 DBG1(DBG_ENC
, " invalid length for rule %d %N",
503 rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
509 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
510 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
516 u_int8_t
*pos_before
= this->byte_pos
;
519 DBG2(DBG_ENC
, " %d bytes left, parsing recursively %N",
520 length
, payload_type_names
, payload_type
);
521 status
= this->public.parse_payload((parser_t
*)this, payload_type
, &payload
);
522 if (status
!= SUCCESS
)
524 DBG1(DBG_ENC
, " parsing of a %N substructure failed",
525 payload_type_names
, payload_type
);
528 list
->insert_last(list
, payload
);
529 length
-= this->byte_pos
- pos_before
;
536 * Implementation of private_parser_t.parse_chunk.
538 static status_t
parse_chunk(private_parser_t
*this, int rule_number
, chunk_t
*output_pos
, size_t length
)
540 if (this->byte_pos
+ length
> this->input_roof
)
542 DBG1(DBG_ENC
, " not enough input (%d bytes) to parse rule %d %N",
543 length
, rule_number
, encoding_type_names
, this->rules
[rule_number
].type
);
548 DBG1(DBG_ENC
, " found rule %d %N on bitpos %d", rule_number
,
549 encoding_type_names
, this->rules
[rule_number
].type
, this->bit_pos
);
552 if (output_pos
!= NULL
)
554 output_pos
->len
= length
;
555 output_pos
->ptr
= malloc(length
);
556 memcpy(output_pos
->ptr
, this->byte_pos
, length
);
558 this->byte_pos
+= length
;
559 DBG3(DBG_ENC
, " => %b", (void*)output_pos
->ptr
, length
);
565 * Implementation of parser_t.parse_payload.
567 static status_t
parse_payload(private_parser_t
*this, payload_type_t payload_type
, payload_t
**payload
)
571 size_t rule_count
, payload_length
= 0, spi_size
= 0, attribute_length
= 0;
572 u_int16_t ts_type
= 0;
573 bool attribute_format
= FALSE
;
575 encoding_rule_t
*rule
;
577 /* create instance of the payload to parse */
578 pld
= payload_create(payload_type
);
580 DBG2(DBG_ENC
, "parsing %N payload, %d bytes left",
581 payload_type_names
, payload_type
, this->input_roof
- this->byte_pos
);
583 DBG3(DBG_ENC
, "parsing payload from %b",
584 this->byte_pos
, this->input_roof
-this->byte_pos
);
586 if (pld
->get_type(pld
) == UNKNOWN_PAYLOAD
)
588 DBG1(DBG_ENC
, " payload type %d is unknown, handling as %N",
589 payload_type
, payload_type_names
, UNKNOWN_PAYLOAD
);
592 /* base pointer for output, avoids casting in every rule */
595 /* parse the payload with its own rulse */
596 pld
->get_encoding_rules(pld
, &(this->rules
), &rule_count
);
597 for (rule_number
= 0; rule_number
< rule_count
; rule_number
++)
599 rule
= &(this->rules
[rule_number
]);
600 DBG2(DBG_ENC
, " parsing rule %d %N",
601 rule_number
, encoding_type_names
, rule
->type
);
606 if (this->parse_uint4(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
615 if (this->parse_uint8(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
624 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
633 if (this->parse_uint32(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
642 if (this->parse_uint64(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
651 if (this->parse_bytes(this, rule_number
, output
+ rule
->offset
,8) != SUCCESS
)
660 if (this->parse_bit(this, rule_number
, NULL
) != SUCCESS
)
669 if (this->parse_uint8(this, rule_number
, NULL
) != SUCCESS
)
678 if (this->parse_bit(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
687 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
692 payload_length
= *(u_int16_t
*)(output
+ rule
->offset
);
697 if (this->parse_uint32(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
706 if (this->parse_uint8(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
711 spi_size
= *(u_int8_t
*)(output
+ rule
->offset
);
716 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, spi_size
) != SUCCESS
)
725 size_t proposals_length
= payload_length
- SA_PAYLOAD_HEADER_LENGTH
;
726 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, PROPOSAL_SUBSTRUCTURE
, proposals_length
) != SUCCESS
)
735 size_t transforms_length
= payload_length
- spi_size
- PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH
;
736 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, TRANSFORM_SUBSTRUCTURE
, transforms_length
) != SUCCESS
)
743 case TRANSFORM_ATTRIBUTES
:
745 size_t transform_a_length
= payload_length
- TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH
;
746 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, TRANSFORM_ATTRIBUTE
, transform_a_length
) != SUCCESS
)
753 case CONFIGURATION_ATTRIBUTES
:
755 size_t configuration_attributes_length
= payload_length
- CP_PAYLOAD_HEADER_LENGTH
;
756 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, CONFIGURATION_ATTRIBUTE
, configuration_attributes_length
) != SUCCESS
)
763 case ATTRIBUTE_FORMAT
:
765 if (this->parse_bit(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
770 attribute_format
= *(bool*)(output
+ rule
->offset
);
775 if (this->parse_uint15(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
780 attribute_format
= *(bool*)(output
+ rule
->offset
);
783 case CONFIGURATION_ATTRIBUTE_LENGTH
:
785 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
790 attribute_length
= *(u_int16_t
*)(output
+ rule
->offset
);
793 case ATTRIBUTE_LENGTH_OR_VALUE
:
795 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
800 attribute_length
= *(u_int16_t
*)(output
+ rule
->offset
);
803 case ATTRIBUTE_VALUE
:
805 if (attribute_format
== FALSE
)
807 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, attribute_length
) != SUCCESS
)
817 size_t nonce_length
= payload_length
- NONCE_PAYLOAD_HEADER_LENGTH
;
818 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, nonce_length
) != SUCCESS
)
827 size_t data_length
= payload_length
- ID_PAYLOAD_HEADER_LENGTH
;
828 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
837 size_t data_length
= payload_length
- AUTH_PAYLOAD_HEADER_LENGTH
;
838 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
847 size_t data_length
= payload_length
- CERT_PAYLOAD_HEADER_LENGTH
;
848 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
857 size_t data_length
= payload_length
- CERTREQ_PAYLOAD_HEADER_LENGTH
;
858 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
867 size_t data_length
= payload_length
- EAP_PAYLOAD_HEADER_LENGTH
;
868 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
877 size_t data_length
= payload_length
- DELETE_PAYLOAD_HEADER_LENGTH
;
878 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
887 size_t data_length
= payload_length
- VENDOR_ID_PAYLOAD_HEADER_LENGTH
;
888 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
895 case CONFIGURATION_ATTRIBUTE_VALUE
:
897 size_t data_length
= attribute_length
;
898 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
905 case KEY_EXCHANGE_DATA
:
907 size_t keydata_length
= payload_length
- KE_PAYLOAD_HEADER_LENGTH
;
908 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, keydata_length
) != SUCCESS
)
915 case NOTIFICATION_DATA
:
917 size_t notify_length
= payload_length
- NOTIFY_PAYLOAD_HEADER_LENGTH
- spi_size
;
918 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, notify_length
) != SUCCESS
)
927 size_t data_length
= payload_length
- ENCRYPTION_PAYLOAD_HEADER_LENGTH
;
928 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
937 if (this->parse_uint8(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
942 ts_type
= *(u_int8_t
*)(output
+ rule
->offset
);
947 size_t address_length
= (ts_type
== TS_IPV4_ADDR_RANGE
) ?
4 : 16;
948 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
,address_length
) != SUCCESS
)
955 case TRAFFIC_SELECTORS
:
957 size_t traffic_selectors_length
= payload_length
- TS_PAYLOAD_HEADER_LENGTH
;
958 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, TRAFFIC_SELECTOR_SUBSTRUCTURE
, traffic_selectors_length
) != SUCCESS
)
965 case UNKNOWN_PAYLOAD
:
967 size_t unknown_payload_data_length
= payload_length
- UNKNOWN_PAYLOAD_HEADER_LENGTH
;
968 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, unknown_payload_data_length
) != SUCCESS
)
977 DBG1(DBG_ENC
, " no rule to parse rule %d %N",
978 rule_number
, encoding_type_names
, rule
->type
);
983 /* process next rulue */
988 DBG2(DBG_ENC
, "parsing %N payload finished",
989 payload_type_names
, payload_type
);
994 * Implementation of parser_t.get_remaining_byte_count.
996 static int get_remaining_byte_count (private_parser_t
*this)
998 int count
= (this->input_roof
- this->byte_pos
);
1003 * Implementation of parser_t.reset_context.
1005 static void reset_context (private_parser_t
*this)
1007 this->byte_pos
= this->input
;
1012 * Implementation of parser_t.destroy.
1014 static void destroy(private_parser_t
*this)
1020 * Described in header.
1022 parser_t
*parser_create(chunk_t data
)
1024 private_parser_t
*this = malloc_thing(private_parser_t
);
1026 this->public.parse_payload
= (status_t(*)(parser_t
*,payload_type_t
,payload_t
**)) parse_payload
;
1027 this->public.reset_context
= (void(*)(parser_t
*)) reset_context
;
1028 this->public.get_remaining_byte_count
= (int (*) (parser_t
*))get_remaining_byte_count
;
1029 this->public.destroy
= (void(*)(parser_t
*)) destroy
;
1031 this->parse_uint4
= parse_uint4
;
1032 this->parse_uint8
= parse_uint8
;
1033 this->parse_uint15
= parse_uint15
;
1034 this->parse_uint16
= parse_uint16
;
1035 this->parse_uint32
= parse_uint32
;
1036 this->parse_uint64
= parse_uint64
;
1037 this->parse_bytes
= parse_bytes
;
1038 this->parse_bit
= parse_bit
;
1039 this->parse_list
= parse_list
;
1040 this->parse_chunk
= parse_chunk
;
1042 this->input
= data
.ptr
;
1043 this->byte_pos
= data
.ptr
;
1045 this->input_roof
= data
.ptr
+ data
.len
;
1047 return (parser_t
*)this;