Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/traffic_selector_substructure.c, revision 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 "traffic_selector_substructure.h"
        !            19: 
        !            20: #include <encoding/payloads/encodings.h>
        !            21: #include <collections/linked_list.h>
        !            22: 
        !            23: typedef struct private_traffic_selector_substructure_t private_traffic_selector_substructure_t;
        !            24: 
        !            25: /**
        !            26:  * Private data of an traffic_selector_substructure_t object.
        !            27:  */
        !            28: struct private_traffic_selector_substructure_t {
        !            29: 
        !            30:        /**
        !            31:         * Public traffic_selector_substructure_t interface.
        !            32:         */
        !            33:        traffic_selector_substructure_t public;
        !            34: 
        !            35:        /**
        !            36:         * Type of traffic selector.
        !            37:         */
        !            38:        uint8_t ts_type;
        !            39: 
        !            40:        /**
        !            41:         * IP Protocol ID.
        !            42:         */
        !            43:        uint8_t ip_protocol_id;
        !            44: 
        !            45:        /**
        !            46:         * Length of this payload.
        !            47:         */
        !            48:        uint16_t payload_length;
        !            49: 
        !            50:        /**
        !            51:         * Start port number.
        !            52:         */
        !            53:        uint16_t start_port;
        !            54: 
        !            55:        /**
        !            56:         * End port number.
        !            57:         */
        !            58:        uint16_t end_port;
        !            59: 
        !            60:        /**
        !            61:         * Starting address.
        !            62:         */
        !            63:        chunk_t starting_address;
        !            64: 
        !            65:        /**
        !            66:         * Ending address.
        !            67:         */
        !            68:        chunk_t ending_address;
        !            69: };
        !            70: 
        !            71: /**
        !            72:  * Encoding rules to parse or generate a TS payload
        !            73:  *
        !            74:  * The defined offsets are the positions in a object of type
        !            75:  * private_traffic_selector_substructure_t.
        !            76:  */
        !            77: static encoding_rule_t encodings[] = {
        !            78:        /* 1 Byte next ts type*/
        !            79:        { TS_TYPE,              offsetof(private_traffic_selector_substructure_t, ts_type)                      },
        !            80:        /* 1 Byte IP protocol id*/
        !            81:        { U_INT_8,              offsetof(private_traffic_selector_substructure_t, ip_protocol_id)       },
        !            82:        /* Length of the whole payload*/
        !            83:        { PAYLOAD_LENGTH,offsetof(private_traffic_selector_substructure_t, payload_length)      },
        !            84:        /* 2 Byte start port*/
        !            85:        { U_INT_16,             offsetof(private_traffic_selector_substructure_t, start_port)           },
        !            86:        /* 2 Byte end port*/
        !            87:        { U_INT_16,             offsetof(private_traffic_selector_substructure_t, end_port)                     },
        !            88:        /* starting address is either 4 or 16 byte */
        !            89:        { ADDRESS,              offsetof(private_traffic_selector_substructure_t, starting_address)     },
        !            90:        /* ending address is either 4 or 16 byte */
        !            91:        { ADDRESS,              offsetof(private_traffic_selector_substructure_t, ending_address)       }
        !            92: };
        !            93: 
        !            94: /*
        !            95:                            1                   2                   3
        !            96:        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
        !            97:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !            98:       !   TS Type     !IP Protocol ID*|       Selector Length         |
        !            99:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           100:       |           Start Port*         |           End Port*           |
        !           101:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           102:       !                                                               !
        !           103:       ~                         Starting Address*                     ~
        !           104:       !                                                               !
        !           105:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           106:       !                                                               !
        !           107:       ~                         Ending Address*                       ~
        !           108:       !                                                               !
        !           109:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        !           110: */
        !           111: 
        !           112: METHOD(payload_t, verify, status_t,
        !           113:        private_traffic_selector_substructure_t *this)
        !           114: {
        !           115:        if (this->start_port > this->end_port)
        !           116:        {
        !           117:                /* OPAQUE ports are the only exception */
        !           118:                if (this->start_port != 0xffff && this->end_port != 0)
        !           119:                {
        !           120:                        return FAILED;
        !           121:                }
        !           122:        }
        !           123:        switch (this->ts_type)
        !           124:        {
        !           125:                case TS_IPV4_ADDR_RANGE:
        !           126:                {
        !           127:                        if ((this->starting_address.len != 4) ||
        !           128:                                (this->ending_address.len != 4))
        !           129:                        {
        !           130:                                /* ipv4 address must be 4 bytes long */
        !           131:                                return FAILED;
        !           132:                        }
        !           133:                        break;
        !           134:                }
        !           135:                case TS_IPV6_ADDR_RANGE:
        !           136:                {
        !           137:                        if ((this->starting_address.len != 16) ||
        !           138:                                (this->ending_address.len != 16))
        !           139:                        {
        !           140:                                /* ipv6 address must be 16 bytes long */
        !           141:                                return FAILED;
        !           142:                        }
        !           143:                        break;
        !           144:                }
        !           145:                default:
        !           146:                {
        !           147:                        /* not supported ts type */
        !           148:                        return FAILED;
        !           149:                }
        !           150:        }
        !           151: 
        !           152:        return SUCCESS;
        !           153: }
        !           154: 
        !           155: METHOD(payload_t, get_encoding_rules, int,
        !           156:        private_traffic_selector_substructure_t *this, encoding_rule_t **rules)
        !           157: {
        !           158:        *rules = encodings;
        !           159:        return countof(encodings);
        !           160: }
        !           161: 
        !           162: METHOD(payload_t, get_header_length, int,
        !           163:        private_traffic_selector_substructure_t *this)
        !           164: {
        !           165:        return 8;
        !           166: }
        !           167: 
        !           168: METHOD(payload_t, get_type, payload_type_t,
        !           169:        private_traffic_selector_substructure_t *this)
        !           170: {
        !           171:        return PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE;
        !           172: }
        !           173: 
        !           174: METHOD(payload_t, get_next_type, payload_type_t,
        !           175:        private_traffic_selector_substructure_t *this)
        !           176: {
        !           177:        return PL_NONE;
        !           178: }
        !           179: 
        !           180: METHOD(payload_t, set_next_type, void,
        !           181:        private_traffic_selector_substructure_t *this,payload_type_t type)
        !           182: {
        !           183: }
        !           184: 
        !           185: METHOD(payload_t, get_length, size_t,
        !           186:        private_traffic_selector_substructure_t *this)
        !           187: {
        !           188:        return this->payload_length;
        !           189: }
        !           190: 
        !           191: METHOD(traffic_selector_substructure_t, get_traffic_selector, traffic_selector_t*,
        !           192:        private_traffic_selector_substructure_t *this)
        !           193: {
        !           194:        return traffic_selector_create_from_bytes(
        !           195:                                                                        this->ip_protocol_id, this->ts_type,
        !           196:                                                                        this->starting_address, this->start_port,
        !           197:                                                                        this->ending_address, this->end_port);
        !           198: }
        !           199: 
        !           200: METHOD2(payload_t, traffic_selector_substructure_t, destroy, void,
        !           201:        private_traffic_selector_substructure_t *this)
        !           202: {
        !           203:        free(this->starting_address.ptr);
        !           204:        free(this->ending_address.ptr);
        !           205:        free(this);
        !           206: }
        !           207: 
        !           208: /*
        !           209:  * Described in header
        !           210:  */
        !           211: traffic_selector_substructure_t *traffic_selector_substructure_create()
        !           212: {
        !           213:        private_traffic_selector_substructure_t *this;
        !           214: 
        !           215:        INIT(this,
        !           216:                .public = {
        !           217:                        .payload_interface = {
        !           218:                                .verify = _verify,
        !           219:                                .get_encoding_rules = _get_encoding_rules,
        !           220:                                .get_header_length = _get_header_length,
        !           221:                                .get_length = _get_length,
        !           222:                                .get_next_type = _get_next_type,
        !           223:                                .set_next_type = _set_next_type,
        !           224:                                .get_type = _get_type,
        !           225:                                .destroy = _destroy,
        !           226:                        },
        !           227:                        .get_traffic_selector = _get_traffic_selector,
        !           228:                        .destroy = _destroy,
        !           229:                },
        !           230:                .payload_length = get_header_length(this),
        !           231:                /* must be set to be valid */
        !           232:                .ts_type = TS_IPV4_ADDR_RANGE,
        !           233:        );
        !           234:        return &this->public;
        !           235: }
        !           236: 
        !           237: /*
        !           238:  * Described in header
        !           239:  */
        !           240: traffic_selector_substructure_t *traffic_selector_substructure_create_from_traffic_selector(
        !           241:                                                                                                        traffic_selector_t *ts)
        !           242: {
        !           243:        private_traffic_selector_substructure_t *this;
        !           244: 
        !           245:        this = (private_traffic_selector_substructure_t*)traffic_selector_substructure_create();
        !           246:        this->ts_type = ts->get_type(ts);
        !           247:        this->ip_protocol_id = ts->get_protocol(ts);
        !           248:        this->start_port = ts->get_from_port(ts);
        !           249:        this->end_port = ts->get_to_port(ts);
        !           250:        this->starting_address = chunk_clone(ts->get_from_address(ts));
        !           251:        this->ending_address = chunk_clone(ts->get_to_address(ts));
        !           252:        this->payload_length = get_header_length(this) +
        !           253:                                                this->ending_address.len + this->starting_address.len;
        !           254: 
        !           255:        return &this->public;
        !           256: }

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