From 110dc83a3c14ce4e86294257f5788429de068ef3 Mon Sep 17 00:00:00 2001 From: Jan Hutter Date: Thu, 10 Nov 2005 17:17:46 +0000 Subject: [PATCH] generator now has its generator_context which is used to generate more then one payload in sequence... --- Source/charon/generator.c | 219 +++++++++++++-------------- Source/charon/generator.h | 55 ++++++- Source/charon/message.c | 120 +++++++++++++++ Source/charon/message.h | 109 ++++++++++++- Source/charon/tests.c | 12 +- Source/charon/tests/generator_test.c | 25 ++- Source/charon/types.h | 3 +- 7 files changed, 417 insertions(+), 126 deletions(-) diff --git a/Source/charon/generator.c b/Source/charon/generator.c index d852246e7..4c28173ce 100644 --- a/Source/charon/generator.c +++ b/Source/charon/generator.c @@ -30,12 +30,13 @@ #include "generator.h" -/** - * Used for generator operations internaly to store a generator context. - */ -typedef struct generator_infos_s generator_infos_t; +typedef struct private_generator_context_s private_generator_context_t; -struct generator_infos_s { +struct private_generator_context_s{ + /** + * Public part of the context + */ + generator_context_t public; /** * Buffer used to generate the data into. @@ -63,12 +64,18 @@ struct generator_infos_s { void * data_struct; /** - * @brief Destroys a generator_infos_t object and its containing buffer + * Writes the current buffer content into a chunk_t + * + * Memory of specific chunk_t gets allocated. * - * @param generator_infos_t generator_infos_t object - * @return always SUCCESSFUL + * @param generator_infos_t calling generator_infos_t object + * @param data pointer of chunk_t to write to + * @return + * - SUCCESSFUL if succeeded + * - OUT_OF_RES otherwise */ - status_t (*destroy) (generator_infos_t *this); + status_t (*write_chunk) (private_generator_context_t *this,chunk_t *data); + /** * Makes sure enough space is available in buffer to store amount of bits. @@ -82,7 +89,7 @@ struct generator_infos_s { * - SUCCESSFUL if succeeded * - OUT_OF_RES otherwise */ - status_t (*make_space_available) (generator_infos_t *this,size_t bits); + status_t (*make_space_available) (private_generator_context_t *this,size_t bits); /** * Writes a specific amount of byte into the buffer. @@ -97,27 +104,16 @@ struct generator_infos_s { * - SUCCESSFUL if succeeded * - OUT_OF_RES otherwise */ - status_t (*write_bytes_to_buffer) (generator_infos_t *this,void * bytes,size_t number_of_bytes); + status_t (*write_bytes_to_buffer) (private_generator_context_t *this,void * bytes,size_t number_of_bytes); - /** - * 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 data pointer of chunk_t to write to - * @return - * - SUCCESSFUL if succeeded - * - OUT_OF_RES otherwise - */ - status_t (*write_chunk) (generator_infos_t *this,chunk_t *data); + }; /** * Implements generator_infos_t's increase_buffer function. * See #generator_infos_s.increase_buffer. */ -static status_t generator_info_make_space_available (generator_infos_t *this, size_t bits) +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) { @@ -146,7 +142,7 @@ static status_t generator_info_make_space_available (generator_infos_t *this, si * Implements generator_infos_t's write_bytes_to_buffer function. * See #generator_infos_s.write_bytes_to_buffer. */ -static status_t generator_info_write_bytes_to_buffer (generator_infos_t *this,void * bytes,size_t number_of_bytes) +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; @@ -172,9 +168,10 @@ static status_t generator_info_write_bytes_to_buffer (generator_infos_t *this,vo * Implements generator_infos_t's write_chunk function. * See #generator_infos_s.write_chunk. */ -static status_t generator_infos_write_chunk (generator_infos_t *this,chunk_t *data) +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); @@ -193,25 +190,19 @@ static status_t generator_infos_write_chunk (generator_infos_t *this,chunk_t *da * Implements generator_infos_t's destroy function. * See #generator_infos_s.destroy. */ -static status_t generator_infos_destroy (generator_infos_t *this) +static status_t generator_context_destroy (private_generator_context_t *this) { allocator_free(this->buffer); allocator_free(this); return SUCCESS; } -/** - * Creates a generator_infos_t object holding necessary informations - * for generating (buffer, data_struct, etc). - * - * @param data_struct data struct where the specific payload informations are stored - * @return - * - pointer to created generator_infos_t object - * - NULL if memory allocation failed +/* + * Described in header */ -generator_infos_t * generator_infos_create(void *data_struct) +static generator_context_t * generator_context_create(generator_t *generator) { - generator_infos_t *this = allocator_alloc_thing(generator_infos_t); + private_generator_context_t *this = allocator_alloc_thing(private_generator_context_t); if (this == NULL) { @@ -219,10 +210,10 @@ generator_infos_t * generator_infos_create(void *data_struct) } /* object methods */ - this->destroy = generator_infos_destroy; - this->make_space_available = generator_info_make_space_available; - this->write_chunk = generator_infos_write_chunk; - this->write_bytes_to_buffer = generator_info_write_bytes_to_buffer; + 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); @@ -235,13 +226,12 @@ generator_infos_t * generator_infos_create(void *data_struct) /* set private data */ this->out_position = this->buffer; this->roof_position = this->buffer + GENERATOR_DATA_BUFFER_SIZE; - this->data_struct = data_struct; + this->data_struct = NULL; this->current_bit = 0; - return (this); + return &(this->public); } - /** * Private part of a generator_t object */ @@ -271,7 +261,7 @@ struct private_generator_s { * @return - SUCCESS if succeeded * - OUT_OF_RES if out of ressources */ - status_t (*generate) (private_generator_t *this,void * data_struct,encoding_rule_t *encoding_rules, size_t encoding_rules_count, chunk_t *data); + 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); /** * Generates a U_INT-Field type @@ -279,34 +269,34 @@ struct private_generator_s { * @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_infos generator_infos_t object where the context is written or read from + * @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 */ - status_t (*generate_u_int_type) (private_generator_t *this,encoding_type_t int_type,u_int32_t offset, generator_infos_t *generator_infos); + 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); /** * Generates a RESERVED BIT field or a RESERVED BYTE field * * @param this private_generator_t object - * @param generator_infos generator_infos_t object where the context is written or read from + * @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 */ - status_t (*generate_reserved_field) (private_generator_t *this,generator_infos_t *generator_infos,int bits); + status_t (*generate_reserved_field) (private_generator_t *this,private_generator_context_t *generator_context,int bits); /** * Generates a FLAG field * * @param this private_generator_t object - * @param generator_infos generator_infos_t object where the context is written or read from + * @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 */ - status_t (*generate_flag) (private_generator_t *this,generator_infos_t *generator_infos,u_int32_t offset); + status_t (*generate_flag) (private_generator_t *this,private_generator_context_t *generator_context,u_int32_t offset); /** * Pointer to the payload informations needed to automatic @@ -319,7 +309,7 @@ struct private_generator_s { * 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,generator_infos_t *generator_infos) +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) { size_t number_of_bits = 0; status_t status; @@ -345,13 +335,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_infos->current_bit != 0)) + if (((number_of_bits % 8) == 0) && (generator_context->current_bit != 0)) { /* current bit has to be zero for values greater then 4 bits */ return FAILED; } - status = generator_infos->make_space_available(generator_infos,number_of_bits); + status = generator_context->make_space_available(generator_context,number_of_bits); if (status != SUCCESS) { @@ -362,22 +352,22 @@ static status_t generate_u_int_type (private_generator_t *this,encoding_type_t i { case U_INT_4: { - if (generator_infos->current_bit == 0) + if (generator_context->current_bit == 0) { - u_int8_t high_val = *((u_int8_t *)(generator_infos->data_struct + offset)) << 4; - u_int8_t low_val = *(generator_infos->out_position) & 0x0F; + u_int8_t high_val = *((u_int8_t *)(generator_context->data_struct + offset)) << 4; + u_int8_t low_val = *(generator_context->out_position) & 0x0F; - *(generator_infos->out_position) = high_val | low_val; + *(generator_context->out_position) = high_val | low_val; /* write position is not changed, just bit position is moved */ - generator_infos->current_bit = 4; + generator_context->current_bit = 4; } - else if (generator_infos->current_bit == 4) + else if (generator_context->current_bit == 4) { - u_int high_val = *(generator_infos->out_position) & 0xF0; - u_int low_val = *((u_int8_t *)(generator_infos->data_struct + offset)) & 0x0F; - *(generator_infos->out_position) = high_val | low_val; - generator_infos->out_position++; - generator_infos->current_bit = 0; + 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; } else @@ -390,30 +380,30 @@ static status_t generate_u_int_type (private_generator_t *this,encoding_type_t i case U_INT_8: { - *generator_infos->out_position = *((u_int8_t *)(generator_infos->data_struct + offset)); - generator_infos->out_position++; + *generator_context->out_position = *((u_int8_t *)(generator_context->data_struct + offset)); + generator_context->out_position++; break; } case U_INT_16: { - u_int16_t int16_val = htons(*((u_int16_t*)(generator_infos->data_struct + offset))); - generator_infos->write_bytes_to_buffer(generator_infos,&int16_val,sizeof(u_int16_t)); + 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)); break; } case U_INT_32: { - u_int32_t int32_val = htonl(*((u_int32_t*)(generator_infos->data_struct + offset))); - generator_infos->write_bytes_to_buffer(generator_infos,&int32_val,sizeof(u_int32_t)); + 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)); break; } case U_INT_64: { - u_int32_t int32_val_low = htonl(*((u_int32_t*)(generator_infos->data_struct + offset))); - u_int32_t int32_val_high = htonl(*((u_int32_t*)(generator_infos->data_struct + offset) + 1)); - generator_infos->write_bytes_to_buffer(generator_infos,&int32_val_high,sizeof(u_int32_t)); - generator_infos->write_bytes_to_buffer(generator_infos,&int32_val_low,sizeof(u_int32_t)); + 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)); break; } @@ -425,7 +415,7 @@ 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,generator_infos_t *generator_infos,int bits) +static status_t generate_reserved_field (private_generator_t *this,private_generator_context_t *generator_context,int bits) { status_t status; @@ -433,7 +423,7 @@ static status_t generate_reserved_field (private_generator_t *this,generator_inf { return FAILED; } - status = generator_infos->make_space_available(generator_infos,bits); + status = generator_context->make_space_available(generator_context,bits); if (status != SUCCESS) { return status; @@ -441,25 +431,25 @@ static status_t generate_reserved_field (private_generator_t *this,generator_inf if (bits == 1) { - u_int8_t reserved_bit = ~(1 << (7 - generator_infos->current_bit)); + u_int8_t reserved_bit = ~(1 << (7 - generator_context->current_bit)); - *(generator_infos->out_position) = *(generator_infos->out_position) & reserved_bit; - generator_infos->current_bit++; - if (generator_infos->current_bit >= 8) + *(generator_context->out_position) = *(generator_context->out_position) & reserved_bit; + generator_context->current_bit++; + if (generator_context->current_bit >= 8) { - generator_infos->current_bit = generator_infos->current_bit % 8; - generator_infos->out_position++; + generator_context->current_bit = generator_context->current_bit % 8; + generator_context->out_position++; } } else { /* one byte */ - if (generator_infos->current_bit > 0) + if (generator_context->current_bit > 0) { return FAILED; } - *(generator_infos->out_position) = 0x00; - generator_infos->out_position++; + *(generator_context->out_position) = 0x00; + generator_context->out_position++; } return SUCCESS; @@ -467,25 +457,25 @@ static status_t generate_reserved_field (private_generator_t *this,generator_inf } -static status_t generate_flag (private_generator_t *this,generator_infos_t *generator_infos,u_int32_t offset) +static status_t generate_flag (private_generator_t *this,private_generator_context_t *generator_context,u_int32_t offset) { status_t status; - u_int8_t flag_value = (*((bool *) (generator_infos->data_struct + offset))) ? 1 : 0; - u_int8_t flag = (flag_value << (7 - generator_infos->current_bit)); + u_int8_t flag_value = (*((bool *) (generator_context->data_struct + offset))) ? 1 : 0; + u_int8_t flag = (flag_value << (7 - generator_context->current_bit)); - status = generator_infos->make_space_available(generator_infos,1); + status = generator_context->make_space_available(generator_context,1); if (status != SUCCESS) { return status; } - *(generator_infos->out_position) = *(generator_infos->out_position) | flag; + *(generator_context->out_position) = *(generator_context->out_position) | flag; - generator_infos->current_bit++; - if (generator_infos->current_bit >= 8) + generator_context->current_bit++; + if (generator_context->current_bit >= 8) { - generator_infos->current_bit = generator_infos->current_bit % 8; - generator_infos->out_position++; + generator_context->current_bit = generator_context->current_bit % 8; + generator_context->out_position++; } return SUCCESS; } @@ -494,14 +484,12 @@ static status_t generate_flag (private_generator_t *this,generator_infos_t *gene * Implements private_generator_t's generate function. * See #private_generator_s.generate. */ -static status_t generate (private_generator_t *this,void * data_struct,encoding_rule_t *encoding_rules, size_t encoding_rules_count, chunk_t *data) +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) { int i; status_t status; - generator_infos_t *infos = generator_infos_create(data_struct); - - if (infos == NULL) + if (generator_context == NULL) { return OUT_OF_RES; } @@ -517,27 +505,27 @@ 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,infos); + status = this->generate_u_int_type(this,encoding_rules[i].type,encoding_rules[i].offset,generator_context); break; case RESERVED_BIT: { - status = this->generate_reserved_field(this,infos,1); + status = this->generate_reserved_field(this,generator_context,1); break; } case RESERVED_BYTE: { - status = this->generate_reserved_field(this,infos,8); + status = this->generate_reserved_field(this,generator_context,8); break; } case FLAG: { - status = this->generate_flag(this,infos,encoding_rules[i].offset); + status = this->generate_flag(this,generator_context,encoding_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,infos); + status = this->generate_u_int_type(this,U_INT_32,encoding_rules[i].offset,generator_context); break; case SPI_SIZE: /* currently not implemented */ @@ -546,13 +534,12 @@ static status_t generate (private_generator_t *this,void * data_struct,encoding_ } if (status != SUCCESS) { - infos->destroy(infos); + generator_context->public.destroy(&(generator_context->public)); return status; } } - status = infos->write_chunk(infos,data); - infos->destroy(infos); +// infos->destroy(infos); return status; } @@ -560,9 +547,13 @@ static status_t generate (private_generator_t *this,void * data_struct,encoding_ * 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, chunk_t *data) +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++) @@ -570,12 +561,17 @@ static status_t generate_payload (private_generator_t *this,payload_type_t paylo 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,data)); + 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. @@ -605,9 +601,10 @@ generator_t * generator_create(payload_info_t ** payload_infos) } /* initiate public functions */ - this->public.generate_payload = (status_t(*)(generator_t*, payload_type_t, void *, chunk_t *)) generate_payload; + 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.destroy = (status_t(*)(generator_t*)) destroy; - + this->public.write_to_chunk = (status_t (*) (generator_t *,generator_context_t *, chunk_t *)) write_to_chunk; /* initiate private functions */ this->generate = generate; this->generate_u_int_type = generate_u_int_type; diff --git a/Source/charon/generator.h b/Source/charon/generator.h index cfd47ae7a..cf643fc5f 100644 --- a/Source/charon/generator.h +++ b/Source/charon/generator.h @@ -37,33 +37,76 @@ */ #define GENERATOR_DATA_BUFFER_INCREASE_VALUE 1000 +/** + * Used for generator operations internaly to store a generator context. + */ +typedef struct generator_context_s generator_context_t; + +struct generator_context_s { + /** + * @brief Destroys a generator_infos_t object and its containing buffer + * + * @param generator_infos_t generator_infos_t object + * @return always SUCCESSFUL + */ + status_t (*destroy) (generator_context_t *this); +}; + + + /** *A generator_t object which generates payloads of specific type. */ typedef struct generator_s generator_t; struct generator_s { + + /** + * Creates a generator_context_t object holding necessary informations + * for generating (buffer, data_struct, etc). + * + * After using, this context has to get destroyed! + * + * @param data_struct data struct where the specific payload informations are stored + * @return + * - pointer to created generator_infos_t object + * - NULL if memory allocation failed + */ + generator_context_t * (*create_context) (generator_t *this); /** * @brief Generates a specific payload from given data struct. * * Remember: Header and substructures are also handled as payloads. * - * @param generator generator_t object - * @param payload_type payload type to generate using the given data struct - * @param[in] data_struct data struct where the needed data for generating are stored - * @param[out] output pointer to a chunk_t where the data are generated to + * @param this generator_t object + * @param payload_type payload type to generate using the given data struct + * @param[in] data_struct data struct where the needed data for generating are stored + * @param generator_context generator context to use when generating * @return * - SUCCESSFUL if succeeded * - NOT_SUPPORTED if payload_type is not supported * - OUT_OF_RES if out of ressources */ - status_t (*generate_payload) (generator_t *this,payload_type_t payload_type,void * data_struct, chunk_t *data); + status_t (*generate_payload) (generator_t *this,payload_type_t payload_type,void * data_struct,generator_context_t *generator_context); + + /** + * Writes all generated data of current context to a chunk + * + * @param this generator_t object + * @param generator_context generator context to use when generating + * * @param[out] data chunk to write the data to + * @return + * @return + * - SUCCESSFUL if succeeded + * - OUT_OF_RES otherwise + */ + status_t (*write_to_chunk) (generator_t *this,generator_context_t *generator_context, chunk_t *data); /** * @brief Destroys a generator_t object. * - * @param generator generator_t object + * @param this generator_t object * * @return always success */ diff --git a/Source/charon/message.c b/Source/charon/message.c index 96d553ece..8d2e836ee 100644 --- a/Source/charon/message.c +++ b/Source/charon/message.c @@ -26,6 +26,25 @@ #include "types.h" #include "message.h" #include "linked_list.h" +#include "encodings.h" + +/** + * Entry for a payload in the internal used linked list + * + */ +typedef struct payload_entry_s payload_entry_t; + +struct payload_entry_s{ + /** + * Type of payload + */ + payload_type_t payload_type; + /** + * Data struct holding the data of given payload + */ + void *data_struct; +}; + /** * Private data of an message_t object @@ -41,6 +60,21 @@ struct private_message_s { /* Private values */ + /** + * Assigned exchange type + */ + exchange_type_t exchange_type; + + /** + * TRUE if message is from original initiator, FALSE otherwise. + */ + bool original_initiator; + + /** + * TRUE if message is request. + * FALSE if message is reply. + */ + bool is_request; /** * Assigned UDP packet. @@ -55,6 +89,80 @@ struct private_message_s { linked_list_t *payloads; }; +/** + * Implements message_t's set_exchange_type function. + * See #message_s.set_exchange_type. + */ +static status_t set_exchange_type (private_message_t *this,exchange_type_t exchange_type) +{ + this->exchange_type = exchange_type; + return SUCCESS; +} + + +/** + * Implements message_t's get_exchange_type function. + * See #message_s.get_exchange_type. + */ +static exchange_type_t get_exchange_type (private_message_t *this) +{ + return this->exchange_type; +} + +/** + * Implements message_t's set_original_initiator function. + * See #message_s.set_original_initiator. + */ +static status_t set_original_initiator (private_message_t *this,bool original_initiator) +{ + this->original_initiator = original_initiator; + return SUCCESS; +} + +/** + * Implements message_t's get_original_initiator function. + * See #message_s.get_original_initiator. + */ +static exchange_type_t get_original_initiator (private_message_t *this) +{ + return this->original_initiator; +} + +/** + * Implements message_t's set_request function. + * See #message_s.set_request. + */ +static status_t set_request (private_message_t *this,bool request) +{ + this->is_request = request; + return SUCCESS; +} + +/** + * Implements message_t's get_request function. + * See #message_s.get_request. + */ +static exchange_type_t get_request (private_message_t *this) +{ + return this->is_request; +} + +/** + * Implements message_t's generate_packet function. + * See #message_s.generate_packet. + */ +static status_t generate_packet (private_message_t *this, packet_t **packet) +{ + if (this->exchange_type == NOT_SET) + { + return EXCHANGE_TYPE_NOT_SET; + } + + + + return SUCCESS; +} + /** * Implements message_t's destroy function. * See #message_s.destroy. @@ -82,7 +190,19 @@ message_t *message_create_from_packet(packet_t *packet) } /* public functions */ + this->public.set_exchange_type = (status_t(*)(message_t*, exchange_type_t))set_exchange_type; + this->public.get_exchange_type = (exchange_type_t(*)(message_t*))get_exchange_type; + this->public.set_original_initiator = (status_t(*)(message_t*, bool))set_original_initiator; + this->public.get_original_initiator = (bool(*)(message_t*))get_original_initiator; + this->public.set_request = (status_t(*)(message_t*, bool))set_request; + this->public.get_request = (bool(*)(message_t*))get_request; + this->public.generate_packet = (status_t (*) (message_t *, packet_t **)) generate_packet; this->public.destroy = (status_t(*)(message_t*))destroy; + + /* public values */ + this->exchange_type = NOT_SET; + this->original_initiator = TRUE; + this->is_request = TRUE; /* private values */ this->packet = packet; diff --git a/Source/charon/message.h b/Source/charon/message.h index 249137e2b..906c5410a 100644 --- a/Source/charon/message.h +++ b/Source/charon/message.h @@ -26,6 +26,38 @@ #include "types.h" #include "packet.h" +/** + * @brief Different types of IKE-Exchanges. + * + * See RFC for different types. + */ +typedef enum exchange_type_e exchange_type_t; + +enum exchange_type_e{ + + /** + * NOT_SET, not a official message type :-) + */ + NOT_SET = 0, + + /** + * IKE_SA_INIT + */ + IKE_SA_INIT = 34, + /** + * IKE_AUTH + */ + IKE_AUTH = 35, + /** + * CREATE_CHILD_SA + */ + CREATE_CHILD_SA = 36, + /** + * INFORMATIONAL + */ + INFORMATIONAL = 37 +}; + /** * @brief This class is used to represent an IKEv2-Message. * @@ -35,22 +67,89 @@ typedef struct message_s message_t; struct message_s { + /** + * @brief Sets the exchange type of the message. + * + * @param this message_t object + * @param exchange_type exchange_type to set + * @return SUCCESS + */ + status_t (*set_exchange_type) (message_t *this,exchange_type_t exchange_type); + + /** + * @brief Gets the exchange type of the message. + * + * @param this message_t object + * @return exchange type of the message + */ + exchange_type_t (*get_exchange_type) (message_t *this); + + /** + * @brief Sets the original initiator flag. + * + * @param this message_t object + * @param original_initiator TRUE if message is from original initiator + * @return SUCCESS + */ + status_t (*set_original_initiator) (message_t *this,bool original_initiator); + + /** + * @brief Gets original initiator flag. + * + * @param this message_t object + * @return TRUE if message is from original initiator, FALSE otherwise + */ + bool (*get_original_initiator) (message_t *this); + + /** + * @brief Sets the request flag. + * + * @param this message_t object + * @param original_initiator TRUE if message is a request, FALSE if it is a reply + * @return SUCCESS + */ + status_t (*set_request) (message_t *this,bool request); + + /** + * @brief Gets request flag. + * + * @param this message_t object + * @return TRUE if message is a request, FALSE if it is a reply + */ + bool (*get_request) (message_t *this); + + /** + * @brief Generates the UDP packet of specific message + * + * @param this message_t object + * @return + * - SUCCESS if packet could be generated + * - EXCHANGE_TYPE_NOT_SET if exchange type is currently not set + * .... + */ + status_t (*generate_packet) (message_t *this, packet_t **packet); + /** * @brief Destroys a message and all including objects * * @param this message_t object - * @return - * - SUCCESSFUL if succeeded + * @return SUCCESS */ status_t (*destroy) (message_t *this); }; /** * Creates an message_t object from a incoming UDP Packet. - * + * * @warning the given packet_t object is not copied and gets * destroyed in message_t's destroy call. * + * @warning Packet is not parsed in here! + * + * - exchange_type is set to NOT_SET + * - original_initiator is set to TRUE + * - is_request is set to TRUE + * * @param packet packet_t object which is assigned to message * * @return @@ -63,6 +162,10 @@ message_t * message_create_from_packet(packet_t *packet); /** * Creates an empty message_t object. * + * - exchange_type is set to NOT_SET + * - original_initiator is set to TRUE + * - is_request is set to TRUE + * * @return * - created message_t object * - NULL if out of ressources diff --git a/Source/charon/tests.c b/Source/charon/tests.c index 68575f730..737a3ceb0 100644 --- a/Source/charon/tests.c +++ b/Source/charon/tests.c @@ -43,6 +43,7 @@ #include "tests/ike_sa_test.h" #include "tests/ike_sa_manager_test.h" #include "tests/generator_test.h" +#include "tests/packet_test.h" /* output for test messages */ @@ -129,6 +130,12 @@ test_t generator_test1 = {test_generator_with_unsupported_payload,"Generator: un */ test_t generator_test2 = {test_generator_with_header_payload,"Generator: header payload"}; +/** + * Test for packet_t + */ +test_t packet_test = {test_packet,"Packet"}; + + /** * Global job-queue */ @@ -176,6 +183,7 @@ logger_t *global_logger; &generator_test1, &generator_test2, &ike_sa_manager_test, + &packet_test, NULL }; global_logger = logger_create("Tester",ALL); @@ -190,8 +198,8 @@ logger_t *global_logger; tester_t *tester = tester_create(test_output, FALSE); - tester->perform_tests(tester,all_tests); -/* tester->perform_test(tester,&generator_test2); */ + /*tester->perform_tests(tester,all_tests);*/ + tester->perform_test(tester,&generator_test2); tester->destroy(tester); diff --git a/Source/charon/tests/generator_test.c b/Source/charon/tests/generator_test.c index 08da99458..9c1d00e4f 100644 --- a/Source/charon/tests/generator_test.c +++ b/Source/charon/tests/generator_test.c @@ -39,13 +39,19 @@ extern logger_t *global_logger; void test_generator_with_unsupported_payload(tester_t *tester) { generator_t *generator; + generator_context_t *generator_context; void * data_struct; chunk_t generated_data; generator = generator_create(payload_infos); tester->assert_true(tester,(generator != NULL), "generator create check"); - tester->assert_true(tester,(generator->generate_payload(generator,(payload_type_t) -1,data_struct,&generated_data) == NOT_SUPPORTED),"generate_payload call check"); + generator_context = generator->create_context(generator); + + tester->assert_true(tester,(generator->generate_payload(generator,(payload_type_t) -1,data_struct,generator_context) == NOT_SUPPORTED),"generate_payload call check"); + + generator_context->destroy(generator_context); + tester->assert_true(tester,(generator->destroy(generator) == SUCCESS), "generator destroy call check"); } @@ -55,6 +61,7 @@ void test_generator_with_unsupported_payload(tester_t *tester) void test_generator_with_header_payload(tester_t *tester) { generator_t *generator; + generator_context_t *generator_context; ike_header_t header_data; chunk_t generated_data; status_t status; @@ -73,10 +80,15 @@ void test_generator_with_header_payload(tester_t *tester) generator = generator_create(payload_infos); tester->assert_true(tester,(generator != NULL), "generator create check"); + + generator_context = generator->create_context(generator); + tester->assert_true(tester,(generator_context != NULL), "generator_context create check"); - status = generator->generate_payload(generator,HEADER,&header_data,&generated_data); + status = generator->generate_payload(generator,HEADER,&header_data,generator_context); tester->assert_true(tester,(status == SUCCESS),"generate_payload call check"); + tester->assert_true(tester,(generator->write_to_chunk(generator,generator_context,&generated_data) == SUCCESS),"write_to_chunk call check"); + u_int8_t expected_generation[] = { 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x01, @@ -92,6 +104,8 @@ void test_generator_with_header_payload(tester_t *tester) tester->assert_true(tester,(memcmp(expected_generation,generated_data.ptr,sizeof(expected_generation)) == 0), "compare generated data 1"); allocator_free_chunk(generated_data); + generator_context->destroy(generator_context); + header_data.initiator_spi = 0x22000054231234; header_data.responder_spi = 0x122398; @@ -105,8 +119,12 @@ void test_generator_with_header_payload(tester_t *tester) header_data.message_id = 0x33AFF3; header_data.length = 0xAA11F; - status = generator->generate_payload(generator,HEADER,&header_data,&generated_data); + generator_context = generator->create_context(generator); + + status = generator->generate_payload(generator,HEADER,&header_data,generator_context); tester->assert_true(tester,(status == SUCCESS),"generate_payload call check"); + + tester->assert_true(tester,(generator->write_to_chunk(generator,generator_context,&generated_data) == SUCCESS),"write_to_chunk call check"); u_int8_t expected_generation2[] = { 0x00,0x22,0x00,0x00, @@ -123,5 +141,6 @@ void test_generator_with_header_payload(tester_t *tester) tester->assert_true(tester,(memcmp(expected_generation2,generated_data.ptr,sizeof(expected_generation2)) == 0), "compare generated data 2"); allocator_free_chunk(generated_data); + generator_context->destroy(generator_context); tester->assert_true(tester,(generator->destroy(generator) == SUCCESS), "generator destroy call check"); } diff --git a/Source/charon/types.h b/Source/charon/types.h index a427160cc..e14a0da3a 100644 --- a/Source/charon/types.h +++ b/Source/charon/types.h @@ -33,7 +33,8 @@ typedef enum status_e { ALREADY_DONE, NOT_SUPPORTED, INVALID_ARG, - NOT_FOUND + NOT_FOUND, + EXCHANGE_TYPE_NOT_SET, } status_t; typedef enum ike_sa_role_e {