2 * Copyright (C) 2010 Tobias Brunner
3 * Copyright (C) 2009 Martin Willi
4 * Hochschule fuer Technik Rapperswil
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>.
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
17 #include "attr_provider.h"
23 #include <utils/linked_list.h>
24 #include <threading/rwlock.h>
28 typedef struct private_attr_provider_t private_attr_provider_t
;
29 typedef struct attribute_entry_t attribute_entry_t
;
32 * private data of attr_provider
34 struct private_attr_provider_t
{
39 attr_provider_t
public;
42 * List of attributes, attribute_entry_t
44 linked_list_t
*attributes
;
47 * Lock for attribute list
52 struct attribute_entry_t
{
53 /** type of attribute */
54 configuration_attribute_type_t type
;
55 /** attribute value */
62 static void attribute_destroy(attribute_entry_t
*this)
64 free(this->value
.ptr
);
69 * convert enumerator value from attribute_entry
71 static bool attr_enum_filter(void *null
, attribute_entry_t
**in
,
72 configuration_attribute_type_t
*type
, void* none
, chunk_t
*value
)
75 *value
= (*in
)->value
;
79 METHOD(attribute_provider_t
, create_attribute_enumerator
, enumerator_t
*,
80 private_attr_provider_t
*this, char *pool
,
81 identification_t
*id
, host_t
*vip
)
85 this->lock
->read_lock(this->lock
);
86 return enumerator_create_filter(
87 this->attributes
->create_enumerator(this->attributes
),
88 (void*)attr_enum_filter
, this->lock
, (void*)this->lock
->unlock
);
90 return enumerator_create_empty();
93 METHOD(attr_provider_t
, destroy
, void,
94 private_attr_provider_t
*this)
96 this->attributes
->destroy_function(this->attributes
,
97 (void*)attribute_destroy
);
98 this->lock
->destroy(this->lock
);
103 * Add an attribute entry to the list
105 static void add_legacy_entry(private_attr_provider_t
*this, char *key
, int nr
,
106 configuration_attribute_type_t type
)
108 attribute_entry_t
*entry
;
112 str
= lib
->settings
->get_str(lib
->settings
, "%s.%s%d", NULL
, hydra
->daemon
,
116 host
= host_create_from_string(str
, 0);
119 entry
= malloc_thing(attribute_entry_t
);
121 if (host
->get_family(host
) == AF_INET6
)
125 case INTERNAL_IP4_DNS
:
126 type
= INTERNAL_IP6_DNS
;
128 case INTERNAL_IP4_NBNS
:
129 type
= INTERNAL_IP6_NBNS
;
136 entry
->value
= chunk_clone(host
->get_address(host
));
138 DBG2(DBG_CFG
, "loaded legacy entry attribute %N: %#B",
139 configuration_attribute_type_names
, entry
->type
, &entry
->value
);
140 this->attributes
->insert_last(this->attributes
, entry
);
146 * Key to attribute type mappings, for v4 and v6 attributes
150 configuration_attribute_type_t v4
;
151 configuration_attribute_type_t v6
;
153 {"address", INTERNAL_IP4_ADDRESS
, INTERNAL_IP6_ADDRESS
},
154 {"dns", INTERNAL_IP4_DNS
, INTERNAL_IP6_DNS
},
155 {"nbns", INTERNAL_IP4_NBNS
, INTERNAL_IP6_NBNS
},
156 {"dhcp", INTERNAL_IP4_DHCP
, INTERNAL_IP6_DHCP
},
157 {"netmask", INTERNAL_IP4_NETMASK
, INTERNAL_IP6_NETMASK
},
158 {"server", INTERNAL_IP4_SERVER
, INTERNAL_IP6_SERVER
},
159 {"subnet", INTERNAL_IP4_SUBNET
, INTERNAL_IP6_SUBNET
},
163 * Load (numerical) entries from the plugins.attr namespace
165 static void load_entries(private_attr_provider_t
*this)
167 enumerator_t
*enumerator
, *tokens
;
168 char *key
, *value
, *token
;
171 for (i
= 1; i
<= SERVER_MAX
; i
++)
173 add_legacy_entry(this, "dns", i
, INTERNAL_IP4_DNS
);
174 add_legacy_entry(this, "nbns", i
, INTERNAL_IP4_NBNS
);
177 enumerator
= lib
->settings
->create_key_value_enumerator(lib
->settings
,
178 "%s.plugins.attr", hydra
->daemon
);
179 while (enumerator
->enumerate(enumerator
, &key
, &value
))
181 configuration_attribute_type_t type
;
182 attribute_entry_t
*entry
;
188 tokens
= enumerator_create_token(value
, ",", " ");
189 while (tokens
->enumerate(tokens
, &token
))
191 pos
= strchr(token
, '/');
197 host
= host_create_from_string(token
, 0);
200 DBG1(DBG_CFG
, "invalid host in key %s: %s", key
, token
);
205 for (i
= 0; i
< countof(keys
); i
++)
207 if (streq(key
, keys
[i
].name
))
209 if (host
->get_family(host
) == AF_INET
)
221 DBG1(DBG_CFG
, "mapping attribute type %s failed", key
);
225 entry
= malloc_thing(attribute_entry_t
);
229 entry
->value
= chunk_clone(host
->get_address(host
));
233 if (host
->get_family(host
) == AF_INET
)
234 { /* IPv4 attributes contain a subnet mask */
238 netmask
= htonl((0xFFFFFFFF >> mask
) << mask
);
239 entry
->value
= chunk_cat("cc", host
->get_address(host
),
240 chunk_from_thing(netmask
));
243 { /* IPv6 addresses the prefix only */
244 entry
->value
= chunk_cat("cc", host
->get_address(host
),
245 chunk_from_chars(mask
));
249 DBG2(DBG_CFG
, "loaded attribute %N: %#B",
250 configuration_attribute_type_names
, entry
->type
, &entry
->value
);
251 this->attributes
->insert_last(this->attributes
, entry
);
253 tokens
->destroy(tokens
);
255 enumerator
->destroy(enumerator
);
258 METHOD(attr_provider_t
, reload
, void,
259 private_attr_provider_t
*this)
261 this->lock
->write_lock(this->lock
);
263 this->attributes
->destroy_function(this->attributes
, (void*)attribute_destroy
);
264 this->attributes
= linked_list_create();
268 DBG1(DBG_CFG
, "loaded %d entr%s for attr plugin configuration",
269 this->attributes
->get_count(this->attributes
),
270 this->attributes
->get_count(this->attributes
) == 1 ?
"y" : "ies");
272 this->lock
->unlock(this->lock
);
278 attr_provider_t
*attr_provider_create(database_t
*db
)
280 private_attr_provider_t
*this;
285 .acquire_address
= (void*)return_null
,
286 .release_address
= (void*)return_false
,
287 .create_attribute_enumerator
= _create_attribute_enumerator
,
292 .attributes
= linked_list_create(),
293 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
298 return &this->public;