diff options
Diffstat (limited to 'src/libcharon/encoding/payloads/cp_payload.c')
-rw-r--r-- | src/libcharon/encoding/payloads/cp_payload.c | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/src/libcharon/encoding/payloads/cp_payload.c b/src/libcharon/encoding/payloads/cp_payload.c index 1813c9790..9ecb15006 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,16 +79,18 @@ 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 */ -static encoding_rule_t 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) }, /* the critical bit */ @@ -98,7 +105,7 @@ static encoding_rule_t encodings[] = { { 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, type) }, + { 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])}, @@ -122,6 +129,47 @@ static encoding_rule_t 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, + 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) { @@ -145,8 +193,13 @@ METHOD(payload_t, verify, status_t, METHOD(payload_t, get_encoding_rules, int, private_cp_payload_t *this, encoding_rule_t **rules) { - *rules = encodings; - return countof(encodings); + 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, @@ -158,7 +211,7 @@ METHOD(payload_t, get_header_length, int, 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, @@ -213,7 +266,7 @@ 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; } METHOD2(payload_t, cp_payload_t, destroy, void, @@ -227,7 +280,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; @@ -251,6 +304,7 @@ cp_payload_t *cp_payload_create_type(config_type_t type) .next_payload = NO_PAYLOAD, .payload_length = get_header_length(this), .attributes = linked_list_create(), + .cfg_type = cfg_type, .type = type, ); return &this->public; @@ -259,7 +313,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); } |