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>
31 #include <definitions.h>
33 #include <utils/logger.h>
34 #include <utils/linked_list.h>
35 #include <encoding/payloads/encodings.h>
36 #include <encoding/payloads/payload.h>
37 #include <encoding/payloads/sa_payload.h>
38 #include <encoding/payloads/proposal_substructure.h>
39 #include <encoding/payloads/transform_substructure.h>
40 #include <encoding/payloads/transform_attribute.h>
41 #include <encoding/payloads/ke_payload.h>
42 #include <encoding/payloads/nonce_payload.h>
43 #include <encoding/payloads/id_payload.h>
44 #include <encoding/payloads/notify_payload.h>
45 #include <encoding/payloads/encryption_payload.h>
46 #include <encoding/payloads/auth_payload.h>
47 #include <encoding/payloads/cert_payload.h>
48 #include <encoding/payloads/certreq_payload.h>
49 #include <encoding/payloads/ts_payload.h>
50 #include <encoding/payloads/delete_payload.h>
51 #include <encoding/payloads/vendor_id_payload.h>
52 #include <encoding/payloads/cp_payload.h>
53 #include <encoding/payloads/configuration_attribute.h>
54 #include <encoding/payloads/eap_payload.h>
55 #include <encoding/payloads/unknown_payload.h>
58 typedef struct private_parser_t private_parser_t
;
61 * Private data stored in a context.
63 * Contains pointers and counters to store current state.
65 struct private_parser_t
{
67 * Public members, see parser_t.
72 * @brief Parse a 4-Bit unsigned integer from the current parsing position.
74 * @param this parser_t object
75 * @param rule_number number of current rule
76 * @param[out] output_pos pointer where to write the parsed result
79 * - PARSE_ERROR when not successful
81 status_t (*parse_uint4
) (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
);
84 * @brief Parse a 8-Bit unsigned integer from the current parsing position.
86 * @param this parser_t object
87 * @param rule_number number of current rule
88 * @param[out] output_pos pointer where to write the parsed result
91 * - PARSE_ERROR when not successful
93 status_t (*parse_uint8
) (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
);
96 * @brief Parse a 15-Bit unsigned integer from the current parsing position.
98 * This is a special case used for ATTRIBUTE_TYPE.
99 * Big-/Little-endian conversion is done here.
101 * @param this parser_t object
102 * @param rule_number number of current rule
103 * @param[out] output_pos pointer where to write the parsed result
106 * - PARSE_ERROR when not successful
108 status_t (*parse_uint15
) (private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
);
111 * @brief Parse a 16-Bit unsigned integer from the current parsing position.
113 * Big-/Little-endian conversion is done here.
115 * @param this parser_t object
116 * @param rule_number number of current rule
117 * @param[out] output_pos pointer where to write the parsed result
120 * - PARSE_ERROR when not successful
122 status_t (*parse_uint16
) (private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
);
125 * @brief Parse a 32-Bit unsigned integer from the current parsing position.
127 * Big-/Little-endian conversion is done here.
129 * @param this parser_t object
130 * @param rule_number number of current rule
131 * @param[out] output_pos pointer where to write the parsed result
134 * - PARSE_ERROR when not successful
136 status_t (*parse_uint32
) (private_parser_t
*this, int rule_number
, u_int32_t
*output_pos
);
139 * @brief Parse a 64-Bit unsigned integer from the current parsing position.
141 * @todo add support for big-endian machines.
143 * @param this parser_t object
144 * @param rule_number number of current rule
145 * @param[out] output_pos pointer where to write the parsed result
148 * - PARSE_ERROR when not successful
150 status_t (*parse_uint64
) (private_parser_t
*this, int rule_number
, u_int64_t
*output_pos
);
153 * @brief Parse a given amount of bytes and writes them to a specific location
155 * @param this parser_t object
156 * @param rule_number number of current rule
157 * @param[out] output_pos pointer where to write the parsed result
158 * @param bytes number of bytes to parse
161 * - PARSE_ERROR when not successful
163 status_t (*parse_bytes
) (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
,size_t bytes
);
166 * @brief Parse a single Bit from the current parsing position
168 * @param this parser_t object
169 * @param rule_number number of current rule
170 * @param[out] output_pos pointer where to write the parsed result
173 * - PARSE_ERROR when not successful
175 status_t (*parse_bit
) (private_parser_t
*this, int rule_number
, bool *output_pos
);
178 * @brief Parse substructures in a list
180 * This function calls the parser recursivly to parse contained substructures
181 * in a linked_list_t. The list must already be created. Payload defines
182 * the type of the substructures. parsing is continued until the specified length
183 * is completely parsed.
185 * @param this parser_t object
186 * @param rule_number number of current rule
187 * @param[out] output_pos pointer of a linked_list where substructures are added
188 * @param payload_type type of the contained substructures to parse
189 * @param length number of bytes to parse in this list
192 * - PARSE_ERROR when not successful
194 status_t (*parse_list
) (private_parser_t
*this, int rule_number
, linked_list_t
**output_pos
, payload_type_t payload_ype
, size_t length
);
197 * @brief Parse data from current parsing position in a chunk.
199 * This function clones length number of bytes to output_pos, without
200 * modifiyng them. Space will be allocated and must be freed by caller.
202 * @param this parser_t object
203 * @param rule_number number of current rule
204 * @param[out] output_pos pointer of a chunk which will point to the allocated data
205 * @param length number of bytes to clone
208 * - PARSE_ERROR when not successful
210 status_t (*parse_chunk
) (private_parser_t
*this, int rule_number
, chunk_t
*output_pos
, size_t length
);
213 * Current bit for reading in input data.
218 * Current byte for reading in input data.
223 * Input data to parse.
228 * Roof of input, used for length-checking.
230 u_int8_t
*input_roof
;
233 * Set of encoding rules for this parsing session.
235 encoding_rule_t
*rules
;
238 * Assigned logger_t object.
244 * Implementation of private_parser_t.parse_uint4.
246 static status_t
parse_uint4(private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
)
248 if (this->byte_pos
+ sizeof(u_int8_t
) > this->input_roof
)
250 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
251 rule_number
, mapping_find(encoding_type_m
,
252 this->rules
[rule_number
].type
));
255 switch (this->bit_pos
)
258 /* caller interested in result ? */
259 if (output_pos
!= NULL
)
261 *output_pos
= *(this->byte_pos
) >> 4;
266 /* caller interested in result ? */
267 if (output_pos
!= NULL
)
269 *output_pos
= *(this->byte_pos
) & 0x0F;
275 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
276 rule_number
, mapping_find(encoding_type_m
,
277 this->rules
[rule_number
].type
), this->bit_pos
);
281 if (output_pos
!= NULL
)
283 this->logger
->log(this->logger
, RAW
|LEVEL2
, " => %d", *output_pos
);
290 * Implementation of private_parser_t.parse_uint8.
292 static status_t
parse_uint8(private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
)
294 if (this->byte_pos
+ sizeof(u_int8_t
) > this->input_roof
)
296 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
297 rule_number
, mapping_find(encoding_type_m
,
298 this->rules
[rule_number
].type
));
303 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
304 rule_number
, mapping_find(encoding_type_m
,
305 this->rules
[rule_number
].type
), this->bit_pos
);
309 /* caller interested in result ? */
310 if (output_pos
!= NULL
)
312 *output_pos
= *(this->byte_pos
);
313 this->logger
->log(this->logger
, RAW
|LEVEL2
, " => %d", *output_pos
);
321 * Implementation of private_parser_t.parse_uint15.
323 static status_t
parse_uint15(private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
)
325 if (this->byte_pos
+ sizeof(u_int16_t
) > this->input_roof
)
327 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
328 rule_number
, mapping_find(encoding_type_m
,
329 this->rules
[rule_number
].type
));
332 if (this->bit_pos
!= 1)
334 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
335 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
),
339 /* caller interested in result ? */
340 if (output_pos
!= NULL
)
342 *output_pos
= ntohs(*((u_int16_t
*)this->byte_pos
)) & ~0x8000;
343 this->logger
->log(this->logger
, RAW
|LEVEL2
, " => %d", *output_pos
);
352 * Implementation of private_parser_t.parse_uint16.
354 static status_t
parse_uint16(private_parser_t
*this, int rule_number
, u_int16_t
*output_pos
)
356 if (this->byte_pos
+ sizeof(u_int16_t
) > this->input_roof
)
358 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
359 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
364 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
365 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
),
369 /* caller interested in result ? */
370 if (output_pos
!= NULL
)
372 *output_pos
= ntohs(*((u_int16_t
*)this->byte_pos
));
374 this->logger
->log(this->logger
, RAW
|LEVEL2
, " => %d", *output_pos
);
381 * Implementation of private_parser_t.parse_uint32.
383 static status_t
parse_uint32(private_parser_t
*this, int rule_number
, u_int32_t
*output_pos
)
385 if (this->byte_pos
+ sizeof(u_int32_t
) > this->input_roof
)
387 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
388 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
393 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
394 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
),
398 /* caller interested in result ? */
399 if (output_pos
!= NULL
)
401 *output_pos
= ntohl(*((u_int32_t
*)this->byte_pos
));
403 this->logger
->log(this->logger
, RAW
|LEVEL2
, " => %d", *output_pos
);
411 * Implementation of private_parser_t.parse_uint64.
413 static status_t
parse_uint64(private_parser_t
*this, int rule_number
, u_int64_t
*output_pos
)
415 if (this->byte_pos
+ sizeof(u_int64_t
) > this->input_roof
)
417 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
418 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
423 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
424 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
),
428 /* caller interested in result ? */
429 if (output_pos
!= NULL
)
431 /* assuming little endian host order */
432 *(output_pos
+ 1) = ntohl(*((u_int32_t
*)this->byte_pos
));
433 *output_pos
= ntohl(*(((u_int32_t
*)this->byte_pos
) + 1));
435 this->logger
->log_bytes(this->logger
, RAW
|LEVEL2
, " =>", (void*)output_pos
, 8);
443 * Implementation of private_parser_t.parse_bytes.
445 static status_t
parse_bytes (private_parser_t
*this, int rule_number
, u_int8_t
*output_pos
,size_t bytes
)
447 if (this->byte_pos
+ bytes
> this->input_roof
)
449 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
450 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
455 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
456 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
),
461 /* caller interested in result ? */
462 if (output_pos
!= NULL
)
464 memcpy(output_pos
,this->byte_pos
,bytes
);
466 this->logger
->log_bytes(this->logger
, RAW
|LEVEL2
, " =>", (void*)output_pos
, bytes
);
468 this->byte_pos
+= bytes
;
474 * Implementation of private_parser_t.parse_bit.
476 static status_t
parse_bit(private_parser_t
*this, int rule_number
, bool *output_pos
)
478 if (this->byte_pos
+ sizeof(u_int8_t
) > this->input_roof
)
480 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " not enough input to parse rule %d %s",
481 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
484 /* caller interested in result ? */
485 if (output_pos
!= NULL
)
488 mask
= 0x01 << (7 - this->bit_pos
);
489 *output_pos
= *this->byte_pos
& mask
;
493 /* set to a "clean", comparable true */
497 this->logger
->log(this->logger
, RAW
|LEVEL2
, " => %d", *output_pos
);
499 this->bit_pos
= (this->bit_pos
+ 1) % 8;
500 if (this->bit_pos
== 0)
509 * Implementation of private_parser_t.parse_list.
511 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
)
513 linked_list_t
* list
= *output_pos
;
517 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " invalid length for rule %d %s",
518 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
524 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
525 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
), this->bit_pos
);
531 u_int8_t
*pos_before
= this->byte_pos
;
534 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, " %d bytes left, parsing recursivly %s",
535 length
, mapping_find(payload_type_m
, payload_type
));
536 status
= this->public.parse_payload((parser_t
*)this, payload_type
, &payload
);
537 if (status
!= SUCCESS
)
539 this->logger
->log(this->logger
, ERROR
, " parsing of a %s substructure failed",
540 mapping_find(payload_type_m
, payload_type
));
543 list
->insert_last(list
, payload
);
544 length
-= this->byte_pos
- pos_before
;
551 * Implementation of private_parser_t.parse_chunk.
553 static status_t
parse_chunk(private_parser_t
*this, int rule_number
, chunk_t
*output_pos
, size_t length
)
555 if (this->byte_pos
+ length
> this->input_roof
)
557 this->logger
->log(this->logger
, ERROR
, " not enough input (%d bytes) to parse rule %d %s",
558 length
, rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
));
563 this->logger
->log(this->logger
, ERROR
, " found rule %d %s on bitpos %d",
564 rule_number
, mapping_find(encoding_type_m
, this->rules
[rule_number
].type
), this->bit_pos
);
567 if (output_pos
!= NULL
)
569 output_pos
->len
= length
;
570 output_pos
->ptr
= malloc(length
);
571 memcpy(output_pos
->ptr
, this->byte_pos
, length
);
573 this->byte_pos
+= length
;
574 this->logger
->log_bytes(this->logger
, RAW
|LEVEL2
, " =>", (void*)output_pos
->ptr
, length
);
580 * Implementation of parser_t.parse_payload.
582 static status_t
parse_payload(private_parser_t
*this, payload_type_t payload_type
, payload_t
**payload
)
586 size_t rule_count
, payload_length
, spi_size
, attribute_length
;
588 bool attribute_format
;
590 encoding_rule_t
*rule
;
592 /* create instance of the payload to parse */
593 pld
= payload_create(payload_type
);
595 this->logger
->log(this->logger
, CONTROL
|LEVEL1
, "parsing %s payload, %d bytes left",
596 mapping_find(payload_type_m
, payload_type
),
597 this->input_roof
-this->byte_pos
);
599 this->logger
->log_bytes(this->logger
, RAW
|LEVEL3
, "parsing payload from", this->byte_pos
,
600 this->input_roof
-this->byte_pos
);
602 if (pld
->get_type(pld
) == UNKNOWN_PAYLOAD
)
604 this->logger
->log(this->logger
, ERROR
|LEVEL1
, " payload type %d is unknown, handling as %s",
605 payload_type
, mapping_find(payload_type_m
, UNKNOWN_PAYLOAD
));
608 /* base pointer for output, avoids casting in every rule */
611 /* parse the payload with its own rulse */
612 pld
->get_encoding_rules(pld
, &(this->rules
), &rule_count
);
613 for (rule_number
= 0; rule_number
< rule_count
; rule_number
++)
615 rule
= &(this->rules
[rule_number
]);
616 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, " parsing rule %d %s",
617 rule_number
, mapping_find(encoding_type_m
, rule
->type
));
622 if (this->parse_uint4(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
631 if (this->parse_uint8(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
640 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
649 if (this->parse_uint32(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
658 if (this->parse_uint64(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
667 if (this->parse_bytes(this, rule_number
, output
+ rule
->offset
,8) != SUCCESS
)
676 if (this->parse_bit(this, rule_number
, NULL
) != SUCCESS
)
685 if (this->parse_uint8(this, rule_number
, NULL
) != SUCCESS
)
694 if (this->parse_bit(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
703 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
708 payload_length
= *(u_int16_t
*)(output
+ rule
->offset
);
713 if (this->parse_uint32(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
722 if (this->parse_uint8(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
727 spi_size
= *(u_int8_t
*)(output
+ rule
->offset
);
732 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, spi_size
) != SUCCESS
)
741 size_t proposals_length
= payload_length
- SA_PAYLOAD_HEADER_LENGTH
;
742 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, PROPOSAL_SUBSTRUCTURE
, proposals_length
) != SUCCESS
)
751 size_t transforms_length
= payload_length
- spi_size
- PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH
;
752 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, TRANSFORM_SUBSTRUCTURE
, transforms_length
) != SUCCESS
)
759 case TRANSFORM_ATTRIBUTES
:
761 size_t transform_a_length
= payload_length
- TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH
;
762 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, TRANSFORM_ATTRIBUTE
, transform_a_length
) != SUCCESS
)
769 case CONFIGURATION_ATTRIBUTES
:
771 size_t configuration_attributes_length
= payload_length
- CP_PAYLOAD_HEADER_LENGTH
;
772 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, CONFIGURATION_ATTRIBUTE
, configuration_attributes_length
) != SUCCESS
)
779 case ATTRIBUTE_FORMAT
:
781 if (this->parse_bit(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
786 attribute_format
= *(bool*)(output
+ rule
->offset
);
791 if (this->parse_uint15(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
796 attribute_format
= *(bool*)(output
+ rule
->offset
);
799 case CONFIGURATION_ATTRIBUTE_LENGTH
:
801 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
806 attribute_length
= *(u_int16_t
*)(output
+ rule
->offset
);
809 case ATTRIBUTE_LENGTH_OR_VALUE
:
811 if (this->parse_uint16(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
816 attribute_length
= *(u_int16_t
*)(output
+ rule
->offset
);
819 case ATTRIBUTE_VALUE
:
821 if (attribute_format
== FALSE
)
823 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, attribute_length
) != SUCCESS
)
833 size_t nonce_length
= payload_length
- NONCE_PAYLOAD_HEADER_LENGTH
;
834 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, nonce_length
) != SUCCESS
)
843 size_t data_length
= payload_length
- ID_PAYLOAD_HEADER_LENGTH
;
844 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
853 size_t data_length
= payload_length
- AUTH_PAYLOAD_HEADER_LENGTH
;
854 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
863 size_t data_length
= payload_length
- CERT_PAYLOAD_HEADER_LENGTH
;
864 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
873 size_t data_length
= payload_length
- CERTREQ_PAYLOAD_HEADER_LENGTH
;
874 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
883 size_t data_length
= payload_length
- EAP_PAYLOAD_HEADER_LENGTH
;
884 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
893 size_t data_length
= payload_length
- DELETE_PAYLOAD_HEADER_LENGTH
;
894 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
903 size_t data_length
= payload_length
- VENDOR_ID_PAYLOAD_HEADER_LENGTH
;
904 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
911 case CONFIGURATION_ATTRIBUTE_VALUE
:
913 size_t data_length
= attribute_length
;
914 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
921 case KEY_EXCHANGE_DATA
:
923 size_t keydata_length
= payload_length
- KE_PAYLOAD_HEADER_LENGTH
;
924 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, keydata_length
) != SUCCESS
)
931 case NOTIFICATION_DATA
:
933 size_t notify_length
= payload_length
- NOTIFY_PAYLOAD_HEADER_LENGTH
- spi_size
;
934 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, notify_length
) != SUCCESS
)
943 size_t data_length
= payload_length
- ENCRYPTION_PAYLOAD_HEADER_LENGTH
;
944 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, data_length
) != SUCCESS
)
953 if (this->parse_uint8(this, rule_number
, output
+ rule
->offset
) != SUCCESS
)
958 ts_type
= *(u_int8_t
*)(output
+ rule
->offset
);
963 size_t address_length
= (ts_type
== TS_IPV4_ADDR_RANGE
) ?
4 : 16;
964 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
,address_length
) != SUCCESS
)
971 case TRAFFIC_SELECTORS
:
973 size_t traffic_selectors_length
= payload_length
- TS_PAYLOAD_HEADER_LENGTH
;
974 if (this->parse_list(this, rule_number
, output
+ rule
->offset
, TRAFFIC_SELECTOR_SUBSTRUCTURE
, traffic_selectors_length
) != SUCCESS
)
981 case UNKNOWN_PAYLOAD
:
983 size_t unknown_payload_data_length
= payload_length
- UNKNOWN_PAYLOAD_HEADER_LENGTH
;
984 if (this->parse_chunk(this, rule_number
, output
+ rule
->offset
, unknown_payload_data_length
) != SUCCESS
)
993 this->logger
->log(this->logger
, ERROR
, " no rule to parse rule %d %s (%d)", rule_number
, mapping_find(encoding_type_m
, rule
->type
), rule
->type
);
998 /* process next rulue */
1003 this->logger
->log(this->logger
, CONTROL
|LEVEL2
, "parsing %s payload finished.",
1004 mapping_find(payload_type_m
, payload_type
));
1009 * Implementation of parser_t.get_remaining_byte_count.
1011 static int get_remaining_byte_count (private_parser_t
*this)
1013 int count
= (this->input_roof
- this->byte_pos
);
1018 * Implementation of parser_t.reset_context.
1020 static void reset_context (private_parser_t
*this)
1022 this->byte_pos
= this->input
;
1027 * Implementation of parser_t.destroy.
1029 static void destroy(private_parser_t
*this)
1035 * Described in header.
1037 parser_t
*parser_create(chunk_t data
)
1039 private_parser_t
*this = malloc_thing(private_parser_t
);
1041 this->logger
= logger_manager
->get_logger(logger_manager
, PARSER
);
1043 this->public.parse_payload
= (status_t(*)(parser_t
*,payload_type_t
,payload_t
**)) parse_payload
;
1044 this->public.reset_context
= (void(*)(parser_t
*)) reset_context
;
1045 this->public.get_remaining_byte_count
= (int (*) (parser_t
*))get_remaining_byte_count
;
1046 this->public.destroy
= (void(*)(parser_t
*)) destroy
;
1048 this->parse_uint4
= parse_uint4
;
1049 this->parse_uint8
= parse_uint8
;
1050 this->parse_uint15
= parse_uint15
;
1051 this->parse_uint16
= parse_uint16
;
1052 this->parse_uint32
= parse_uint32
;
1053 this->parse_uint64
= parse_uint64
;
1054 this->parse_bytes
= parse_bytes
;
1055 this->parse_bit
= parse_bit
;
1056 this->parse_list
= parse_list
;
1057 this->parse_chunk
= parse_chunk
;
1059 this->input
= data
.ptr
;
1060 this->byte_pos
= data
.ptr
;
1062 this->input_roof
= data
.ptr
+ data
.len
;
1064 return (parser_t
*)this;