Annotation of embedaddon/strongswan/src/libcharon/encoding/payloads/ts_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 "ts_payload.h"
                     21: 
                     22: #include <encoding/payloads/encodings.h>
                     23: #include <collections/linked_list.h>
                     24: 
                     25: typedef struct private_ts_payload_t private_ts_payload_t;
                     26: 
                     27: /**
                     28:  * Private data of an ts_payload_t object.
                     29:  */
                     30: struct private_ts_payload_t {
                     31: 
                     32:        /**
                     33:         * Public ts_payload_t interface.
                     34:         */
                     35:        ts_payload_t public;
                     36: 
                     37:        /**
                     38:         * TRUE if this TS payload is of type TSi, FALSE for TSr.
                     39:         */
                     40:        bool is_initiator;
                     41: 
                     42:        /**
                     43:         * Next payload type.
                     44:         */
                     45:        uint8_t  next_payload;
                     46: 
                     47:        /**
                     48:         * Critical flag.
                     49:         */
                     50:        bool critical;
                     51: 
                     52:        /**
                     53:         * reserved bits
                     54:         */
                     55:        bool reserved_bit[7];
                     56: 
                     57:        /**
                     58:         * reserved bytes
                     59:         */
                     60:        bool reserved_byte[3];
                     61: 
                     62:        /**
                     63:         * Length of this payload.
                     64:         */
                     65:        uint16_t payload_length;
                     66: 
                     67:        /**
                     68:         * Number of traffic selectors
                     69:         */
                     70:        uint8_t ts_num;
                     71: 
                     72:        /**
                     73:         * Contains the traffic selectors of type traffic_selector_substructure_t.
                     74:         */
                     75:        linked_list_t *substrs;
                     76: };
                     77: 
                     78: /**
                     79:  * Encoding rules to parse or generate a TS payload
                     80:  *
                     81:  * The defined offsets are the positions in a object of type
                     82:  * private_ts_payload_t.
                     83:  */
                     84: static encoding_rule_t encodings[] = {
                     85:        /* 1 Byte next payload type, stored in the field next_payload */
                     86:        { U_INT_8,                      offsetof(private_ts_payload_t, next_payload)    },
                     87:        /* the critical bit */
                     88:        { FLAG,                         offsetof(private_ts_payload_t, critical)                },
                     89:        /* 7 Bit reserved bits */
                     90:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[0]) },
                     91:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[1]) },
                     92:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[2]) },
                     93:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[3]) },
                     94:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[4]) },
                     95:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[5]) },
                     96:        { RESERVED_BIT,         offsetof(private_ts_payload_t, reserved_bit[6]) },
                     97:        /* Length of the whole payload*/
                     98:        { PAYLOAD_LENGTH,       offsetof(private_ts_payload_t, payload_length)  },
                     99:        /* 1 Byte TS type*/
                    100:        { U_INT_8,                      offsetof(private_ts_payload_t, ts_num)                  },
                    101:        /* 3 reserved bytes */
                    102:        { RESERVED_BYTE,        offsetof(private_ts_payload_t, reserved_byte[0])},
                    103:        { RESERVED_BYTE,        offsetof(private_ts_payload_t, reserved_byte[1])},
                    104:        { RESERVED_BYTE,        offsetof(private_ts_payload_t, reserved_byte[2])},
                    105:        /* wrapped list of traffic selectors substructures */
                    106:        { PAYLOAD_LIST + PLV2_TRAFFIC_SELECTOR_SUBSTRUCTURE,
                    107:                                                offsetof(private_ts_payload_t, substrs)                 },
                    108: };
                    109: 
                    110: /*
                    111:                            1                   2                   3
                    112:        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
                    113:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    114:       ! Next Payload  !C!  RESERVED   !         Payload Length        !
                    115:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    116:       ! Number of TSs !                 RESERVED                      !
                    117:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    118:       !                                                               !
                    119:       ~                       <Traffic Selectors>                     ~
                    120:       !                                                               !
                    121:       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    122: */
                    123: 
                    124: METHOD(payload_t, verify, status_t,
                    125:        private_ts_payload_t *this)
                    126: {
                    127:        enumerator_t *enumerator;
                    128:        payload_t *substr;
                    129:        status_t status = SUCCESS;
                    130: 
                    131:        if (this->ts_num != this->substrs->get_count(this->substrs))
                    132:        {
                    133:                return FAILED;
                    134:        }
                    135:        enumerator = this->substrs->create_enumerator(this->substrs);
                    136:        while (enumerator->enumerate(enumerator, &substr))
                    137:        {
                    138:                status = substr->verify(substr);
                    139:                if (status != SUCCESS)
                    140:                {
                    141:                        break;
                    142:                }
                    143:        }
                    144:        enumerator->destroy(enumerator);
                    145: 
                    146:        return status;
                    147: }
                    148: 
                    149: METHOD(payload_t, get_encoding_rules, int,
                    150:        private_ts_payload_t *this, encoding_rule_t **rules)
                    151: {
                    152:        *rules = encodings;
                    153:        return countof(encodings);
                    154: }
                    155: 
                    156: METHOD(payload_t, get_header_length, int,
                    157:        private_ts_payload_t *this)
                    158: {
                    159:        return 8;
                    160: }
                    161: 
                    162: METHOD(payload_t, get_type, payload_type_t,
                    163:        private_ts_payload_t *this)
                    164: {
                    165:        if (this->is_initiator)
                    166:        {
                    167:                return PLV2_TS_INITIATOR;
                    168:        }
                    169:        return PLV2_TS_RESPONDER;
                    170: }
                    171: 
                    172: METHOD(payload_t, get_next_type, payload_type_t,
                    173:        private_ts_payload_t *this)
                    174: {
                    175:        return this->next_payload;
                    176: }
                    177: 
                    178: METHOD(payload_t, set_next_type, void,
                    179:        private_ts_payload_t *this,payload_type_t type)
                    180: {
                    181:        this->next_payload = type;
                    182: }
                    183: 
                    184: /**
                    185:  * recompute the length of the payload.
                    186:  */
                    187: static void compute_length(private_ts_payload_t *this)
                    188: {
                    189:        enumerator_t *enumerator;
                    190:        payload_t *subst;
                    191: 
                    192:        this->payload_length = get_header_length(this);
                    193:        this->ts_num = 0;
                    194:        enumerator = this->substrs->create_enumerator(this->substrs);
                    195:        while (enumerator->enumerate(enumerator, &subst))
                    196:        {
                    197:                this->payload_length += subst->get_length(subst);
                    198:                this->ts_num++;
                    199:        }
                    200:        enumerator->destroy(enumerator);
                    201: }
                    202: 
                    203: METHOD(payload_t, get_length, size_t,
                    204:        private_ts_payload_t *this)
                    205: {
                    206:        return this->payload_length;
                    207: }
                    208: 
                    209: METHOD(ts_payload_t, get_initiator, bool,
                    210:        private_ts_payload_t *this)
                    211: {
                    212:        return this->is_initiator;
                    213: }
                    214: 
                    215: METHOD(ts_payload_t, set_initiator, void,
                    216:        private_ts_payload_t *this,bool is_initiator)
                    217: {
                    218:        this->is_initiator = is_initiator;
                    219: }
                    220: 
                    221: METHOD(ts_payload_t, get_traffic_selectors, linked_list_t*,
                    222:        private_ts_payload_t *this)
                    223: {
                    224:        traffic_selector_t *ts;
                    225:        enumerator_t *enumerator;
                    226:        traffic_selector_substructure_t *subst;
                    227:        linked_list_t *list;
                    228: 
                    229:        list = linked_list_create();
                    230:        enumerator = this->substrs->create_enumerator(this->substrs);
                    231:        while (enumerator->enumerate(enumerator, &subst))
                    232:        {
                    233:                ts = subst->get_traffic_selector(subst);
                    234:                list->insert_last(list, ts);
                    235:        }
                    236:        enumerator->destroy(enumerator);
                    237: 
                    238:        return list;
                    239: }
                    240: 
                    241: METHOD2(payload_t, ts_payload_t, destroy, void,
                    242:        private_ts_payload_t *this)
                    243: {
                    244:        this->substrs->destroy_offset(this->substrs, offsetof(payload_t, destroy));
                    245:        free(this);
                    246: }
                    247: 
                    248: /*
                    249:  * Described in header
                    250:  */
                    251: ts_payload_t *ts_payload_create(bool is_initiator)
                    252: {
                    253:        private_ts_payload_t *this;
                    254: 
                    255:        INIT(this,
                    256:                .public = {
                    257:                        .payload_interface = {
                    258:                                .verify = _verify,
                    259:                                .get_encoding_rules = _get_encoding_rules,
                    260:                                .get_header_length = _get_header_length,
                    261:                                .get_length = _get_length,
                    262:                                .get_next_type = _get_next_type,
                    263:                                .set_next_type = _set_next_type,
                    264:                                .get_type = _get_type,
                    265:                                .destroy = _destroy,
                    266:                        },
                    267:                        .get_initiator = _get_initiator,
                    268:                        .set_initiator = _set_initiator,
                    269:                        .get_traffic_selectors = _get_traffic_selectors,
                    270:                        .destroy = _destroy,
                    271:                },
                    272:                .next_payload = PL_NONE,
                    273:                .payload_length = get_header_length(this),
                    274:                .is_initiator = is_initiator,
                    275:                .substrs = linked_list_create(),
                    276:        );
                    277:        return &this->public;
                    278: }
                    279: 
                    280: /*
                    281:  * Described in header
                    282:  */
                    283: ts_payload_t *ts_payload_create_from_traffic_selectors(bool is_initiator,
                    284:                                                                                        linked_list_t *traffic_selectors)
                    285: {
                    286:        enumerator_t *enumerator;
                    287:        traffic_selector_t *ts;
                    288:        traffic_selector_substructure_t *subst;
                    289:        private_ts_payload_t *this;
                    290: 
                    291:        this = (private_ts_payload_t*)ts_payload_create(is_initiator);
                    292: 
                    293:        enumerator = traffic_selectors->create_enumerator(traffic_selectors);
                    294:        while (enumerator->enumerate(enumerator, &ts))
                    295:        {
                    296:                subst = traffic_selector_substructure_create_from_traffic_selector(ts);
                    297:                this->substrs->insert_last(this->substrs, subst);
                    298:        }
                    299:        enumerator->destroy(enumerator);
                    300:        compute_length(this);
                    301: 
                    302:        return &this->public;
                    303: }

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