sub-component depth from pts database on component evidence request
[strongswan.git] / src / libpts / pts / components / pts_component_manager.c
1 /*
2 * Copyright (C) 2011 Andreas Steffen
3 *
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 "pts/components/pts_component_manager.h"
18
19 #include <utils/linked_list.h>
20 #include <debug.h>
21
22 typedef struct private_pts_component_manager_t private_pts_component_manager_t;
23 typedef struct vendor_entry_t vendor_entry_t;
24 typedef struct component_entry_t component_entry_t;
25
26 #define PTS_QUALIFIER_SIZE 6
27
28 /**
29 * Vendor-specific namespace information and list of registered components
30 */
31 struct vendor_entry_t {
32
33 /**
34 * Vendor ID
35 */
36 pen_t vendor_id;
37
38 /**
39 * Vendor-specific Component Functional names
40 */
41 enum_name_t *comp_func_names;
42
43 /**
44 * Vendor-specific Qualifier Type names
45 */
46 enum_name_t *qualifier_type_names;
47
48 /**
49 * Vendor-specific Qualifier Flag names
50 */
51 char *qualifier_flag_names;
52
53 /**
54 * Vendor-specific size of Qualfiier Type field
55 */
56 int qualifier_type_size;
57
58 /**
59 * List of vendor-specific registered Functional Components
60 */
61 linked_list_t *components;
62 };
63
64 /**
65 * Destroy a vendor_entry_t object
66 */
67 static void vendor_entry_destroy(vendor_entry_t *entry)
68 {
69 entry->components->destroy_function(entry->components, free);
70 free(entry);
71 }
72
73 /**
74 * Creation method for a vendor-specific Functional Component
75 */
76 struct component_entry_t {
77
78 /**
79 * Vendor-Specific Component Functional Name
80 */
81 u_int32_t name;
82
83 /**
84 * Functional Component creation method
85 */
86 pts_component_create_t create;
87 };
88
89 /**
90 * Private data of a pts_component_manager_t object.
91 *
92 */
93 struct private_pts_component_manager_t {
94
95 /**
96 * Public pts_component_manager_t interface.
97 */
98 pts_component_manager_t public;
99
100 /**
101 * List of vendor-specific namespaces and registered components
102 */
103 linked_list_t *list;
104 };
105
106 METHOD(pts_component_manager_t, add_vendor, void,
107 private_pts_component_manager_t *this, pen_t vendor_id,
108 enum_name_t *comp_func_names, int qualifier_type_size,
109 char *qualifier_flag_names, enum_name_t *qualifier_type_names)
110 {
111 vendor_entry_t *entry;
112
113 entry = malloc_thing(vendor_entry_t);
114 entry->vendor_id = vendor_id;
115 entry->comp_func_names = comp_func_names;
116 entry->qualifier_type_size = qualifier_type_size;
117 entry->qualifier_flag_names = qualifier_flag_names;
118 entry->qualifier_type_names = qualifier_type_names;
119 entry->components = linked_list_create();
120
121 this->list->insert_last(this->list, entry);
122 DBG2(DBG_PTS, "added %N functional component namespace",
123 pen_names, vendor_id);
124 }
125
126 METHOD(pts_component_manager_t, get_comp_func_names, enum_name_t*,
127 private_pts_component_manager_t *this, pen_t vendor_id)
128 {
129 enumerator_t *enumerator;
130 vendor_entry_t *entry;
131 enum_name_t *names = NULL;
132
133 enumerator = this->list->create_enumerator(this->list);
134 while (enumerator->enumerate(enumerator, &entry))
135 {
136 if (entry->vendor_id == vendor_id)
137 {
138 names = entry->comp_func_names;
139 break;
140 }
141 }
142 enumerator->destroy(enumerator);
143
144 return names;
145 }
146
147 METHOD(pts_component_manager_t, get_qualifier_type_names, enum_name_t*,
148 private_pts_component_manager_t *this, pen_t vendor_id)
149 {
150 enumerator_t *enumerator;
151 vendor_entry_t *entry;
152 enum_name_t *names = NULL;
153
154 enumerator = this->list->create_enumerator(this->list);
155 while (enumerator->enumerate(enumerator, &entry))
156 {
157 if (entry->vendor_id == vendor_id)
158 {
159 names = entry->qualifier_type_names;
160 break;
161 }
162 }
163 enumerator->destroy(enumerator);
164
165 return names;
166 }
167
168 METHOD(pts_component_manager_t, add_component, void,
169 private_pts_component_manager_t *this, pen_t vendor_id, u_int32_t name,
170 pts_component_create_t create)
171 {
172 enumerator_t *enumerator;
173 vendor_entry_t *entry;
174 component_entry_t *component;
175
176 enumerator = this->list->create_enumerator(this->list);
177 while (enumerator->enumerate(enumerator, &entry))
178 {
179 if (entry->vendor_id == vendor_id)
180 {
181 component = malloc_thing(component_entry_t);
182 component->name = name;
183 component->create = create;
184
185 entry->components->insert_last(entry->components, component);
186 DBG2(DBG_PTS, "added %N functional component '%N'",
187 pen_names, vendor_id,
188 get_comp_func_names(this, vendor_id), name);
189 }
190 }
191 enumerator->destroy(enumerator);
192 }
193
194 METHOD(pts_component_manager_t, remove_vendor, void,
195 private_pts_component_manager_t *this, pen_t vendor_id)
196 {
197 enumerator_t *enumerator;
198 vendor_entry_t *entry;
199
200 enumerator = this->list->create_enumerator(this->list);
201 while (enumerator->enumerate(enumerator, &entry))
202 {
203 if (entry->vendor_id == vendor_id)
204 {
205 this->list->remove_at(this->list, enumerator);
206 vendor_entry_destroy(entry);
207 DBG2(DBG_PTS, "removed %N functional component namespace",
208 pen_names, vendor_id);
209 }
210 }
211 enumerator->destroy(enumerator);
212 }
213
214 METHOD(pts_component_manager_t, get_qualifier, u_int8_t,
215 private_pts_component_manager_t *this, pts_comp_func_name_t *name,
216 char *flags)
217 {
218 enumerator_t *enumerator;
219 vendor_entry_t *entry;
220 u_int8_t qualifier, size, flag, type = 0;
221 int i;
222
223 enumerator = this->list->create_enumerator(this->list);
224 while (enumerator->enumerate(enumerator, &entry))
225 {
226 if (entry->vendor_id == name->get_vendor_id(name))
227 {
228 qualifier = name->get_qualifier(name);
229 size = entry->qualifier_type_size;
230
231 /* mask qualifier type field */
232 type = qualifier & ((1 << size) - 1);
233
234 /* determine flags */
235 size = PTS_QUALIFIER_SIZE - size;
236 flag = (1 << (PTS_QUALIFIER_SIZE - 1));
237 if (flags)
238 {
239 for (i = 0 ; i < size; i++)
240 {
241 flags[i] = (qualifier & flag) ?
242 entry->qualifier_flag_names[i] : '.';
243 flag >>= 1;
244 }
245 flags[size] = '\0';
246 }
247 }
248 }
249 enumerator->destroy(enumerator);
250
251 return type;
252 }
253
254 METHOD(pts_component_manager_t, create, pts_component_t*,
255 private_pts_component_manager_t *this,
256 pts_comp_func_name_t *name, u_int32_t depth)
257 {
258 enumerator_t *enumerator, *e2;
259 vendor_entry_t *entry;
260 component_entry_t *entry2;
261 pts_component_t *component = NULL;
262
263 enumerator = this->list->create_enumerator(this->list);
264 while (enumerator->enumerate(enumerator, &entry))
265 {
266 if (entry->vendor_id == name->get_vendor_id(name))
267 {
268 e2 = entry->components->create_enumerator(entry->components);
269 while (e2->enumerate(e2, &entry2))
270 {
271 if (entry2->name == name->get_name(name) && entry2->create)
272 {
273 component = entry2->create(name->get_qualifier(name), depth);
274 break;
275 }
276 }
277 e2->destroy(e2);
278 break;
279 }
280 }
281 enumerator->destroy(enumerator);
282
283 return component;
284 }
285
286 METHOD(pts_component_manager_t, destroy, void,
287 private_pts_component_manager_t *this)
288 {
289 this->list->destroy_function(this->list, (void *)vendor_entry_destroy);
290 free(this);
291 }
292
293 /**
294 * See header
295 */
296 pts_component_manager_t *pts_component_manager_create(void)
297 {
298 private_pts_component_manager_t *this;
299
300 INIT(this,
301 .public = {
302 .add_vendor = _add_vendor,
303 .add_component = _add_component,
304 .remove_vendor = _remove_vendor,
305 .get_comp_func_names = _get_comp_func_names,
306 .get_qualifier_type_names = _get_qualifier_type_names,
307 .get_qualifier = _get_qualifier,
308 .create = _create,
309 .destroy = _destroy,
310 },
311 .list = linked_list_create(),
312 );
313
314 return &this->public;
315 }
316