Annotation of embedaddon/strongswan/src/libcharon/tests/utils/mock_ipsec.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2016-2017 Tobias Brunner
        !             3:  * Copyright (C) 2008 Martin Willi
        !             4:  * HSR Hochschule fuer Technik Rapperswil
        !             5:  *
        !             6:  * This program is free software; you can redistribute it and/or modify it
        !             7:  * under the terms of the GNU General Public License as published by the
        !             8:  * Free Software Foundation; either version 2 of the License, or (at your
        !             9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
        !            10:  *
        !            11:  * This program is distributed in the hope that it will be useful, but
        !            12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
        !            13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
        !            14:  * for more details.
        !            15:  */
        !            16: 
        !            17: #include "mock_ipsec.h"
        !            18: 
        !            19: #include <daemon.h>
        !            20: #include <collections/hashtable.h>
        !            21: #include <collections/array.h>
        !            22: 
        !            23: #include <assert.h>
        !            24: 
        !            25: typedef struct private_kernel_ipsec_t private_kernel_ipsec_t;
        !            26: 
        !            27: /**
        !            28:  * Private data
        !            29:  */
        !            30: struct private_kernel_ipsec_t {
        !            31: 
        !            32:        /**
        !            33:         * Public interface
        !            34:         */
        !            35:        kernel_ipsec_t public;
        !            36: 
        !            37:        /**
        !            38:         * Rekey listener
        !            39:         */
        !            40:        listener_t listener;
        !            41: 
        !            42:        /**
        !            43:         * Allocated SPI
        !            44:         */
        !            45:        refcount_t spi;
        !            46: 
        !            47:        /**
        !            48:         * Installed SAs
        !            49:         */
        !            50:        hashtable_t *sas;
        !            51: };
        !            52: 
        !            53: /**
        !            54:  * Global instance
        !            55:  */
        !            56: static private_kernel_ipsec_t *instance;
        !            57: 
        !            58: /**
        !            59:  * Data about installed IPsec SAs
        !            60:  */
        !            61: typedef struct {
        !            62:        /**
        !            63:         * SPI of the SA
        !            64:         */
        !            65:        uint32_t spi;
        !            66: 
        !            67:        /**
        !            68:         * Associated IKE_SA
        !            69:         */
        !            70:        ike_sa_t *ike_sa;
        !            71: 
        !            72:        /**
        !            73:         * TRUE if this was an allocated SPI
        !            74:         */
        !            75:        bool alloc;
        !            76: 
        !            77: } entry_t;
        !            78: 
        !            79: /**
        !            80:  * Hash an IPsec SA entry
        !            81:  */
        !            82: static u_int entry_hash(const void *key)
        !            83: {
        !            84:        entry_t *entry = (entry_t*)key;
        !            85:        return chunk_hash_inc(chunk_from_thing(entry->spi),
        !            86:                                                  chunk_hash(chunk_from_thing(entry->ike_sa)));
        !            87: }
        !            88: 
        !            89: /**
        !            90:  * Compare an IPsec SA entry
        !            91:  */
        !            92: static bool entry_equals(const void *key, const void *other_key)
        !            93: {
        !            94:        entry_t *a = (entry_t*)key, *b = (entry_t*)other_key;
        !            95:        return a->spi == b->spi && a->ike_sa == b->ike_sa;
        !            96: }
        !            97: 
        !            98: METHOD(kernel_ipsec_t, get_spi, status_t,
        !            99:        private_kernel_ipsec_t *this, host_t *src, host_t *dst, uint8_t protocol,
        !           100:        uint32_t *spi)
        !           101: {
        !           102:        entry_t *entry;
        !           103: 
        !           104:        *spi = (uint32_t)ref_get(&this->spi);
        !           105:        INIT(entry,
        !           106:                .spi = *spi,
        !           107:                .ike_sa = charon->bus->get_sa(charon->bus),
        !           108:                .alloc = TRUE,
        !           109:        );
        !           110:        entry = this->sas->put(this->sas, entry, entry);
        !           111:        assert(!entry);
        !           112:        return SUCCESS;
        !           113: }
        !           114: 
        !           115: METHOD(kernel_ipsec_t, get_cpi, status_t,
        !           116:        private_kernel_ipsec_t *this, host_t *src, host_t *dst, uint16_t *cpi)
        !           117: {
        !           118:        return FAILED;
        !           119: }
        !           120: 
        !           121: METHOD(kernel_ipsec_t, add_sa, status_t,
        !           122:        private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id,
        !           123:        kernel_ipsec_add_sa_t *data)
        !           124: {
        !           125:        entry_t *entry;
        !           126: 
        !           127:        INIT(entry,
        !           128:                .spi = id->spi,
        !           129:                .ike_sa = charon->bus->get_sa(charon->bus),
        !           130:        );
        !           131:        if (data->inbound)
        !           132:        {
        !           133:                entry = this->sas->put(this->sas, entry, entry);
        !           134:                assert(entry && entry->alloc);
        !           135:                free(entry);
        !           136:        }
        !           137:        else
        !           138:        {
        !           139:                entry = this->sas->put(this->sas, entry, entry);
        !           140:                assert(!entry);
        !           141:        }
        !           142:        return SUCCESS;
        !           143: }
        !           144: 
        !           145: METHOD(kernel_ipsec_t, update_sa, status_t,
        !           146:        private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id,
        !           147:        kernel_ipsec_update_sa_t *data)
        !           148: {
        !           149:        return SUCCESS;
        !           150: }
        !           151: 
        !           152: METHOD(kernel_ipsec_t, query_sa, status_t,
        !           153:        private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id,
        !           154:        kernel_ipsec_query_sa_t *data, uint64_t *bytes, uint64_t *packets,
        !           155:        time_t *time)
        !           156: {
        !           157:        return NOT_SUPPORTED;
        !           158: }
        !           159: 
        !           160: METHOD(kernel_ipsec_t, del_sa, status_t,
        !           161:        private_kernel_ipsec_t *this, kernel_ipsec_sa_id_t *id,
        !           162:        kernel_ipsec_del_sa_t *data)
        !           163: {
        !           164:        entry_t *entry, lookup = {
        !           165:                .spi = id->spi,
        !           166:                .ike_sa = charon->bus->get_sa(charon->bus),
        !           167:        };
        !           168: 
        !           169:        entry = this->sas->remove(this->sas, &lookup);
        !           170:        assert(entry);
        !           171:        free(entry);
        !           172:        return SUCCESS;
        !           173: }
        !           174: 
        !           175: METHOD(listener_t, ike_rekey, bool,
        !           176:        listener_t *listener, ike_sa_t *old, ike_sa_t *new)
        !           177: {
        !           178:        enumerator_t *enumerator;
        !           179:        array_t *sas = NULL;
        !           180:        entry_t *entry;
        !           181: 
        !           182:        enumerator = instance->sas->create_enumerator(instance->sas);
        !           183:        while (enumerator->enumerate(enumerator, &entry, NULL))
        !           184:        {
        !           185:                if (entry->ike_sa == old)
        !           186:                {
        !           187:                        instance->sas->remove_at(instance->sas, enumerator);
        !           188:                        array_insert_create(&sas, ARRAY_TAIL, entry);
        !           189:                }
        !           190:        }
        !           191:        enumerator->destroy(enumerator);
        !           192:        enumerator = array_create_enumerator(sas);
        !           193:        while (enumerator->enumerate(enumerator, &entry))
        !           194:        {
        !           195:                array_remove_at(sas, enumerator);
        !           196:                entry->ike_sa = new;
        !           197:                entry = instance->sas->put(instance->sas, entry, entry);
        !           198:                assert(!entry);
        !           199:        }
        !           200:        enumerator->destroy(enumerator);
        !           201:        array_destroy(sas);
        !           202:        return TRUE;
        !           203: }
        !           204: 
        !           205: METHOD(kernel_ipsec_t, add_policy, status_t,
        !           206:        private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id,
        !           207:        kernel_ipsec_manage_policy_t *data)
        !           208: {
        !           209:        return SUCCESS;
        !           210: }
        !           211: 
        !           212: METHOD(kernel_ipsec_t, query_policy, status_t,
        !           213:        private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id,
        !           214:        kernel_ipsec_query_policy_t *data, time_t *use_time)
        !           215: {
        !           216:        *use_time = 1;
        !           217:        return SUCCESS;
        !           218: }
        !           219: 
        !           220: METHOD(kernel_ipsec_t, del_policy, status_t,
        !           221:        private_kernel_ipsec_t *this, kernel_ipsec_policy_id_t *id,
        !           222:        kernel_ipsec_manage_policy_t *data)
        !           223: {
        !           224:        return SUCCESS;
        !           225: }
        !           226: 
        !           227: METHOD(kernel_ipsec_t, destroy, void,
        !           228:        private_kernel_ipsec_t *this)
        !           229: {
        !           230:        charon->bus->remove_listener(charon->bus, &this->listener);
        !           231:        this->sas->destroy(this->sas);
        !           232:        free(this);
        !           233: }
        !           234: 
        !           235: /*
        !           236:  * Described in header
        !           237:  */
        !           238: kernel_ipsec_t *mock_ipsec_create()
        !           239: {
        !           240:        private_kernel_ipsec_t *this;
        !           241: 
        !           242:        INIT(this,
        !           243:                .public = {
        !           244:                        .get_spi = _get_spi,
        !           245:                        .get_cpi = _get_cpi,
        !           246:                        .add_sa = _add_sa,
        !           247:                        .update_sa = _update_sa,
        !           248:                        .query_sa = _query_sa,
        !           249:                        .del_sa = _del_sa,
        !           250:                        .flush_sas = (void*)return_failed,
        !           251:                        .add_policy = _add_policy,
        !           252:                        .query_policy = _query_policy,
        !           253:                        .del_policy = _del_policy,
        !           254:                        .flush_policies = (void*)return_failed,
        !           255:                        .bypass_socket = (void*)return_true,
        !           256:                        .enable_udp_decap = (void*)return_true,
        !           257:                        .destroy = _destroy,
        !           258:                },
        !           259:                .listener = {
        !           260:                        .ike_rekey = _ike_rekey,
        !           261:                },
        !           262:                .sas = hashtable_create(entry_hash, entry_equals, 8),
        !           263:        );
        !           264: 
        !           265:        instance = this;
        !           266: 
        !           267:        charon->bus->add_listener(charon->bus, &this->listener);
        !           268: 
        !           269:        return &this->public;
        !           270: }
        !           271: 
        !           272: 
        !           273: CALLBACK(filter_sas, bool,
        !           274:        void *data, enumerator_t *orig, va_list args)
        !           275: {
        !           276:        entry_t *entry;
        !           277:        ike_sa_t **ike_sa;
        !           278:        uint32_t *spi;
        !           279: 
        !           280:        VA_ARGS_VGET(args, ike_sa, spi);
        !           281: 
        !           282:        while (orig->enumerate(orig, &entry, NULL))
        !           283:        {
        !           284:                if (entry->alloc)
        !           285:                {
        !           286:                        continue;
        !           287:                }
        !           288:                *ike_sa = entry->ike_sa;
        !           289:                *spi = entry->spi;
        !           290:                return TRUE;
        !           291:        }
        !           292:        return FALSE;
        !           293: }
        !           294: 
        !           295: /*
        !           296:  * Described in header
        !           297:  */
        !           298: enumerator_t *mock_ipsec_create_sa_enumerator()
        !           299: {
        !           300:        return enumerator_create_filter(
        !           301:                                                        instance->sas->create_enumerator(instance->sas),
        !           302:                                                        filter_sas, NULL, NULL);
        !           303: }

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