diff options
Diffstat (limited to 'Source/charon/generator.c')
-rw-r--r-- | Source/charon/generator.c | 538 |
1 files changed, 230 insertions, 308 deletions
diff --git a/Source/charon/generator.c b/Source/charon/generator.c index 1b1b31efa..997c556b9 100644 --- a/Source/charon/generator.c +++ b/Source/charon/generator.c @@ -30,54 +30,73 @@ #include "types.h" #include "utils/allocator.h" +#include "utils/logger_manager.h" #include "payloads/payload.h" -typedef struct private_generator_context_s private_generator_context_t; +extern logger_manager_t *global_logger_manager; -struct private_generator_context_s{ - /** - * Public part of the context - */ - generator_context_t public; +/** + * Private part of a generator_t object + */ +typedef struct private_generator_s private_generator_t; +struct private_generator_s { /** - * Buffer used to generate the data into. + * Public part of a generator_t object */ - u_int8_t *buffer; + generator_t public; + + /* private functions and fields */ - /** - * Current write position in buffer (one byte aligned). - */ - u_int8_t *out_position; /** - * Position of last byte in buffer. + * Generates a U_INT-Field type + * + * @param this private_generator_t object + * @param int_type type of U_INT field (U_INT_4, U_INT_8, etc.) + * @param offset offset of value in data struct + * @param generator_contexts generator_contexts_t object where the context is written or read from + * @return - SUCCESS if succeeded + * - OUT_OF_RES if out of ressources */ - u_int8_t *roof_position; + status_t (*generate_u_int_type) (private_generator_t *this,encoding_type_t int_type,u_int32_t offset); /** - * Current bit writing to in current byte (between 0 and 7). + * Generates a RESERVED BIT field or a RESERVED BYTE field + * + * @param this private_generator_t object + * @param generator_contexts generator_contexts_t object where the context is written or read from + * @param bits number of bits to generate + * @return - SUCCESS if succeeded + * - OUT_OF_RES if out of ressources + * - FAILED if bit count not supported */ - size_t current_bit; - + status_t (*generate_reserved_field) (private_generator_t *this,int bits); + /** - * Associated data struct to read informations from. + * Generates a FLAG field + * + * @param this private_generator_t object + * @param generator_contexts generator_contexts_t object where the context is written or read from + * @param offset offset of flag value in data struct + * @return - SUCCESS if succeeded + * - OUT_OF_RES if out of ressources */ - void * data_struct; - + status_t (*generate_flag) (private_generator_t *this,u_int32_t offset); + /** * Writes the current buffer content into a chunk_t * * Memory of specific chunk_t gets allocated. * - * @param generator_infos_t calling generator_infos_t object + * @param this calling private_generator_t object * @param data pointer of chunk_t to write to * @return * - SUCCESSFUL if succeeded * - OUT_OF_RES otherwise */ - status_t (*write_chunk) (private_generator_context_t *this,chunk_t *data); + status_t (*write_chunk) (private_generator_t *this,chunk_t *data); /** @@ -86,13 +105,13 @@ struct private_generator_context_s{ * If buffer is to small to hold the specific amount of bits it * is increased using reallocation function of allocator. * - * @param generator_infos_t calling generator_infos_t object + * @param this calling private_generator_t object * @param bits number of bits to make available in buffer * @return * - SUCCESSFUL if succeeded * - OUT_OF_RES otherwise */ - status_t (*make_space_available) (private_generator_context_t *this,size_t bits); + status_t (*make_space_available) (private_generator_t *this,size_t bits); /** * Writes a specific amount of byte into the buffer. @@ -100,219 +119,52 @@ struct private_generator_context_s{ * If buffer is to small to hold the specific amount of bytes it * is increased. * - * @param generator_infos_t calling generator_infos_t object + * @param this calling private_generator_t object * @param bytes pointer to bytes to write * @param number_of_bytes number of bytes to write into buffer * @return * - SUCCESSFUL if succeeded * - OUT_OF_RES otherwise */ - status_t (*write_bytes_to_buffer) (private_generator_context_t *this,void * bytes,size_t number_of_bytes); - + status_t (*write_bytes_to_buffer) (private_generator_t *this,void * bytes,size_t number_of_bytes); + -}; - -/** - * Implements generator_infos_t's increase_buffer function. - * See #generator_infos_s.increase_buffer. - */ -static status_t generator_context_make_space_available (private_generator_context_t *this, size_t bits) -{ - while ((((this->roof_position - this->out_position) * 8) - this->current_bit) < bits) - { - size_t old_buffer_size = ((this->roof_position) - ( this->buffer)); - size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE; - size_t out_position_offset = ((this->out_position) - (this->buffer)); - u_int8_t *new_buffer; - - new_buffer = allocator_realloc(this->buffer,new_buffer_size); - if (new_buffer == NULL) - { - return OUT_OF_RES; - } - - this->buffer = new_buffer; - - this->out_position = (this->buffer + out_position_offset); - this->roof_position = (this->buffer + new_buffer_size); - - } - - return SUCCESS; -} - -/** - * Implements generator_infos_t's write_bytes_to_buffer function. - * See #generator_infos_s.write_bytes_to_buffer. - */ -static status_t generator_context_write_bytes_to_buffer (private_generator_context_t *this,void * bytes,size_t number_of_bytes) -{ - u_int8_t *read_position = (u_int8_t *) bytes; - int i; - status_t status; - - status = this->make_space_available(this,number_of_bytes * 8); - - if (status != SUCCESS) - { - return status; - } - - for (i = 0; i < number_of_bytes; i++) - { - *(this->out_position) = *(read_position); - read_position++; - this->out_position++; - } - return status; -} - -/** - * Implements generator_infos_t's write_chunk function. - * See #generator_infos_s.write_chunk. - */ -static status_t generator_context_write_chunk (private_generator_context_t *this,chunk_t *data) -{ - size_t data_length = this->out_position - this->buffer; - - if (this->current_bit > 0) - data_length++; - data->ptr = allocator_alloc(data_length); - if (data->ptr == NULL) - { - data->len = 0; - return OUT_OF_RES; - } - memcpy(data->ptr,this->buffer,data_length); - data->len = data_length; - return SUCCESS; -} - - -/** - * Implements generator_infos_t's destroy function. - * See #generator_infos_s.destroy. - */ -static status_t generator_context_destroy (private_generator_context_t *this) -{ - allocator_free(this->buffer); - allocator_free(this); - return SUCCESS; -} - -/* - * Described in header - */ -static generator_context_t * generator_context_create(generator_t *generator) -{ - private_generator_context_t *this = allocator_alloc_thing(private_generator_context_t); - - if (this == NULL) - { - return NULL; - } - - /* object methods */ - this->public.destroy = (status_t (*) (generator_context_t *this))generator_context_destroy; - this->make_space_available = generator_context_make_space_available; - this->write_chunk = generator_context_write_chunk; - this->write_bytes_to_buffer = generator_context_write_bytes_to_buffer; - - /* allocate memory for buffer */ - this->buffer = allocator_alloc(GENERATOR_DATA_BUFFER_SIZE); - if (this->buffer == NULL) - { - allocator_free(this); - return NULL; - } - - /* set private data */ - this->out_position = this->buffer; - this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE; - this->data_struct = NULL; - this->current_bit = 0; - return &(this->public); -} - - -/** - * Private part of a generator_t object - */ -typedef struct private_generator_s private_generator_t; - -struct private_generator_s { /** - * Public part of a generator_t object + * Buffer used to generate the data into. */ - generator_t public; - - /* private functions and fields */ + u_int8_t *buffer; /** - * Generates a chunk_t with specific encoding rules. - * - * Iems are bytewhise written. - * - * @param this private_generator_t object - * @param data_struct data_struct to read data from - * @param encoding_rules pointer to first encoding_rule - * of encoding rules array - * @param encoding_rules_count number of encoding rules - * in encoding rules array - * @param data pointer to chunk_t where to write the data in - * - * @return - SUCCESS if succeeded - * - OUT_OF_RES if out of ressources + * Current write position in buffer (one byte aligned). */ - status_t (*generate) (private_generator_t *this,void * data_struct,encoding_rule_t *encoding_rules, size_t encoding_rules_count, private_generator_context_t *generator_context); + u_int8_t *out_position; /** - * Generates a U_INT-Field type - * - * @param this private_generator_t object - * @param int_type type of U_INT field (U_INT_4, U_INT_8, etc.) - * @param offset offset of value in data struct - * @param generator_contexts generator_contexts_t object where the context is written or read from - * @return - SUCCESS if succeeded - * - OUT_OF_RES if out of ressources + * Position of last byte in buffer. */ - status_t (*generate_u_int_type) (private_generator_t *this,encoding_type_t int_type,u_int32_t offset, private_generator_context_t *generator_context); + u_int8_t *roof_position; /** - * Generates a RESERVED BIT field or a RESERVED BYTE field - * - * @param this private_generator_t object - * @param generator_contexts generator_contexts_t object where the context is written or read from - * @param bits number of bits to generate - * @return - SUCCESS if succeeded - * - OUT_OF_RES if out of ressources - * - FAILED if bit count not supported + * Current bit writing to in current byte (between 0 and 7). */ - status_t (*generate_reserved_field) (private_generator_t *this,private_generator_context_t *generator_context,int bits); - + size_t current_bit; + /** - * Generates a FLAG field - * - * @param this private_generator_t object - * @param generator_contexts generator_contexts_t object where the context is written or read from - * @param offset offset of flag value in data struct - * @return - SUCCESS if succeeded - * - OUT_OF_RES if out of ressources + * Associated data struct to read informations from. */ - status_t (*generate_flag) (private_generator_t *this,private_generator_context_t *generator_context,u_int32_t offset); - + void * data_struct; + /** - * Pointer to the payload informations needed to automatic - * generate a specific payload type + * Associated Logger */ - payload_info_t **payload_infos; + logger_t *logger; }; /** * Implements private_generator_t's generate_u_int_type function. * See #private_generator_s.generate_u_int_type. */ -static status_t generate_u_int_type (private_generator_t *this,encoding_type_t int_type,u_int32_t offset,private_generator_context_t *generator_context) +static status_t generate_u_int_type (private_generator_t *this,encoding_type_t int_type,u_int32_t offset) { size_t number_of_bits = 0; status_t status; @@ -338,13 +190,13 @@ static status_t generate_u_int_type (private_generator_t *this,encoding_type_t i default: return FAILED; } - if (((number_of_bits % 8) == 0) && (generator_context->current_bit != 0)) + if (((number_of_bits % 8) == 0) && (this->current_bit != 0)) { /* current bit has to be zero for values greater then 4 bits */ return FAILED; } - status = generator_context->make_space_available(generator_context,number_of_bits); + status = this->make_space_available(this,number_of_bits); if (status != SUCCESS) { @@ -355,22 +207,22 @@ static status_t generate_u_int_type (private_generator_t *this,encoding_type_t i { case U_INT_4: { - if (generator_context->current_bit == 0) + if (this->current_bit == 0) { - u_int8_t high_val = *((u_int8_t *)(generator_context->data_struct + offset)) << 4; - u_int8_t low_val = *(generator_context->out_position) & 0x0F; + u_int8_t high_val = *((u_int8_t *)(this->data_struct + offset)) << 4; + u_int8_t low_val = *(this->out_position) & 0x0F; - *(generator_context->out_position) = high_val | low_val; + *(this->out_position) = high_val | low_val; /* write position is not changed, just bit position is moved */ - generator_context->current_bit = 4; + this->current_bit = 4; } - else if (generator_context->current_bit == 4) + else if (this->current_bit == 4) { - u_int high_val = *(generator_context->out_position) & 0xF0; - u_int low_val = *((u_int8_t *)(generator_context->data_struct + offset)) & 0x0F; - *(generator_context->out_position) = high_val | low_val; - generator_context->out_position++; - generator_context->current_bit = 0; + u_int high_val = *(this->out_position) & 0xF0; + u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F; + *(this->out_position) = high_val | low_val; + this->out_position++; + this->current_bit = 0; } else @@ -383,30 +235,30 @@ static status_t generate_u_int_type (private_generator_t *this,encoding_type_t i case U_INT_8: { - *generator_context->out_position = *((u_int8_t *)(generator_context->data_struct + offset)); - generator_context->out_position++; + *this->out_position = *((u_int8_t *)(this->data_struct + offset)); + this->out_position++; break; } case U_INT_16: { - u_int16_t int16_val = htons(*((u_int16_t*)(generator_context->data_struct + offset))); - generator_context->write_bytes_to_buffer(generator_context,&int16_val,sizeof(u_int16_t)); + u_int16_t int16_val = htons(*((u_int16_t*)(this->data_struct + offset))); + this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t)); break; } case U_INT_32: { - u_int32_t int32_val = htonl(*((u_int32_t*)(generator_context->data_struct + offset))); - generator_context->write_bytes_to_buffer(generator_context,&int32_val,sizeof(u_int32_t)); + u_int32_t int32_val = htonl(*((u_int32_t*)(this->data_struct + offset))); + this->write_bytes_to_buffer(this,&int32_val,sizeof(u_int32_t)); break; } case U_INT_64: { - u_int32_t int32_val_low = htonl(*((u_int32_t*)(generator_context->data_struct + offset))); - u_int32_t int32_val_high = htonl(*((u_int32_t*)(generator_context->data_struct + offset) + 1)); - generator_context->write_bytes_to_buffer(generator_context,&int32_val_high,sizeof(u_int32_t)); - generator_context->write_bytes_to_buffer(generator_context,&int32_val_low,sizeof(u_int32_t)); + u_int32_t int32_val_low = htonl(*((u_int32_t*)(this->data_struct + offset))); + u_int32_t int32_val_high = htonl(*((u_int32_t*)(this->data_struct + offset) + 1)); + this->write_bytes_to_buffer(this,&int32_val_high,sizeof(u_int32_t)); + this->write_bytes_to_buffer(this,&int32_val_low,sizeof(u_int32_t)); break; } @@ -418,7 +270,11 @@ static status_t generate_u_int_type (private_generator_t *this,encoding_type_t i return SUCCESS; } -static status_t generate_reserved_field (private_generator_t *this,private_generator_context_t *generator_context,int bits) +/** + * Implements private_generator_t's generate_reserved_field function. + * See #private_generator_s.generate_reserved_field. + */ +static status_t generate_reserved_field (private_generator_t *this,int bits) { status_t status; @@ -426,7 +282,7 @@ static status_t generate_reserved_field (private_generator_t *this,private_gener { return FAILED; } - status = generator_context->make_space_available(generator_context,bits); + status = this->make_space_available(this,bits); if (status != SUCCESS) { return status; @@ -434,25 +290,25 @@ static status_t generate_reserved_field (private_generator_t *this,private_gener if (bits == 1) { - u_int8_t reserved_bit = ~(1 << (7 - generator_context->current_bit)); + u_int8_t reserved_bit = ~(1 << (7 - this->current_bit)); - *(generator_context->out_position) = *(generator_context->out_position) & reserved_bit; - generator_context->current_bit++; - if (generator_context->current_bit >= 8) + *(this->out_position) = *(this->out_position) & reserved_bit; + this->current_bit++; + if (this->current_bit >= 8) { - generator_context->current_bit = generator_context->current_bit % 8; - generator_context->out_position++; + this->current_bit = this->current_bit % 8; + this->out_position++; } } else { /* one byte */ - if (generator_context->current_bit > 0) + if (this->current_bit > 0) { return FAILED; } - *(generator_context->out_position) = 0x00; - generator_context->out_position++; + *(this->out_position) = 0x00; + this->out_position++; } return SUCCESS; @@ -460,47 +316,134 @@ static status_t generate_reserved_field (private_generator_t *this,private_gener } -static status_t generate_flag (private_generator_t *this,private_generator_context_t *generator_context,u_int32_t offset) +/** + * Implements private_generator_t's generate_flag function. + * See #private_generator_s.generate_flag. + */ +static status_t generate_flag (private_generator_t *this,u_int32_t offset) { status_t status; - u_int8_t flag_value = (*((bool *) (generator_context->data_struct + offset))) ? 1 : 0; - u_int8_t flag = (flag_value << (7 - generator_context->current_bit)); + u_int8_t flag_value = (*((bool *) (this->data_struct + offset))) ? 1 : 0; + u_int8_t flag = (flag_value << (7 - this->current_bit)); - status = generator_context->make_space_available(generator_context,1); + status = this->make_space_available(this,1); if (status != SUCCESS) { return status; } - *(generator_context->out_position) = *(generator_context->out_position) | flag; + *(this->out_position) = *(this->out_position) | flag; - generator_context->current_bit++; - if (generator_context->current_bit >= 8) + this->current_bit++; + if (this->current_bit >= 8) + { + this->current_bit = this->current_bit % 8; + this->out_position++; + } + return SUCCESS; +} + +/** + * Implements private_generator_t's generator_context_make_space_available function. + * See #private_generator_s.generator_context_make_space_available. + */ +static status_t make_space_available (private_generator_t *this, size_t bits) +{ + while ((((this->roof_position - this->out_position) * 8) - this->current_bit) < bits) { - generator_context->current_bit = generator_context->current_bit % 8; - generator_context->out_position++; + size_t old_buffer_size = ((this->roof_position) - ( this->buffer)); + size_t new_buffer_size = old_buffer_size + GENERATOR_DATA_BUFFER_INCREASE_VALUE; + size_t out_position_offset = ((this->out_position) - (this->buffer)); + u_int8_t *new_buffer; + + new_buffer = allocator_realloc(this->buffer,new_buffer_size); + if (new_buffer == NULL) + { + return OUT_OF_RES; + } + + this->buffer = new_buffer; + + this->out_position = (this->buffer + out_position_offset); + this->roof_position = (this->buffer + new_buffer_size); + } + return SUCCESS; } /** - * Implements private_generator_t's generate function. - * See #private_generator_s.generate. + * Implements private_generator_t's write_bytes_to_buffer function. + * See #private_generator_s.write_bytes_to_buffer. */ -static status_t generate (private_generator_t *this,void * data_struct,encoding_rule_t *encoding_rules, size_t encoding_rules_count, private_generator_context_t *generator_context) +static status_t write_bytes_to_buffer (private_generator_t *this,void * bytes,size_t number_of_bytes) { + u_int8_t *read_position = (u_int8_t *) bytes; int i; status_t status; - if (generator_context == NULL) + status = this->make_space_available(this,number_of_bytes * 8); + + if (status != SUCCESS) + { + return status; + } + + for (i = 0; i < number_of_bytes; i++) { + *(this->out_position) = *(read_position); + read_position++; + this->out_position++; + } + return status; +} + +/** + * Implements generator_t's write_chunk function. + * See #generator_s.write_chunk. + */ +static status_t write_to_chunk (private_generator_t *this,chunk_t *data) +{ + size_t data_length = this->out_position - this->buffer; + + if (this->current_bit > 0) + data_length++; + data->ptr = allocator_alloc(data_length); + if (data->ptr == NULL) + { + data->len = 0; return OUT_OF_RES; } + memcpy(data->ptr,this->buffer,data_length); + data->len = data_length; + return SUCCESS; +} + - for (i = 0; i < encoding_rules_count;i++) + +/** + * Implements generator_t's generate_payload function. + * See #generator_s.generate_payload. + */ +static status_t generate_payload (private_generator_t *this,payload_t *payload) +{ + int i; + status_t status; + this->data_struct = payload; + size_t rule_count; + encoding_rule_t *rules; + + + payload_type_t payload_type = payload->get_type(payload); + + this->logger->log(this->logger,CONTROL,"Start generating payload of type %s",mapping_find(payload_type_t_mappings,payload_type)); + + payload->get_encoding_rules(payload,&rules,&rule_count); + + for (i = 0; i < rule_count;i++) { status = SUCCESS; - switch (encoding_rules[i].type) + switch (rules[i].type) { /* all u int values are generated in generate_u_int_type */ case U_INT_4: @@ -508,79 +451,48 @@ static status_t generate (private_generator_t *this,void * data_struct,encoding_ case U_INT_16: case U_INT_32: case U_INT_64: - status = this->generate_u_int_type(this,encoding_rules[i].type,encoding_rules[i].offset,generator_context); + status = this->generate_u_int_type(this,rules[i].type,rules[i].offset); break; case RESERVED_BIT: { - status = this->generate_reserved_field(this,generator_context,1); + status = this->generate_reserved_field(this,1); break; } case RESERVED_BYTE: { - status = this->generate_reserved_field(this,generator_context,8); + status = this->generate_reserved_field(this,8); break; } case FLAG: { - status = this->generate_flag(this,generator_context,encoding_rules[i].offset); + status = this->generate_flag(this,rules[i].offset); break; } case LENGTH: /* length is generated like an U_INT_32 */ - status = this->generate_u_int_type(this,U_INT_32,encoding_rules[i].offset,generator_context); + status = this->generate_u_int_type(this,U_INT_32,rules[i].offset); break; case SPI_SIZE: /* currently not implemented */ default: break; } - if (status != SUCCESS) - { - generator_context->public.destroy(&(generator_context->public)); - return status; - } } -// infos->destroy(infos); return status; -} - -/** - * Implements generator_t's generate_payload function. - * See #generator_s.generate_payload. - */ -static status_t generate_payload (private_generator_t *this,payload_type_t payload_type,void * data_struct, generator_context_t *generator_context) -{ - int i; - private_generator_context_t *private_generator_context = (private_generator_context_t *) generator_context; - - private_generator_context->data_struct = data_struct; - - /* check every payload info for specific type */ - for (i = 0; this->payload_infos[i] != NULL; i++) - { - if (this->payload_infos[i]->payload_type == payload_type) - { - /* found payload informations, generating is done in private function generate() */ - return (this->generate(this, data_struct,this->payload_infos[i]->ecoding_rules,this->payload_infos[i]->encoding_rules_count,private_generator_context)); - } - } return NOT_SUPPORTED; } -status_t write_to_chunk (private_generator_t *this,private_generator_context_t *generator_context, chunk_t *data) -{ - return generator_context->write_chunk(generator_context,data); -} - /** * Implements generator_t's destroy function. * See #generator_s.destroy. */ static status_t destroy(private_generator_t *this) { + allocator_free(this->buffer); + global_logger_manager->destroy_logger(global_logger_manager,this->logger); allocator_free(this); return SUCCESS; } @@ -588,15 +500,10 @@ static status_t destroy(private_generator_t *this) /* * Described in header */ -generator_t * generator_create(payload_info_t ** payload_infos) +generator_t * generator_create() { private_generator_t *this; - if (payload_infos == NULL) - { - return NULL; - } - this = allocator_alloc_thing(private_generator_t); if (this == NULL) { @@ -604,18 +511,33 @@ generator_t * generator_create(payload_info_t ** payload_infos) } /* initiate public functions */ - this->public.create_context = (generator_context_t * (*) (generator_t *)) generator_context_create; - this->public.generate_payload = (status_t(*)(generator_t*, payload_type_t, void *, generator_context_t *)) generate_payload; + this->public.generate_payload = (status_t(*)(generator_t*, payload_t *)) generate_payload; this->public.destroy = (status_t(*)(generator_t*)) destroy; - this->public.write_to_chunk = (status_t (*) (generator_t *,generator_context_t *, chunk_t *)) write_to_chunk; + this->public.write_to_chunk = (status_t (*) (generator_t *,chunk_t *)) write_to_chunk; + + /* initiate private functions */ - this->generate = generate; +// this->generate = generate; this->generate_u_int_type = generate_u_int_type; this->generate_reserved_field = generate_reserved_field; this->generate_flag = generate_flag; + this->make_space_available = make_space_available; + this->write_bytes_to_buffer = write_bytes_to_buffer; - /* initiate private variables */ - this->payload_infos = payload_infos; + /* allocate memory for buffer */ + this->buffer = allocator_alloc(GENERATOR_DATA_BUFFER_SIZE); + if (this->buffer == NULL) + { + allocator_free(this); + return NULL; + } + + /* initiate private variables */ + this->out_position = this->buffer; + this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE; + this->data_struct = NULL; + this->current_bit = 0; + this->logger = global_logger_manager->create_logger(global_logger_manager,GENERATOR,NULL); return &(this->public); } |