Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/cp_payload.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 "cp_payload.h"
                     21: 
                     22: #include <encoding/payloads/encodings.h>
                     23: #include <collections/linked_list.h>
                     24: 
                     25: ENUM(config_type_names, CFG_REQUEST, CFG_ACK,
                     26:        "CFG_REQUEST",
                     27:        "CFG_REPLY",
                     28:        "CFG_SET",
                     29:        "CFG_ACK",
                     30: );
                     31: 
                     32: typedef struct private_cp_payload_t private_cp_payload_t;
                     33: 
                     34: /**
                     35:  * Private data of an cp_payload_t object.
                     36:  */
                     37: struct private_cp_payload_t {
                     38: 
                     39:        /**
                     40:         * Public cp_payload_t interface.
                     41:         */
                     42:        cp_payload_t public;
                     43: 
                     44:        /**
                     45:         * Next payload type.
                     46:         */
                     47:        uint8_t next_payload;
                     48: 
                     49:        /**
                     50:         * Critical flag.
                     51:         */
                     52:        bool critical;
                     53: 
                     54:        /**
                     55:         * Reserved bits
                     56:         */
                     57:        bool reserved_bit[7];
                     58: 
                     59:        /**
                     60:         * Reserved bytes
                     61:         */
                     62:        uint8_t reserved_byte[3];
                     63: 
                     64:        /**
                     65:         * Length of this payload.
                     66:         */
                     67:        uint16_t payload_length;
                     68: 
                     69:        /**
                     70:         * Identifier field, IKEv1 only
                     71:         */
                     72:        uint16_t identifier;
                     73: 
                     74:        /**
                     75:         * List of attributes, as configuration_attribute_t
                     76:         */
                     77:        linked_list_t *attributes;
                     78: 
                     79:        /**
                     80:         * Config Type.
                     81:         */
                     82:        uint8_t cfg_type;
                     83: 
                     84:        /**
                     85:         * PLV2_CONFIGURATION or PLV1_CONFIGURATION
                     86:         */
                     87:        payload_type_t type;
                     88: };
                     89: 
                     90: /**
                     91:  * Encoding rules to for an IKEv2 configuration payload
                     92:  */
                     93: static encoding_rule_t encodings_v2[] = {
                     94:        /* 1 Byte next payload type, stored in the field next_payload */
                     95:        { U_INT_8,                      offsetof(private_cp_payload_t, next_payload)    },
                     96:        /* the critical bit */
                     97:        { FLAG,                         offsetof(private_cp_payload_t, critical)                },
                     98:        /* 7 Bit reserved bits */
                     99:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[0]) },
                    100:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[1]) },
                    101:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[2]) },
                    102:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[3]) },
                    103:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[4]) },
                    104:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[5]) },
                    105:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[6]) },
                    106:        /* Length of the whole CP payload*/
                    107:        { PAYLOAD_LENGTH,       offsetof(private_cp_payload_t, payload_length)  },
                    108:        { U_INT_8,                      offsetof(private_cp_payload_t, cfg_type)                },
                    109:        /* 3 reserved bytes */
                    110:        { RESERVED_BYTE,        offsetof(private_cp_payload_t, reserved_byte[0])},
                    111:        { RESERVED_BYTE,        offsetof(private_cp_payload_t, reserved_byte[1])},
                    112:        { RESERVED_BYTE,        offsetof(private_cp_payload_t, reserved_byte[2])},
                    113:        /* list of configuration attributes in a list */
                    114:        { PAYLOAD_LIST + PLV2_CONFIGURATION_ATTRIBUTE,
                    115:                                                offsetof(private_cp_payload_t, attributes)              },
                    116: };
                    117: 
                    118: /*
                    119:                            1                   2                   3
                    120:        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
                    121:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    122:       ! Next Payload  !C! RESERVED    !         Payload Length        !
                    123:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    124:       !   CFG Type    !                    RESERVED                   !
                    125:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    126:       !                                                               !
                    127:       ~                   Configuration Attributes                    ~
                    128:       !                                                               !
                    129:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    130: */
                    131: 
                    132: /**
                    133:  * Encoding rules to for an IKEv1 configuration payload
                    134:  */
                    135: static encoding_rule_t encodings_v1[] = {
                    136:        /* 1 Byte next payload type, stored in the field next_payload */
                    137:        { U_INT_8,                      offsetof(private_cp_payload_t, next_payload)    },
                    138:        /* the critical bit */
                    139:        { FLAG,                         offsetof(private_cp_payload_t, critical)                },
                    140:        /* 7 Bit reserved bits */
                    141:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[0]) },
                    142:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[1]) },
                    143:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[2]) },
                    144:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[3]) },
                    145:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[4]) },
                    146:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[5]) },
                    147:        { RESERVED_BIT,         offsetof(private_cp_payload_t, reserved_bit[6]) },
                    148:        /* Length of the whole CP payload*/
                    149:        { PAYLOAD_LENGTH,       offsetof(private_cp_payload_t, payload_length)  },
                    150:        { U_INT_8,                      offsetof(private_cp_payload_t, cfg_type)                },
                    151:        /* 1 reserved bytes */
                    152:        { RESERVED_BYTE,        offsetof(private_cp_payload_t, reserved_byte[0])},
                    153:        { U_INT_16,                     offsetof(private_cp_payload_t, identifier)},
                    154:        /* list of configuration attributes in a list */
                    155:        { PAYLOAD_LIST + PLV1_CONFIGURATION_ATTRIBUTE,
                    156:                                                offsetof(private_cp_payload_t, attributes)              },
                    157: };
                    158: 
                    159: /*
                    160:                            1                   2                   3
                    161:        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
                    162:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    163:       ! Next Payload  !   RESERVED    !         Payload Length        !
                    164:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    165:       !   CFG Type    !   RESERVED    !           Identifier          !
                    166:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    167:       !                                                               !
                    168:       ~                   Configuration Attributes                    ~
                    169:       !                                                               !
                    170:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    171: */
                    172: 
                    173: METHOD(payload_t, verify, status_t,
                    174:        private_cp_payload_t *this)
                    175: {
                    176:        status_t status = SUCCESS;
                    177:        enumerator_t *enumerator;
                    178:        payload_t *attribute;
                    179: 
                    180:        enumerator = this->attributes->create_enumerator(this->attributes);
                    181:        while (enumerator->enumerate(enumerator, &attribute))
                    182:        {
                    183:                status = attribute->verify(attribute);
                    184:                if (status != SUCCESS)
                    185:                {
                    186:                        break;
                    187:                }
                    188:        }
                    189:        enumerator->destroy(enumerator);
                    190:        return status;
                    191: }
                    192: 
                    193: METHOD(payload_t, get_encoding_rules, int,
                    194:        private_cp_payload_t *this, encoding_rule_t **rules)
                    195: {
                    196:        if (this->type == PLV2_CONFIGURATION)
                    197:        {
                    198:                *rules = encodings_v2;
                    199:                return countof(encodings_v2);
                    200:        }
                    201:        *rules = encodings_v1;
                    202:        return countof(encodings_v1);
                    203: }
                    204: 
                    205: METHOD(payload_t, get_header_length, int,
                    206:        private_cp_payload_t *this)
                    207: {
                    208:        return 8;
                    209: }
                    210: 
                    211: METHOD(payload_t, get_type, payload_type_t,
                    212:        private_cp_payload_t *this)
                    213: {
                    214:        return this->type;
                    215: }
                    216: 
                    217: METHOD(payload_t, get_next_type, payload_type_t,
                    218:        private_cp_payload_t *this)
                    219: {
                    220:        return this->next_payload;
                    221: }
                    222: 
                    223: METHOD(payload_t, set_next_type, void,
                    224:        private_cp_payload_t *this,payload_type_t type)
                    225: {
                    226:        this->next_payload = type;
                    227: }
                    228: 
                    229: /**
                    230:  * recompute the length of the payload.
                    231:  */
                    232: static void compute_length(private_cp_payload_t *this)
                    233: {
                    234:        enumerator_t *enumerator;
                    235:        payload_t *attribute;
                    236: 
                    237:        this->payload_length = get_header_length(this);
                    238: 
                    239:        enumerator = this->attributes->create_enumerator(this->attributes);
                    240:        while (enumerator->enumerate(enumerator, &attribute))
                    241:        {
                    242:                this->payload_length += attribute->get_length(attribute);
                    243:        }
                    244:        enumerator->destroy(enumerator);
                    245: }
                    246: 
                    247: METHOD(payload_t, get_length, size_t,
                    248:        private_cp_payload_t *this)
                    249: {
                    250:        return this->payload_length;
                    251: }
                    252: 
                    253: METHOD(cp_payload_t, create_attribute_enumerator, enumerator_t*,
                    254:        private_cp_payload_t *this)
                    255: {
                    256:        return this->attributes->create_enumerator(this->attributes);
                    257: }
                    258: 
                    259: METHOD(cp_payload_t, add_attribute, void,
                    260:        private_cp_payload_t *this, configuration_attribute_t *attribute)
                    261: {
                    262:        this->attributes->insert_last(this->attributes, attribute);
                    263:        compute_length(this);
                    264: }
                    265: 
                    266: METHOD(cp_payload_t, get_config_type, config_type_t,
                    267:        private_cp_payload_t *this)
                    268: {
                    269:        return this->cfg_type;
                    270: }
                    271: 
                    272: METHOD(cp_payload_t, get_identifier, uint16_t,
                    273:                         private_cp_payload_t *this)
                    274: {
                    275:        return this->identifier;
                    276: }
                    277: METHOD(cp_payload_t, set_identifier, void,
                    278:                         private_cp_payload_t *this, uint16_t identifier)
                    279: {
                    280:        this->identifier = identifier;
                    281: }
                    282: 
                    283: METHOD2(payload_t, cp_payload_t, destroy, void,
                    284:        private_cp_payload_t *this)
                    285: {
                    286:        this->attributes->destroy_offset(this->attributes,
                    287:                                                                offsetof(configuration_attribute_t, destroy));
                    288:        free(this);
                    289: }
                    290: 
                    291: /*
                    292:  * Described in header.
                    293:  */
                    294: cp_payload_t *cp_payload_create_type(payload_type_t type, config_type_t cfg_type)
                    295: {
                    296:        private_cp_payload_t *this;
                    297: 
                    298:        INIT(this,
                    299:                .public = {
                    300:                        .payload_interface = {
                    301:                                .verify = _verify,
                    302:                                .get_encoding_rules = _get_encoding_rules,
                    303:                                .get_header_length = _get_header_length,
                    304:                                .get_length = _get_length,
                    305:                                .get_next_type = _get_next_type,
                    306:                                .set_next_type = _set_next_type,
                    307:                                .get_type = _get_type,
                    308:                                .destroy = _destroy,
                    309:                        },
                    310:                        .create_attribute_enumerator = _create_attribute_enumerator,
                    311:                        .add_attribute = _add_attribute,
                    312:                        .get_type = _get_config_type,
                    313:                        .get_identifier = _get_identifier,
                    314:                        .set_identifier = _set_identifier,
                    315:                        .destroy = _destroy,
                    316:                },
                    317:                .next_payload = PL_NONE,
                    318:                .payload_length = get_header_length(this),
                    319:                .attributes = linked_list_create(),
                    320:                .cfg_type = cfg_type,
                    321:                .type = type,
                    322:        );
                    323:        return &this->public;
                    324: }
                    325: 
                    326: /*
                    327:  * Described in header.
                    328:  */
                    329: cp_payload_t *cp_payload_create(payload_type_t type)
                    330: {
                    331:        return cp_payload_create_type(type, CFG_REQUEST);
                    332: }

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