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>