diff options
Diffstat (limited to 'src/charon/encoding/parser.c')
-rw-r--r-- | src/charon/encoding/parser.c | 479 |
1 files changed, 214 insertions, 265 deletions
diff --git a/src/charon/encoding/parser.c b/src/charon/encoding/parser.c index 396054810..ac2b78c28 100644 --- a/src/charon/encoding/parser.c +++ b/src/charon/encoding/parser.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2006 Martin Willi + * Copyright (C) 2005-2009 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil * @@ -12,8 +12,6 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. - * - * $Id: parser.c 4703 2008-11-26 10:54:08Z martin $ */ #include <stdlib.h> @@ -88,29 +86,52 @@ struct private_parser_t { }; /** + * Forward declaration + */ +static status_t parse_payload(private_parser_t *this, + payload_type_t payload_type, payload_t **payload); + +/** + * Log invalid length error + */ +static bool short_input(private_parser_t *this, int number) +{ + DBG1(DBG_ENC, " not enough input to parse rule %d %N", + number, encoding_type_names, this->rules[number].type); + return FALSE; +} + +/** + * Log unaligned rules + */ +static bool bad_bitpos(private_parser_t *this, int number) +{ + DBG1(DBG_ENC, " found rule %d %N on bitpos %d", + number, encoding_type_names, this->rules[number].type, this->bit_pos); + return FALSE; +} + +/** * Parse a 4-Bit unsigned integer from the current parsing position. */ -static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *output_pos) +static bool parse_uint4(private_parser_t *this, int rule_number, + u_int8_t *output_pos) { - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } switch (this->bit_pos) { case 0: - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { *output_pos = *(this->byte_pos) >> 4; } this->bit_pos = 4; break; - case 4: - /* caller interested in result ? */ - if (output_pos != NULL) + case 4: + if (output_pos) { *output_pos = *(this->byte_pos) & 0x0F; } @@ -118,311 +139,240 @@ static status_t parse_uint4(private_parser_t *this, int rule_number, u_int8_t *o this->byte_pos++; break; default: - DBG2(DBG_ENC, " found rule %d %N on bitpos %d", - rule_number, encoding_type_names, - this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - - if (output_pos != NULL) + if (output_pos) { DBG3(DBG_ENC, " => %d", *output_pos); } - - return SUCCESS; + return TRUE; } /** * Parse a 8-Bit unsigned integer from the current parsing position. */ -static status_t parse_uint8(private_parser_t *this, int rule_number, u_int8_t *output_pos) +static bool parse_uint8(private_parser_t *this, int rule_number, + u_int8_t *output_pos) { - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } if (this->bit_pos) { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", - rule_number, encoding_type_names, - this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { *output_pos = *(this->byte_pos); DBG3(DBG_ENC, " => %d", *output_pos); } this->byte_pos++; - - return SUCCESS; + return TRUE; } /** * Parse a 15-Bit unsigned integer from the current parsing position. */ -static status_t parse_uint15(private_parser_t *this, int rule_number, u_int16_t *output_pos) +static bool parse_uint15(private_parser_t *this, int rule_number, + u_int16_t *output_pos) { if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } if (this->bit_pos != 1) { - DBG2(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { - *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & ~0x8000; + memcpy(output_pos, this->byte_pos, sizeof(u_int16_t)); + *output_pos = ntohs(*output_pos) & ~0x8000; DBG3(DBG_ENC, " => %d", *output_pos); } - this->byte_pos += 2; + this->byte_pos += sizeof(u_int16_t); this->bit_pos = 0; - - return SUCCESS; + return TRUE; } /** * Parse a 16-Bit unsigned integer from the current parsing position. */ -static status_t parse_uint16(private_parser_t *this, int rule_number, u_int16_t *output_pos) +static bool parse_uint16(private_parser_t *this, int rule_number, + u_int16_t *output_pos) { if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } if (this->bit_pos) { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { - *output_pos = ntohs(*((u_int16_t*)this->byte_pos)); - + memcpy(output_pos, this->byte_pos, sizeof(u_int16_t)); + *output_pos = ntohs(*output_pos); DBG3(DBG_ENC, " => %d", *output_pos); } - this->byte_pos += 2; - - return SUCCESS; + this->byte_pos += sizeof(u_int16_t); + return TRUE; } /** * Parse a 32-Bit unsigned integer from the current parsing position. */ -static status_t parse_uint32(private_parser_t *this, int rule_number, u_int32_t *output_pos) +static bool parse_uint32(private_parser_t *this, int rule_number, + u_int32_t *output_pos) { if (this->byte_pos + sizeof(u_int32_t) > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } if (this->bit_pos) { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { - *output_pos = ntohl(*((u_int32_t*)this->byte_pos)); - + memcpy(output_pos, this->byte_pos, sizeof(u_int32_t)); + *output_pos = ntohl(*output_pos); DBG3(DBG_ENC, " => %d", *output_pos); } - this->byte_pos += 4; - - return SUCCESS; -} - -/** - * Parse a 64-Bit unsigned integer from the current parsing position. - */ -static status_t parse_uint64(private_parser_t *this, int rule_number, u_int64_t *output_pos) -{ - if (this->byte_pos + sizeof(u_int64_t) > this->input_roof) - { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; - } - if (this->bit_pos) - { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; - } - /* caller interested in result ? */ - if (output_pos != NULL) - { - /* assuming little endian host order */ - *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos)); - *output_pos = ntohl(*(((u_int32_t*)this->byte_pos) + 1)); - - DBG3(DBG_ENC, " => %b", (void*)output_pos, sizeof(u_int64_t)); - } - this->byte_pos += 8; - - return SUCCESS; + this->byte_pos += sizeof(u_int32_t); + return TRUE; } /** * Parse a given amount of bytes and writes them to a specific location */ -static status_t parse_bytes (private_parser_t *this, int rule_number, u_int8_t *output_pos,size_t bytes) +static bool parse_bytes(private_parser_t *this, int rule_number, + u_int8_t *output_pos, int bytes) { if (this->byte_pos + bytes > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } if (this->bit_pos) { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { - memcpy(output_pos,this->byte_pos,bytes); - - DBG3(DBG_ENC, " => %b", (void*)output_pos, bytes); + memcpy(output_pos, this->byte_pos, bytes); + DBG3(DBG_ENC, " => %b", output_pos, bytes); } this->byte_pos += bytes; - - return SUCCESS; + return TRUE; } /** * Parse a single Bit from the current parsing position */ -static status_t parse_bit(private_parser_t *this, int rule_number, bool *output_pos) +static bool parse_bit(private_parser_t *this, int rule_number, + bool *output_pos) { if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) { - DBG1(DBG_ENC, " not enough input to parse rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } - /* caller interested in result ? */ - if (output_pos != NULL) + if (output_pos) { u_int8_t mask; mask = 0x01 << (7 - this->bit_pos); *output_pos = *this->byte_pos & mask; - + if (*output_pos) - { - /* set to a "clean", comparable true */ + { /* set to a "clean", comparable true */ *output_pos = TRUE; } - DBG3(DBG_ENC, " => %d", *output_pos); } this->bit_pos = (this->bit_pos + 1) % 8; - if (this->bit_pos == 0) + if (this->bit_pos == 0) { - this->byte_pos++; + this->byte_pos++; } - - return SUCCESS; + return TRUE; } /** * Parse substructures in a list. */ -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) +static bool parse_list(private_parser_t *this, int rule_number, + linked_list_t **output_pos, payload_type_t payload_type, int length) { - linked_list_t * list = *output_pos; + linked_list_t *list = *output_pos; if (length < 0) { - DBG1(DBG_ENC, " invalid length for rule %d %N", - rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } - if (this->bit_pos) { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - while (length > 0) { u_int8_t *pos_before = this->byte_pos; payload_t *payload; - status_t status; + DBG2(DBG_ENC, " %d bytes left, parsing recursively %N", length, payload_type_names, payload_type); - status = this->public.parse_payload((parser_t*)this, payload_type, &payload); - if (status != SUCCESS) + + if (parse_payload(this, payload_type, &payload) != SUCCESS) { DBG1(DBG_ENC, " parsing of a %N substructure failed", payload_type_names, payload_type); - return status; + return FALSE; } list->insert_last(list, payload); length -= this->byte_pos - pos_before; } + if (length != 0) + { /* must yield exactly to zero */ + DBG1(DBG_ENC, " length of %N substructure list invalid", + payload_type_names, payload_type); + return FALSE; + } *output_pos = list; - return SUCCESS; + return TRUE; } /** * Parse data from current parsing position in a chunk. */ -static status_t parse_chunk(private_parser_t *this, int rule_number, chunk_t *output_pos, size_t length) +static bool parse_chunk(private_parser_t *this, int rule_number, + chunk_t *output_pos, int length) { if (this->byte_pos + length > this->input_roof) { - DBG1(DBG_ENC, " not enough input (%d bytes) to parse rule %d %N", - length, rule_number, encoding_type_names, this->rules[rule_number].type); - return PARSE_ERROR; + return short_input(this, rule_number); } if (this->bit_pos) { - DBG1(DBG_ENC, " found rule %d %N on bitpos %d", rule_number, - encoding_type_names, this->rules[rule_number].type, this->bit_pos); - return PARSE_ERROR; + return bad_bitpos(this, rule_number); } - if (output_pos != NULL) + if (output_pos) { - output_pos->len = length; - output_pos->ptr = malloc(length); + *output_pos = chunk_alloc(length); memcpy(output_pos->ptr, this->byte_pos, length); + DBG3(DBG_ENC, " => %b", output_pos->ptr, length); } this->byte_pos += length; - DBG3(DBG_ENC, " => %b", (void*)output_pos->ptr, length); - - return SUCCESS; + return TRUE; } /** * Implementation of parser_t.parse_payload. */ -static status_t parse_payload(private_parser_t *this, payload_type_t payload_type, payload_t **payload) +static status_t parse_payload(private_parser_t *this, + payload_type_t payload_type, payload_t **payload) { payload_t *pld; void *output; - size_t rule_count, payload_length = 0, spi_size = 0, attribute_length = 0; + size_t rule_count; + int payload_length = 0, spi_size = 0, attribute_length = 0; u_int16_t ts_type = 0; bool attribute_format = FALSE; int rule_number; @@ -435,7 +385,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ payload_type_names, payload_type, this->input_roof - this->byte_pos); DBG3(DBG_ENC, "parsing payload from %b", - this->byte_pos, this->input_roof-this->byte_pos); + this->byte_pos, this->input_roof - this->byte_pos); if (pld->get_type(pld) == UNKNOWN_PAYLOAD) { @@ -447,7 +397,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ output = pld; /* parse the payload with its own rulse */ - pld->get_encoding_rules(pld, &(this->rules), &rule_count); + pld->get_encoding_rules(pld, &this->rules, &rule_count); for (rule_number = 0; rule_number < rule_count; rule_number++) { rule = &(this->rules[rule_number]); @@ -457,7 +407,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ { case U_INT_4: { - if (parse_uint4(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint4(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -466,7 +416,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case U_INT_8: { - if (parse_uint8(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint8(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -475,7 +425,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case U_INT_16: { - if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint16(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -484,16 +434,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case U_INT_32: { - if (parse_uint32(this, rule_number, output + rule->offset) != SUCCESS) - { - pld->destroy(pld); - return PARSE_ERROR; - } - break; - } - case U_INT_64: - { - if (parse_uint64(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint32(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -502,7 +443,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case IKE_SPI: { - if (parse_bytes(this, rule_number, output + rule->offset,8) != SUCCESS) + if (!parse_bytes(this, rule_number, output + rule->offset, 8)) { pld->destroy(pld); return PARSE_ERROR; @@ -511,7 +452,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case RESERVED_BIT: { - if (parse_bit(this, rule_number, NULL) != SUCCESS) + if (!parse_bit(this, rule_number, NULL)) { pld->destroy(pld); return PARSE_ERROR; @@ -520,7 +461,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case RESERVED_BYTE: { - if (parse_uint8(this, rule_number, NULL) != SUCCESS) + if (!parse_uint8(this, rule_number, NULL)) { pld->destroy(pld); return PARSE_ERROR; @@ -529,7 +470,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case FLAG: { - if (parse_bit(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_bit(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -538,11 +479,12 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case PAYLOAD_LENGTH: { - if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint16(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; } + /* parsed u_int16 should be aligned */ payload_length = *(u_int16_t*)(output + rule->offset); if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH) { @@ -553,7 +495,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case HEADER_LENGTH: { - if (parse_uint32(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint32(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -562,7 +504,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case SPI_SIZE: { - if (parse_uint8(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint8(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -572,7 +514,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case SPI: { - if (parse_chunk(this, rule_number, output + rule->offset, spi_size) != SUCCESS) + if (!parse_chunk(this, rule_number, output + rule->offset, + spi_size)) { pld->destroy(pld); return PARSE_ERROR; @@ -582,8 +525,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case PROPOSALS: { if (payload_length < SA_PAYLOAD_HEADER_LENGTH || - parse_list(this, rule_number, output + rule->offset, PROPOSAL_SUBSTRUCTURE, - payload_length - SA_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_list(this, rule_number, output + rule->offset, + PROPOSAL_SUBSTRUCTURE, + payload_length - SA_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -592,9 +536,11 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case TRANSFORMS: { - if (payload_length < spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH || - parse_list(this, rule_number, output + rule->offset, TRANSFORM_SUBSTRUCTURE, - payload_length - spi_size - PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS) + if (payload_length < + spi_size + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH || + !parse_list(this, rule_number, output + rule->offset, + TRANSFORM_SUBSTRUCTURE, payload_length - spi_size - + PROPOSAL_SUBSTRUCTURE_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -604,8 +550,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case TRANSFORM_ATTRIBUTES: { if (payload_length < TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH || - parse_list(this, rule_number, output + rule->offset, TRANSFORM_ATTRIBUTE, - payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH) != SUCCESS) + !parse_list(this, rule_number, output + rule->offset, + TRANSFORM_ATTRIBUTE, + payload_length - TRANSFORM_SUBSTRUCTURE_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -615,8 +562,9 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case CONFIGURATION_ATTRIBUTES: { if (payload_length < CP_PAYLOAD_HEADER_LENGTH || - parse_list(this, rule_number, output + rule->offset, CONFIGURATION_ATTRIBUTE, - payload_length - CP_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_list(this, rule_number, output + rule->offset, + CONFIGURATION_ATTRIBUTE, + payload_length - CP_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -625,7 +573,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case ATTRIBUTE_FORMAT: { - if (parse_bit(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_bit(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -635,17 +583,16 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case ATTRIBUTE_TYPE: { - if (parse_uint15(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint15(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; } - attribute_format = *(bool*)(output + rule->offset); break; } case CONFIGURATION_ATTRIBUTE_LENGTH: { - if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint16(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -654,8 +601,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ break; } case ATTRIBUTE_LENGTH_OR_VALUE: - { - if (parse_uint16(this, rule_number, output + rule->offset) != SUCCESS) + { + if (!parse_uint16(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; @@ -665,43 +612,42 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } case ATTRIBUTE_VALUE: { - if (attribute_format == FALSE) + if (attribute_format == FALSE && + !parse_chunk(this, rule_number, output + rule->offset, + attribute_length)) { - if (parse_chunk(this, rule_number, output + rule->offset, attribute_length) != SUCCESS) - { - pld->destroy(pld); - return PARSE_ERROR; - } + pld->destroy(pld); + return PARSE_ERROR; } break; } case NONCE_DATA: { if (payload_length < NONCE_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - NONCE_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - NONCE_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; - } + } break; } case ID_DATA: { if (payload_length < ID_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - ID_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - ID_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; - } + } break; } case AUTH_DATA: { if (payload_length < AUTH_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - AUTH_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - AUTH_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -711,8 +657,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case CERT_DATA: { if (payload_length < CERT_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - CERT_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - CERT_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -722,8 +668,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case CERTREQ_DATA: { if (payload_length < CERTREQ_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - CERTREQ_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -733,8 +679,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case EAP_DATA: { if (payload_length < EAP_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - EAP_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - EAP_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; @@ -744,109 +690,112 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ case SPIS: { if (payload_length < DELETE_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - DELETE_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - DELETE_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; - } - break; + } + break; } case VID_DATA: { if (payload_length < VENDOR_ID_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - VENDOR_ID_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; - } - break; + } + break; } case CONFIGURATION_ATTRIBUTE_VALUE: { - size_t data_length = attribute_length; - if (parse_chunk(this, rule_number, output + rule->offset, data_length) != SUCCESS) + if (!parse_chunk(this, rule_number, output + rule->offset, + attribute_length)) { pld->destroy(pld); return PARSE_ERROR; - } - break; + } + break; } case KEY_EXCHANGE_DATA: { if (payload_length < KE_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - KE_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - KE_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; - } - break; + } + break; } case NOTIFICATION_DATA: { if (payload_length < NOTIFY_PAYLOAD_HEADER_LENGTH + spi_size || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - NOTIFY_PAYLOAD_HEADER_LENGTH - spi_size)) { pld->destroy(pld); return PARSE_ERROR; - } - break; + } + break; } case ENCRYPTED_DATA: - { + { if (payload_length < ENCRYPTION_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - ENCRYPTION_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; - } - break; + } + break; } case TS_TYPE: { - if (parse_uint8(this, rule_number, output + rule->offset) != SUCCESS) + if (!parse_uint8(this, rule_number, output + rule->offset)) { pld->destroy(pld); return PARSE_ERROR; } ts_type = *(u_int8_t*)(output + rule->offset); - break; + break; } case ADDRESS: { - size_t address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16; - if (parse_chunk(this, rule_number, output + rule->offset,address_length) != SUCCESS) + int address_length = (ts_type == TS_IPV4_ADDR_RANGE) ? 4 : 16; + + if (!parse_chunk(this, rule_number, output + rule->offset, + address_length)) { pld->destroy(pld); return PARSE_ERROR; } - break; + break; } case TRAFFIC_SELECTORS: { if (payload_length < TS_PAYLOAD_HEADER_LENGTH || - parse_list(this, rule_number, output + rule->offset, TRAFFIC_SELECTOR_SUBSTRUCTURE, - payload_length - TS_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_list(this, rule_number, output + rule->offset, + TRAFFIC_SELECTOR_SUBSTRUCTURE, + payload_length - TS_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; } - break; + break; } case UNKNOWN_DATA: { if (payload_length < UNKNOWN_PAYLOAD_HEADER_LENGTH || - parse_chunk(this, rule_number, output + rule->offset, - payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH) != SUCCESS) + !parse_chunk(this, rule_number, output + rule->offset, + payload_length - UNKNOWN_PAYLOAD_HEADER_LENGTH)) { pld->destroy(pld); return PARSE_ERROR; } - break; + break; } default: { @@ -871,8 +820,7 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ */ static int get_remaining_byte_count (private_parser_t *this) { - int count = (this->input_roof - this->byte_pos); - return count; + return this->input_roof - this->byte_pos; } /** @@ -889,7 +837,7 @@ static void reset_context (private_parser_t *this) */ static void destroy(private_parser_t *this) { - free(this); + free(this); } /* @@ -899,7 +847,7 @@ parser_t *parser_create(chunk_t data) { private_parser_t *this = malloc_thing(private_parser_t); - this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload; + this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**))parse_payload; this->public.reset_context = (void(*)(parser_t*)) reset_context; this->public.get_remaining_byte_count = (int (*) (parser_t *))get_remaining_byte_count; this->public.destroy = (void(*)(parser_t*)) destroy; @@ -909,5 +857,6 @@ parser_t *parser_create(chunk_t data) this->bit_pos = 0; this->input_roof = data.ptr + data.len; - return (parser_t*)this; + return &this->public; } + |