diff options
Diffstat (limited to 'src/libcharon/encoding/payloads/cp_payload.c')
-rw-r--r-- | src/libcharon/encoding/payloads/cp_payload.c | 144 |
1 files changed, 109 insertions, 35 deletions
diff --git a/src/libcharon/encoding/payloads/cp_payload.c b/src/libcharon/encoding/payloads/cp_payload.c index 82e9e51b7..40f6ae48f 100644 --- a/src/libcharon/encoding/payloads/cp_payload.c +++ b/src/libcharon/encoding/payloads/cp_payload.c @@ -44,7 +44,7 @@ struct private_cp_payload_t { /** * Next payload type. */ - u_int8_t next_payload; + u_int8_t next_payload; /** * Critical flag. @@ -67,6 +67,11 @@ struct private_cp_payload_t { u_int16_t payload_length; /** + * Identifier field, IKEv1 only + */ + u_int16_t identifier; + + /** * List of attributes, as configuration_attribute_t */ linked_list_t *attributes; @@ -74,38 +79,40 @@ struct private_cp_payload_t { /** * Config Type. */ - u_int8_t type; + u_int8_t cfg_type; + + /** + * CONFIGURATION or CONFIGURATION_V1 + */ + payload_type_t type; }; /** - * Encoding rules to parse or generate a IKEv2-CP Payload - * - * The defined offsets are the positions in a object of type - * private_cp_payload_t. + * Encoding rules to for an IKEv2 configuration payload */ -encoding_rule_t cp_payload_encodings[] = { +static encoding_rule_t encodings_v2[] = { /* 1 Byte next payload type, stored in the field next_payload */ - { U_INT_8, offsetof(private_cp_payload_t, next_payload) }, + { U_INT_8, offsetof(private_cp_payload_t, next_payload) }, /* the critical bit */ - { FLAG, offsetof(private_cp_payload_t, critical) }, + { FLAG, offsetof(private_cp_payload_t, critical) }, /* 7 Bit reserved bits */ - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) }, - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) }, - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) }, - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) }, - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) }, - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) }, - { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) }, /* Length of the whole CP payload*/ - { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) }, - /* Proposals are stored in a proposal substructure, - offset points to a linked_list_t pointer */ - { U_INT_8, offsetof(private_cp_payload_t, type) }, + { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) }, + { U_INT_8, offsetof(private_cp_payload_t, cfg_type) }, /* 3 reserved bytes */ - { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])}, - { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[1])}, - { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[2])}, - { CONFIGURATION_ATTRIBUTES, offsetof(private_cp_payload_t, attributes) } + { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])}, + { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[1])}, + { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[2])}, + /* list of configuration attributes in a list */ + { PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE, + offsetof(private_cp_payload_t, attributes) }, }; /* @@ -122,6 +129,47 @@ encoding_rule_t cp_payload_encodings[] = { +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ +/** + * Encoding rules to for an IKEv1 configuration payload + */ +static encoding_rule_t encodings_v1[] = { + /* 1 Byte next payload type, stored in the field next_payload */ + { U_INT_8, offsetof(private_cp_payload_t, next_payload) }, + /* the critical bit */ + { FLAG, offsetof(private_cp_payload_t, critical) }, + /* 7 Bit reserved bits */ + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[0]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[1]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[2]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[3]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[4]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[5]) }, + { RESERVED_BIT, offsetof(private_cp_payload_t, reserved_bit[6]) }, + /* Length of the whole CP payload*/ + { PAYLOAD_LENGTH, offsetof(private_cp_payload_t, payload_length) }, + { U_INT_8, offsetof(private_cp_payload_t, cfg_type) }, + /* 1 reserved bytes */ + { RESERVED_BYTE, offsetof(private_cp_payload_t, reserved_byte[0])}, + { U_INT_16, offsetof(private_cp_payload_t, identifier)}, + /* list of configuration attributes in a list */ + { PAYLOAD_LIST + CONFIGURATION_ATTRIBUTE_V1, + offsetof(private_cp_payload_t, attributes) }, +}; + +/* + 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! Next Payload ! RESERVED ! Payload Length ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! CFG Type ! RESERVED ! Identifier ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + ! ! + ~ Configuration Attributes ~ + ! ! + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + METHOD(payload_t, verify, status_t, private_cp_payload_t *this) { @@ -142,17 +190,28 @@ METHOD(payload_t, verify, status_t, return status; } -METHOD(payload_t, get_encoding_rules, void, - private_cp_payload_t *this, encoding_rule_t **rules, size_t *rule_count) +METHOD(payload_t, get_encoding_rules, int, + private_cp_payload_t *this, encoding_rule_t **rules) +{ + if (this->type == CONFIGURATION) + { + *rules = encodings_v2; + return countof(encodings_v2); + } + *rules = encodings_v1; + return countof(encodings_v1); +} + +METHOD(payload_t, get_header_length, int, + private_cp_payload_t *this) { - *rules = cp_payload_encodings; - *rule_count = countof(cp_payload_encodings); + return 8; } METHOD(payload_t, get_type, payload_type_t, private_cp_payload_t *this) { - return CONFIGURATION; + return this->type; } METHOD(payload_t, get_next_type, payload_type_t, @@ -175,7 +234,7 @@ static void compute_length(private_cp_payload_t *this) enumerator_t *enumerator; payload_t *attribute; - this->payload_length = CP_PAYLOAD_HEADER_LENGTH; + this->payload_length = get_header_length(this); enumerator = this->attributes->create_enumerator(this->attributes); while (enumerator->enumerate(enumerator, &attribute)) @@ -207,7 +266,18 @@ METHOD(cp_payload_t, add_attribute, void, METHOD(cp_payload_t, get_config_type, config_type_t, private_cp_payload_t *this) { - return this->type; + return this->cfg_type; +} + +METHOD(cp_payload_t, get_identifier, u_int16_t, + private_cp_payload_t *this) +{ + return this->identifier; +} +METHOD(cp_payload_t, set_identifier, void, + private_cp_payload_t *this, u_int16_t identifier) +{ + this->identifier = identifier; } METHOD2(payload_t, cp_payload_t, destroy, void, @@ -221,7 +291,7 @@ METHOD2(payload_t, cp_payload_t, destroy, void, /* * Described in header. */ -cp_payload_t *cp_payload_create_type(config_type_t type) +cp_payload_t *cp_payload_create_type(payload_type_t type, config_type_t cfg_type) { private_cp_payload_t *this; @@ -230,6 +300,7 @@ cp_payload_t *cp_payload_create_type(config_type_t type) .payload_interface = { .verify = _verify, .get_encoding_rules = _get_encoding_rules, + .get_header_length = _get_header_length, .get_length = _get_length, .get_next_type = _get_next_type, .set_next_type = _set_next_type, @@ -239,11 +310,14 @@ cp_payload_t *cp_payload_create_type(config_type_t type) .create_attribute_enumerator = _create_attribute_enumerator, .add_attribute = _add_attribute, .get_type = _get_config_type, + .get_identifier = _get_identifier, + .set_identifier = _set_identifier, .destroy = _destroy, }, .next_payload = NO_PAYLOAD, - .payload_length = CP_PAYLOAD_HEADER_LENGTH, + .payload_length = get_header_length(this), .attributes = linked_list_create(), + .cfg_type = cfg_type, .type = type, ); return &this->public; @@ -252,7 +326,7 @@ cp_payload_t *cp_payload_create_type(config_type_t type) /* * Described in header. */ -cp_payload_t *cp_payload_create() +cp_payload_t *cp_payload_create(payload_type_t type) { - return cp_payload_create_type(CFG_REQUEST); + return cp_payload_create_type(type, CFG_REQUEST); } |