Annotation of embedaddon/strongswan/src/libcharon/tests/utils/mock_ipsec.c, revision 1.1.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>