Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/transform_substructure.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2005-2010 Martin Willi
                      3:  * Copyright (C) 2010 revosec AG
                      4:  * Copyright (C) 2005 Jan Hutter
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include <stddef.h>
                     19: 
                     20: #include "transform_substructure.h"
                     21: 
                     22: #include <encoding/payloads/transform_attribute.h>
                     23: #include <encoding/payloads/encodings.h>
                     24: #include <library.h>
                     25: #include <collections/linked_list.h>
                     26: #include <daemon.h>
                     27: 
                     28: typedef struct private_transform_substructure_t private_transform_substructure_t;
                     29: 
                     30: /**
                     31:  * Private data of an transform_substructure_t object.
                     32:  */
                     33: struct private_transform_substructure_t {
                     34: 
                     35:        /**
                     36:         * Public transform_substructure_t interface.
                     37:         */
                     38:        transform_substructure_t public;
                     39: 
                     40:        /**
                     41:         * Next payload type.
                     42:         */
                     43:        uint8_t  next_payload;
                     44: 
                     45:        /**
                     46:         * Reserved byte
                     47:         */
                     48:        uint8_t reserved[3];
                     49: 
                     50:        /**
                     51:         * Length of this payload.
                     52:         */
                     53:        uint16_t transform_length;
                     54: 
                     55:        /**
                     56:         * Type or number, Type of the transform in IKEv2, number in IKEv2.
                     57:         */
                     58:        uint8_t transform_ton;
                     59: 
                     60:        /**
                     61:         * Transform ID, as encoded in IKEv1.
                     62:         */
                     63:        uint8_t transform_id_v1;
                     64: 
                     65:        /**
                     66:         * Transform ID, as encoded in IKEv2.
                     67:         */
                     68:        uint16_t transform_id_v2;
                     69: 
                     70:        /**
                     71:         * Transforms Attributes are stored in a linked_list_t.
                     72:         */
                     73:        linked_list_t *attributes;
                     74: 
                     75:        /**
                     76:         * Payload type, PLV2_TRANSFORM_SUBSTRUCTURE or PLV1_TRANSFORM_SUBSTRUCTURE
                     77:         */
                     78:        payload_type_t type;
                     79: };
                     80: 
                     81: /**
                     82:  * Encoding rules for PLV2_TRANSFORM_SUBSTRUCTURE
                     83:  */
                     84: static encoding_rule_t encodings_v2[] = {
                     85:        /* 1 Byte next payload type, stored in the field next_payload */
                     86:        { U_INT_8,                      offsetof(private_transform_substructure_t, next_payload)        },
                     87:        /* 1 Reserved Byte */
                     88:        { RESERVED_BYTE,        offsetof(private_transform_substructure_t, reserved[0])         },
                     89:        /* Length of the whole transform substructure*/
                     90:        { PAYLOAD_LENGTH,       offsetof(private_transform_substructure_t, transform_length)},
                     91:        /* transform type */
                     92:        { U_INT_8,                      offsetof(private_transform_substructure_t, transform_ton)       },
                     93:        /* transform identifier, as used by IKEv1 */
                     94:        { RESERVED_BYTE,        offsetof(private_transform_substructure_t, reserved[1])         },
                     95:        /* transform identifier, as used by IKEv2 */
                     96:        { U_INT_16,                     offsetof(private_transform_substructure_t, transform_id_v2)     },
                     97:        /* Attributes in a transform attribute list */
                     98:        { PAYLOAD_LIST + PLV2_TRANSFORM_ATTRIBUTE,
                     99:                                                offsetof(private_transform_substructure_t, attributes)          }
                    100: };
                    101: 
                    102: /**
                    103:  * Encoding rules for PLV1_TRANSFORM_SUBSTRUCTURE
                    104:  */
                    105: static encoding_rule_t encodings_v1[] = {
                    106:        /* 1 Byte next payload type, stored in the field next_payload */
                    107:        { U_INT_8,                      offsetof(private_transform_substructure_t, next_payload)        },
                    108:        /* 1 Reserved Byte */
                    109:        { RESERVED_BYTE,        offsetof(private_transform_substructure_t, reserved[0])         },
                    110:        /* Length of the whole transform substructure*/
                    111:        { PAYLOAD_LENGTH,       offsetof(private_transform_substructure_t, transform_length)},
                    112:        /* transform number */
                    113:        { U_INT_8,                      offsetof(private_transform_substructure_t, transform_ton)},
                    114:        /* transform identifier, as used by IKEv1 */
                    115:        { U_INT_8,                      offsetof(private_transform_substructure_t, transform_id_v1)     },
                    116:        /* transform identifier, as used by IKEv2 */
                    117:        { RESERVED_BYTE,        offsetof(private_transform_substructure_t, reserved[1])         },
                    118:        { RESERVED_BYTE,        offsetof(private_transform_substructure_t, reserved[2])         },
                    119:        /* Attributes in a transform attribute list */
                    120:        { PAYLOAD_LIST + PLV1_TRANSFORM_ATTRIBUTE,
                    121:                                                offsetof(private_transform_substructure_t, attributes)          }
                    122: };
                    123: 
                    124: /*
                    125:                            1                   2                   3
                    126:        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
                    127:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    128:       ! 0 (last) or 3 !   RESERVED    !        Transform Length       !
                    129:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    130:       ! Tfrm Typ or # ! Tfrm ID IKEv1 !        Transform ID IKEv2     !
                    131:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    132:       !                                                               !
                    133:       ~                      Transform Attributes                     ~
                    134:       !                                                               !
                    135:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    136: */
                    137: 
                    138: METHOD(payload_t, verify, status_t,
                    139:        private_transform_substructure_t *this)
                    140: {
                    141:        status_t status = SUCCESS;
                    142:        enumerator_t *enumerator;
                    143:        payload_t *attribute;
                    144: 
                    145:        if (this->next_payload != PL_NONE && this->next_payload != 3)
                    146:        {
                    147:                DBG1(DBG_ENC, "inconsistent next payload");
                    148:                return FAILED;
                    149:        }
                    150: 
                    151:        enumerator = this->attributes->create_enumerator(this->attributes);
                    152:        while (enumerator->enumerate(enumerator, &attribute))
                    153:        {
                    154:                status = attribute->verify(attribute);
                    155:                if (status != SUCCESS)
                    156:                {
                    157:                        DBG1(DBG_ENC, "TRANSFORM_ATTRIBUTE verification failed");
                    158:                        break;
                    159:                }
                    160:        }
                    161:        enumerator->destroy(enumerator);
                    162: 
                    163:        /* proposal number is checked in SA payload */
                    164:        return status;
                    165: }
                    166: 
                    167: METHOD(payload_t, get_encoding_rules, int,
                    168:        private_transform_substructure_t *this, encoding_rule_t **rules)
                    169: {
                    170:        if (this->type == PLV2_TRANSFORM_SUBSTRUCTURE)
                    171:        {
                    172:                *rules = encodings_v2;
                    173:                return countof(encodings_v2);
                    174:        }
                    175:        *rules = encodings_v1;
                    176:        return countof(encodings_v1);
                    177: }
                    178: 
                    179: METHOD(payload_t, get_header_length, int,
                    180:        private_transform_substructure_t *this)
                    181: {
                    182:        return 8;
                    183: }
                    184: 
                    185: METHOD(payload_t, get_type, payload_type_t,
                    186:        private_transform_substructure_t *this)
                    187: {
                    188:        return this->type;
                    189: }
                    190: 
                    191: METHOD(payload_t, get_next_type, payload_type_t,
                    192:        private_transform_substructure_t *this)
                    193: {
                    194:        return this->next_payload;
                    195: }
                    196: 
                    197: /**
                    198:  * recompute the length of the payload.
                    199:  */
                    200: static void compute_length(private_transform_substructure_t *this)
                    201: {
                    202:        enumerator_t *enumerator;
                    203:        payload_t *attribute;
                    204: 
                    205:        this->transform_length = get_header_length(this);
                    206:        enumerator = this->attributes->create_enumerator(this->attributes);
                    207:        while (enumerator->enumerate(enumerator, &attribute))
                    208:        {
                    209:                this->transform_length += attribute->get_length(attribute);
                    210:        }
                    211:        enumerator->destroy(enumerator);
                    212: }
                    213: 
                    214: METHOD(payload_t, get_length, size_t,
                    215:        private_transform_substructure_t *this)
                    216: {
                    217:        return this->transform_length;
                    218: }
                    219: 
                    220: METHOD(transform_substructure_t, add_transform_attribute, void,
                    221:        private_transform_substructure_t *this, transform_attribute_t *attribute)
                    222: {
                    223:        this->attributes->insert_last(this->attributes, attribute);
                    224:        compute_length(this);
                    225: }
                    226: 
                    227: METHOD(transform_substructure_t, set_is_last_transform, void,
                    228:        private_transform_substructure_t *this, bool is_last)
                    229: {
                    230:        this->next_payload = is_last ? 0: TRANSFORM_TYPE_VALUE;
                    231: }
                    232: 
                    233: METHOD(payload_t, set_next_type, void,
                    234:        private_transform_substructure_t *this,payload_type_t type)
                    235: {
                    236: }
                    237: 
                    238: METHOD(transform_substructure_t, get_transform_type_or_number, uint8_t,
                    239:        private_transform_substructure_t *this)
                    240: {
                    241:        return this->transform_ton;
                    242: }
                    243: 
                    244: METHOD(transform_substructure_t, get_transform_id, uint16_t,
                    245:        private_transform_substructure_t *this)
                    246: {
                    247:        if (this->type == PLV2_TRANSFORM_SUBSTRUCTURE)
                    248:        {
                    249:                return this->transform_id_v2;
                    250:        }
                    251:        return this->transform_id_v1;
                    252: }
                    253: 
                    254: METHOD(transform_substructure_t, create_attribute_enumerator, enumerator_t*,
                    255:        private_transform_substructure_t *this)
                    256: {
                    257:        return this->attributes->create_enumerator(this->attributes);
                    258: }
                    259: 
                    260: METHOD2(payload_t, transform_substructure_t, destroy, void,
                    261:        private_transform_substructure_t *this)
                    262: {
                    263:        this->attributes->destroy_offset(this->attributes,
                    264:                                                                         offsetof(payload_t, destroy));
                    265:        free(this);
                    266: }
                    267: 
                    268: /*
                    269:  * Described in header.
                    270:  */
                    271: transform_substructure_t *transform_substructure_create(payload_type_t type)
                    272: {
                    273:        private_transform_substructure_t *this;
                    274: 
                    275:        INIT(this,
                    276:                .public = {
                    277:                        .payload_interface = {
                    278:                                .verify = _verify,
                    279:                                .get_encoding_rules = _get_encoding_rules,
                    280:                                .get_header_length = _get_header_length,
                    281:                                .get_length = _get_length,
                    282:                                .get_next_type = _get_next_type,
                    283:                                .set_next_type = _set_next_type,
                    284:                                .get_type = _get_type,
                    285:                                .destroy = _destroy,
                    286:                        },
                    287:                        .add_transform_attribute = _add_transform_attribute,
                    288:                        .set_is_last_transform = _set_is_last_transform,
                    289:                        .get_transform_type_or_number = _get_transform_type_or_number,
                    290:                        .get_transform_id = _get_transform_id,
                    291:                        .create_attribute_enumerator = _create_attribute_enumerator,
                    292:                        .destroy = _destroy,
                    293:                },
                    294:                .next_payload = PL_NONE,
                    295:                .transform_length = get_header_length(this),
                    296:                .attributes = linked_list_create(),
                    297:                .type = type,
                    298:        );
                    299:        return &this->public;
                    300: }
                    301: 
                    302: /*
                    303:  * Described in header
                    304:  */
                    305: transform_substructure_t *transform_substructure_create_type(payload_type_t type,
                    306:                                uint8_t type_or_number, uint16_t id)
                    307: {
                    308:        private_transform_substructure_t *this;
                    309: 
                    310:        this = (private_transform_substructure_t*)transform_substructure_create(type);
                    311: 
                    312:        this->transform_ton = type_or_number;
                    313:        if (type == PLV2_TRANSFORM_SUBSTRUCTURE)
                    314:        {
                    315:                this->transform_id_v2 = id;
                    316:        }
                    317:        else
                    318:        {
                    319:                this->transform_id_v1 = id;
                    320:        }
                    321:        return &this->public;
                    322: }
                    323: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>