diff options
author | Martin Willi <martin@strongswan.org> | 2005-11-14 17:29:22 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2005-11-14 17:29:22 +0000 |
commit | 6c55be346a0036da2eebcfad6230857dea6f3372 (patch) | |
tree | 6b5d9983351a4ad82fb97eb3fc05ee39439e37ab | |
parent | a14dffd1cc28761947f6847f784d54b0f5db2efc (diff) | |
download | strongswan-6c55be346a0036da2eebcfad6230857dea6f3372.tar.bz2 strongswan-6c55be346a0036da2eebcfad6230857dea6f3372.tar.xz |
- parser succesfully parses sa payload
-rw-r--r-- | Source/charon/parser.c | 551 | ||||
-rw-r--r-- | Source/charon/payloads/encodings.h | 4 | ||||
-rw-r--r-- | Source/charon/payloads/payload.c | 9 | ||||
-rw-r--r-- | Source/charon/testcases/parser_test.c | 43 | ||||
-rw-r--r-- | Source/charon/testcases/parser_test.h | 4 | ||||
-rw-r--r-- | Source/charon/testcases/testcases.c | 19 |
6 files changed, 480 insertions, 150 deletions
diff --git a/Source/charon/parser.c b/Source/charon/parser.c index 4680dd162..1cf467fad 100644 --- a/Source/charon/parser.c +++ b/Source/charon/parser.c @@ -30,8 +30,11 @@ #include "globals.h" #include "utils/allocator.h" #include "utils/logger.h" +#include "utils/linked_list.h" #include "payloads/payload.h" + + /** * @private data stored in a context * @@ -44,6 +47,16 @@ struct private_parser_s { * Public members */ parser_t public; + + status_t (*parse_uint4) (private_parser_t*,encoding_rule_t*,int,u_int8_t*); + status_t (*parse_uint8) (private_parser_t*,encoding_rule_t*,int,u_int8_t*); + status_t (*parse_uint15) (private_parser_t*,encoding_rule_t*,int,u_int16_t*); + status_t (*parse_uint16) (private_parser_t*,encoding_rule_t*,int,u_int16_t*); + status_t (*parse_uint32) (private_parser_t*,encoding_rule_t*,int,u_int32_t*); + status_t (*parse_uint64) (private_parser_t*,encoding_rule_t*,int,u_int32_t*); + status_t (*parse_bit) (private_parser_t*,encoding_rule_t*,int,bool*); + status_t (*parse_list) (private_parser_t*,encoding_rule_t*,int,linked_list_t**,payload_type_t,size_t); + status_t (*parse_chunk) (private_parser_t*,encoding_rule_t*,int,chunk_t*,size_t); /** * Current bit for reading in input data @@ -65,29 +78,311 @@ struct private_parser_s { */ u_int8_t *input_roof; + /** * logger object */ logger_t *logger; +}; + + +static status_t parse_uint4(private_parser_t *this, encoding_rule_t *rule, int rule_number, u_int8_t *output_pos) +{ + if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + switch (this->bit_pos) + { + case 0: + /* caller interested in result ? */ + if (output_pos != NULL) + { + *output_pos = *(this->byte_pos) >> 4; + } + this->bit_pos = 4; + break; + case 4: + /* caller interested in result ? */ + if (output_pos != NULL) + { + *output_pos = *(this->byte_pos) & 0x0F; + } + this->bit_pos = 0; + this->byte_pos++; + break; + default: + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + if (output_pos != NULL) + { + this->logger->log(this->logger, RAW, " => %d", *output_pos); + } -}; + + return SUCCESS; +} + +static status_t parse_uint8(private_parser_t *this, encoding_rule_t *rule, int rule_number, u_int8_t *output_pos) +{ + if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + if (this->bit_pos) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + + /* caller interested in result ? */ + if (output_pos != NULL) + { + *output_pos = *(this->byte_pos); + this->logger->log(this->logger, RAW, " => %d", *output_pos); + } + this->byte_pos++; + + + + return SUCCESS; +} + +static status_t parse_uint15(private_parser_t *this, encoding_rule_t *rule, int rule_number, u_int16_t *output_pos) +{ + if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + if (this->bit_pos != 1) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + /* caller interested in result ? */ + if (output_pos != NULL) + { + *output_pos = ntohs(*((u_int16_t*)this->byte_pos)) & 0xEFFF; + this->logger->log(this->logger, RAW, " => %d", *output_pos); + } + this->byte_pos += 2; + this->bit_pos = 0; + + + + return SUCCESS; +} + + +static status_t parse_uint16(private_parser_t *this, encoding_rule_t *rule, int rule_number, u_int16_t *output_pos) +{ + if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + if (this->bit_pos) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + /* caller interested in result ? */ + if (output_pos != NULL) + { + *output_pos = ntohs(*((u_int16_t*)this->byte_pos)); + + this->logger->log(this->logger, RAW, " => %d", *output_pos); + } + this->byte_pos += 2; + + + return SUCCESS; +} + +static status_t parse_uint32(private_parser_t *this, encoding_rule_t *rule, int rule_number, u_int32_t *output_pos) +{ + if (this->byte_pos + sizeof(u_int32_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + if (this->bit_pos) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + /* caller interested in result ? */ + if (output_pos != NULL) + { + *output_pos = ntohl(*((u_int32_t*)this->byte_pos)); + + this->logger->log(this->logger, RAW, " => %d", *output_pos); + } + this->byte_pos += 4; + + + return SUCCESS; +} + +static status_t parse_uint64(private_parser_t *this, encoding_rule_t *rule, int rule_number, u_int32_t *output_pos) +{ + if (this->byte_pos + 2 * sizeof(u_int32_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + if (this->bit_pos) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->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)); + + this->logger->log_bytes(this->logger, RAW, " =>", (void*)output_pos, 8); + } + this->byte_pos += 8; + + + + return SUCCESS; +} + + +static status_t parse_bit(private_parser_t *this, encoding_rule_t *rule, int rule_number, bool *output_pos) +{ + if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + /* caller interested in result ? */ + if (output_pos != NULL) + { + 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 */ + *output_pos = TRUE; + } + + this->logger->log(this->logger, RAW, " => %d", *output_pos); + } + this->bit_pos = (this->bit_pos + 1) % 8; + if (this->bit_pos == 0) + { + this->byte_pos++; + } + + + return SUCCESS; +} + +static status_t parse_list(private_parser_t *this, encoding_rule_t *rule, int rule_number, linked_list_t **output_pos, payload_type_t payload_type, size_t length) +{ + linked_list_t * list = *output_pos; + + if (length < 0) + { + this->logger->log(this->logger, ERROR, " invalid length for rule %d %s", + rule_number, mapping_find(encoding_type_t_mappings, rule->type)); + return PARSE_ERROR; + } + + if (this->bit_pos) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + + while (length > 0) + { + u_int8_t *pos_before = this->byte_pos; + payload_t *payload; + status_t status; + status = this->public.parse_payload((parser_t*)this, payload_type, &payload); + if (status != SUCCESS) + { + return status; + } + list->insert_last(list, payload); + length -= this->byte_pos - pos_before; + } + *output_pos = list; + return SUCCESS; +} + + +static status_t parse_chunk(private_parser_t *this, encoding_rule_t *rule, int rule_number, chunk_t *output_pos, size_t length) +{ + if (this->byte_pos + length > this->input_roof) + { + this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s, SPI_LENGTH: %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), length); + return PARSE_ERROR; + } + if (this->bit_pos) + { + this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", + rule_number, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); + return PARSE_ERROR; + } + if (output_pos != NULL) + { + output_pos->len = length; + output_pos->ptr = allocator_alloc(length); + if (output_pos->ptr == NULL) + { + return OUT_OF_RES; + } + memcpy(output_pos->ptr, this->byte_pos, length); + + this->logger->log_bytes(this->logger, RAW, " =>", output_pos->ptr, length); + } + this->byte_pos += length; + + return SUCCESS; +} /** * implementation of parser_context_t.parse_payload */ static status_t parse_payload(private_parser_t *this, payload_type_t payload_type, payload_t **payload) { - - this->logger->log(this->logger, CONTROL, "parsing %s payload", mapping_find(payload_type_t_mappings, payload_type)); - - /* find payload in null terminated list*/ - payload_t *pld; void *output; + size_t rule_count, payload_length, spi_size, attribute_length; + bool attribute_format; int current; encoding_rule_t *rule; - size_t rule_count; + + this->logger->log(this->logger, CONTROL, "parsing %s payload", mapping_find(payload_type_t_mappings, payload_type)); /* ok, do the parsing */ pld = payload_create(payload_type); @@ -109,236 +404,195 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ { case U_INT_4: { - u_int8_t *output_pos = output + rule->offset; - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + if (this->parse_uint4(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - switch (this->bit_pos) - { - case 0: - *output_pos = *(this->byte_pos) >> 4; - this->bit_pos = 4; - break; - case 4: - *output_pos = *(this->byte_pos) & 0x0F; - this->bit_pos = 0; - this->byte_pos++; - break; - default: - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); - pld->destroy(pld); - return PARSE_ERROR; - } break; } case U_INT_8: { - u_int8_t *output_pos = output + rule->offset; - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + if (this->parse_uint8(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - if (this->bit_pos) - { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); - pld->destroy(pld); - return PARSE_ERROR; - } - - *output_pos = *(this->byte_pos); - this->byte_pos++; break; } case U_INT_16: { - u_int16_t *output_pos = output + rule->offset; - if (this->byte_pos + sizeof(u_int16_t) > this->input_roof) + if (this->parse_uint16(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - if (this->bit_pos) + break; + } + case U_INT_32: + { + if (this->parse_uint32(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); pld->destroy(pld); return PARSE_ERROR; } - if ((int)this->byte_pos % 2) + break; + } + case U_INT_64: + { + if (this->parse_uint64(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos odd bytepos", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - *output_pos = ntohs(*((u_int16_t*)this->byte_pos)); - this->byte_pos += 2; - break; + break; } - case U_INT_32: + case RESERVED_BIT: { - u_int32_t *output_pos = output + rule->offset; - if (this->byte_pos + sizeof(u_int32_t) > this->input_roof) + if (this->parse_bit(this, rule, current, NULL) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - if (this->bit_pos) + break; + } + case RESERVED_BYTE: + { + if (this->parse_uint8(this, rule, current, NULL) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); pld->destroy(pld); return PARSE_ERROR; } - if ((int)this->byte_pos % 4) + break; + } + case FLAG: + { + if (this->parse_bit(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on unaligned bytepos", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - *output_pos = ntohl(*((u_int32_t*)this->byte_pos)); - this->byte_pos += 4; - break; + break; } - case U_INT_64: + case PAYLOAD_LENGTH: { - u_int32_t *output_pos = output + rule->offset; - if (this->byte_pos + 2 * sizeof(u_int32_t) > this->input_roof) + if (this->parse_uint16(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - if (this->bit_pos) + payload_length = *(u_int16_t*)(output + rule->offset); + break; + } + case HEADER_LENGTH: + { + if (this->parse_uint32(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); pld->destroy(pld); return PARSE_ERROR; } - if ((int)this->byte_pos % 8) + break; + } + case SPI_SIZE: + { + if (this->parse_uint8(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on unaligned bytepos", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - /* assuming little endian host order */ - *(output_pos + 1) = ntohl(*((u_int32_t*)this->byte_pos)); - this->byte_pos += 4; - *output_pos = ntohl(*((u_int32_t*)this->byte_pos)); - this->byte_pos += 4; - - break; + spi_size = *(u_int8_t*)(output + rule->offset); + break; } - case RESERVED_BIT: + case SPI: { - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + if (this->parse_chunk(this, rule, current, output + rule->offset, spi_size) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - this->bit_pos = (this->bit_pos + 1) % 8; - if (this->bit_pos == 0) - { - this->byte_pos++; - } - break; + break; } - case RESERVED_BYTE: + case PROPOSALS: { - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + size_t proposals_length = payload_length - 4; + if (this->parse_list(this, rule, current, output + rule->offset, PROPOSAL_SUBSTRUCTURE, proposals_length) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - if (this->bit_pos) + //TODO check if next_payloads are correct? + break; + } + case TRANSFORMS: + { + size_t transforms_length = payload_length - spi_size - 8; + if (this->parse_list(this, rule, current, output + rule->offset, TRANSFORM_SUBSTRUCTURE, transforms_length) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); pld->destroy(pld); return PARSE_ERROR; } - this->byte_pos++; - break; + //TODO check if we have the desired transforms count + break; } - case FLAG: + case TRANSFORM_ATTRIBUTES: { - bool *output_pos = output + rule->offset; - u_int8_t mask; - if (this->byte_pos + sizeof(u_int8_t) > this->input_roof) + size_t transform_a_length = payload_length - 8; + if (this->parse_list(this, rule, current, output + rule->offset, TRANSFORM_ATTRIBUTE, transform_a_length) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - mask = 0x01 << (7 - this->bit_pos); - *output_pos = *this->byte_pos & mask; - - if (*output_pos) - { - /* set to a "clean", comparable true */ - *output_pos = TRUE; - } - this->bit_pos = (this->bit_pos + 1) % 8; - if (this->bit_pos == 0) + break; + } + case ATTRIBUTE_FORMAT: + { + if (this->parse_bit(this, rule, current, output + rule->offset) != SUCCESS) { - this->byte_pos++; + pld->destroy(pld); + return PARSE_ERROR; } + attribute_format = *(bool*)(output + rule->offset); break; } - case HEADER_LENGTH: + case ATTRIBUTE_TYPE: { - u_int32_t *output_pos = output + rule->offset; - if (this->byte_pos + sizeof(u_int32_t) > this->input_roof) + if (this->parse_uint15(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " not enough input to parse rule %d %s", - current, mapping_find(encoding_type_t_mappings, rule->type)); pld->destroy(pld); return PARSE_ERROR; } - if (this->bit_pos) + attribute_format = *(bool*)(output + rule->offset); + break; + } + case ATTRIBUTE_LENGTH_OR_VALUE: + { + this->logger->log_bytes(this->logger, RAW, "ATTRIBUTE_LENGTH_OR_VALUE", this->byte_pos, 2); + + if (this->parse_uint16(this, rule, current, output + rule->offset) != SUCCESS) { - this->logger->log(this->logger, ERROR, " found rule %d %s on bitpos %d", - current, mapping_find(encoding_type_t_mappings, rule->type), this->bit_pos); pld->destroy(pld); return PARSE_ERROR; } - if ((int)this->byte_pos % 4) + attribute_length = *(u_int16_t*)(output + rule->offset); + this->logger->log_bytes(this->logger, RAW, "ATTRIBUTE_LENGTH_OR_VALUE", output + rule->offset, 2); + + break; + } + case ATTRIBUTE_VALUE: + { + if (attribute_format == FALSE) { - this->logger->log(this->logger, ERROR, " found rule %d %s on unaligned bytepos", - current, mapping_find(encoding_type_t_mappings, rule->type)); - pld->destroy(pld); - return PARSE_ERROR; + if (this->parse_chunk(this, rule, current, output + rule->offset, attribute_length) != SUCCESS) + { + pld->destroy(pld); + return PARSE_ERROR; + } } - *output_pos = ntohl(*((u_int32_t*)this->byte_pos)); - this->byte_pos += 4; - break; - + break; } default: { - this->logger->log(this->logger, ERROR, " no rule to parse rule %d %s (%d)", current, mapping_find(payload_type_t_mappings, payload_type), payload_type); + this->logger->log(this->logger, ERROR, " no rule to parse rule %d %s (%d)", current, mapping_find(encoding_type_t_mappings, rule->type), rule->type); pld->destroy(pld); return PARSE_ERROR; } @@ -348,6 +602,8 @@ static status_t parse_payload(private_parser_t *this, payload_type_t payload_typ } *payload = pld; + + this->logger->log(this->logger, CONTROL, "parsing %s successful", mapping_find(payload_type_t_mappings, payload_type)); return SUCCESS; } @@ -375,7 +631,7 @@ parser_t *parser_create(chunk_t data) } this->logger = global_logger_manager->create_logger(global_logger_manager, PARSER, NULL); - this->logger->enable_level(this->logger, ALL); + this->logger->enable_level(this->logger, CONTROL|CONTROL_MORE|ERROR|RAW); if (this->logger == NULL) @@ -387,6 +643,17 @@ parser_t *parser_create(chunk_t data) this->public.parse_payload = (status_t(*)(parser_t*,payload_type_t,payload_t**)) parse_payload; this->public.destroy = (status_t(*)(parser_t*)) destroy; + + this->parse_uint4 = parse_uint4; + this->parse_uint8 = parse_uint8; + this->parse_uint15 = parse_uint15; + this->parse_uint16 = parse_uint16; + this->parse_uint32 = parse_uint32; + this->parse_uint64 = parse_uint64; + this->parse_bit = parse_bit; + this->parse_list = parse_list; + this->parse_chunk = parse_chunk; + this->input = data.ptr; this->byte_pos = data.ptr; diff --git a/Source/charon/payloads/encodings.h b/Source/charon/payloads/encodings.h index e085454f8..f365a6ebb 100644 --- a/Source/charon/payloads/encodings.h +++ b/Source/charon/payloads/encodings.h @@ -174,11 +174,11 @@ enum encoding_type_e{ * * When generating it must be changed from host to network order. * The value is read from the associated data struct. - * The current write position is moved 32 bit forward afterwards. + * The current write position is moved 8 bit forward afterwards. * * When parsing it must be changed from network to host order. * The value is written to the associated data struct. - * The current read pointer is moved 32 bit forward afterwards. + * The current read pointer is moved 8 bit forward afterwards. */ SPI_SIZE, /** diff --git a/Source/charon/payloads/payload.c b/Source/charon/payloads/payload.c index bbb1a5d06..cf7a75b4f 100644 --- a/Source/charon/payloads/payload.c +++ b/Source/charon/payloads/payload.c @@ -25,6 +25,7 @@ #include "payload.h" #include "ike_header.h" +#include "sa_payload.h" @@ -67,6 +68,14 @@ payload_t *payload_create(payload_type_t type) { case HEADER: return (payload_t*)ike_header_create(); + case SECURITY_ASSOCIATION: + return (payload_t*)sa_payload_create(); + case PROPOSAL_SUBSTRUCTURE: + return (payload_t*)proposal_substructure_create(); + case TRANSFORM_SUBSTRUCTURE: + return (payload_t*)transform_substructure_create(); + case TRANSFORM_ATTRIBUTE: + return (payload_t*)transform_attribute_create(); default: return NULL; } diff --git a/Source/charon/testcases/parser_test.c b/Source/charon/testcases/parser_test.c index 63034eb75..72587c406 100644 --- a/Source/charon/testcases/parser_test.c +++ b/Source/charon/testcases/parser_test.c @@ -29,6 +29,7 @@ #include "../utils/logger_manager.h" #include "../payloads/encodings.h" #include "../payloads/ike_header.h" +#include "../payloads/sa_payload.h" extern logger_manager_t *global_logger_manager; @@ -79,9 +80,49 @@ void test_parser_with_header_payload(tester_t *tester) tester->assert_true(tester,(ike_header->flags.response == TRUE),"parsed flags.response value"); tester->assert_true(tester,(ike_header->message_id == 7),"parsed message_id value"); tester->assert_true(tester,(ike_header->length == 8),"parsed length value"); + + ike_header->destroy(ike_header); +} + +/* + * Described in Header + */ +void test_parser_with_sa_payload(tester_t *tester) +{ + parser_t *parser; + sa_payload_t *sa_payload; + status_t status; + chunk_t sa_chunk; + + u_int8_t sa_bytes[] = { + 0x00,0x80,0x00,0x24, /* payload header*/ + 0x00,0x00,0x00,0x20, /* a proposal */ + 0x01,0x02,0x04,0x05, + 0x01,0x02,0x03,0x04, /* spi */ + 0x00,0x00,0x00,0x14, /* transform */ + 0x02,0x00,0x00,0x03, + 0x80,0x01,0x00,0x05, /* attribute without length */ + 0x00,0x01,0x00,0x04, /* attribute with lenngth */ + 0x01,0x02,0x03,0x04 + + + }; + sa_chunk.ptr = sa_bytes; + sa_chunk.len = sizeof(sa_bytes); + + parser = parser_create(sa_chunk); + tester->assert_true(tester,(parser != NULL), "parser create check"); + status = parser->parse_payload(parser, SECURITY_ASSOCIATION, (payload_t**)&sa_payload); + tester->assert_true(tester,(status == SUCCESS),"parse_payload call check"); + tester->assert_true(tester,(parser->destroy(parser) == SUCCESS), "parser destroy call check"); + if (status != SUCCESS) + { + return; + } - ike_header->destroy(ike_header); + + sa_payload->destroy(sa_payload); } diff --git a/Source/charon/testcases/parser_test.h b/Source/charon/testcases/parser_test.h index dc952ef87..0d9e70d65 100644 --- a/Source/charon/testcases/parser_test.h +++ b/Source/charon/testcases/parser_test.h @@ -27,4 +27,8 @@ void test_parser_with_header_payload(tester_t *tester); +void test_parser_with_sa_payload(tester_t *tester); + + + #endif /*PARSER_TEST_H_*/ diff --git a/Source/charon/testcases/testcases.c b/Source/charon/testcases/testcases.c index 10f036d7e..c649bfaf3 100644 --- a/Source/charon/testcases/testcases.c +++ b/Source/charon/testcases/testcases.c @@ -43,7 +43,7 @@ #include "ike_sa_test.h" #include "ike_sa_manager_test.h" #include "generator_test.h" -//#include "parser_test.h" +#include "parser_test.h" #include "packet_test.h" @@ -131,6 +131,7 @@ test_t generator_test1 = {test_generator_with_header_payload,"Generator: header test_t generator_test2 = {test_generator_with_transform_attribute,"Generator: transform attribute"}; /** + * Parser test for ike header * Test 3 for generator_t */ test_t generator_test3 = {test_generator_with_transform_substructure,"Generator: transform substructure"}; @@ -139,7 +140,14 @@ test_t generator_test3 = {test_generator_with_transform_substructure,"Generator: /** * Test 2 for generator_t */ -//test_t parser_test = {test_parser_with_header_payload, "Parser: header payload"}; + +test_t parser_test_header = {test_parser_with_header_payload, "Parser: header payload"}; + + +/** + * Parser test for ike security association + */ +test_t parser_test_sa_payload = {test_parser_with_sa_payload, "Parser: sa payload"}; /** @@ -194,8 +202,9 @@ logger_manager_t *global_logger_manager; &ike_sa_test, &generator_test1, &generator_test2, + &parser_test_header, + &parser_test_sa_payload, &generator_test3, -// &parser_test, &ike_sa_manager_test, &packet_test, NULL @@ -212,8 +221,8 @@ logger_manager_t *global_logger_manager; tester_t *tester = tester_create(test_output, FALSE); - //tester->perform_tests(tester,all_tests); - tester->perform_test(tester,&generator_test3); + tester->perform_tests(tester,all_tests); +// tester->perform_test(tester,&parser_test_sa_payload); tester->destroy(tester); |