aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-03-24 15:28:14 +0100
committerMartin Willi <martin@revosec.ch>2010-03-25 14:29:10 +0100
commitb262429e0b991ec8dbe7f7694c8f0418023f0fde (patch)
tree51012f3a4818c86cbf01b98a8d25c790274b8feb /src/libcharon
parent913eb696929d9c611cc9a85a0609c122467f696e (diff)
downloadstrongswan-b262429e0b991ec8dbe7f7694c8f0418023f0fde.tar.bz2
strongswan-b262429e0b991ec8dbe7f7694c8f0418023f0fde.tar.xz
Include configuration payloads for DNS/WINS server received via DHCP
Diffstat (limited to 'src/libcharon')
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_provider.c18
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_socket.c30
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_transaction.c62
-rw-r--r--src/libcharon/plugins/dhcp/dhcp_transaction.h17
4 files changed, 125 insertions, 2 deletions
diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c
index a3a289595..dbcceb6ce 100644
--- a/src/libcharon/plugins/dhcp/dhcp_provider.c
+++ b/src/libcharon/plugins/dhcp/dhcp_provider.c
@@ -131,7 +131,23 @@ METHOD(attribute_provider_t, release_address, bool,
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
private_dhcp_provider_t *this, identification_t *id, host_t *vip)
{
- return enumerator_create_empty();
+ dhcp_transaction_t *transaction;
+
+ if (!vip)
+ {
+ return NULL;
+ }
+ this->mutex->lock(this->mutex);
+ transaction = this->transactions->get(this->transactions,
+ (void*)hash_id_host(id, vip));
+ if (!transaction)
+ {
+ this->mutex->unlock(this->mutex);
+ return NULL;
+ }
+ return enumerator_create_cleaner(
+ transaction->create_attribute_enumerator(transaction),
+ (void*)this->mutex->unlock, this->mutex);
}
METHOD(dhcp_provider_t, destroy, void,
diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c
index b789e11ec..190024ce6 100644
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
@@ -446,7 +446,7 @@ METHOD(dhcp_socket_t, release, void,
*/
static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
{
- dhcp_transaction_t *transaction;
+ dhcp_transaction_t *transaction = NULL;
enumerator_t *enumerator;
host_t *offer, *server;
@@ -470,6 +470,34 @@ static void handle_offer(private_dhcp_socket_t *this, dhcp_t *dhcp, int optlen)
}
}
enumerator->destroy(enumerator);
+
+ if (transaction)
+ {
+ int optsize, optpos = 0, pos;
+ dhcp_option_t *option;
+
+ while (optlen > sizeof(dhcp_option_t))
+ {
+ option = (dhcp_option_t*)&dhcp->options[optpos];
+ optsize = sizeof(dhcp_option_t) + option->len;
+ if (option->type == DHCP_OPTEND || optlen < optsize)
+ {
+ break;
+ }
+ if (option->type == DHCP_DNS_SERVER ||
+ option->type == DHCP_NBNS_SERVER)
+ {
+ for (pos = 0; pos + 4 <= option->len; pos += 4)
+ {
+ transaction->add_attribute(transaction, option->type ==
+ DHCP_DNS_SERVER ? INTERNAL_IP4_DNS : INTERNAL_IP4_NBNS,
+ chunk_create((char*)&option->data[pos], 4));
+ }
+ }
+ optlen -= optsize;
+ optpos += optsize;
+ }
+ }
this->mutex->unlock(this->mutex);
this->condvar->broadcast(this->condvar);
offer->destroy(offer);
diff --git a/src/libcharon/plugins/dhcp/dhcp_transaction.c b/src/libcharon/plugins/dhcp/dhcp_transaction.c
index 27235ffb9..83f822dd8 100644
--- a/src/libcharon/plugins/dhcp/dhcp_transaction.c
+++ b/src/libcharon/plugins/dhcp/dhcp_transaction.c
@@ -15,6 +15,8 @@
#include "dhcp_transaction.h"
+#include <utils/linked_list.h>
+
typedef struct private_dhcp_transaction_t private_dhcp_transaction_t;
/**
@@ -46,8 +48,21 @@ struct private_dhcp_transaction_t {
* discovered DHCP server address
*/
host_t *server;
+
+ /**
+ * List of added attributes, as attribute_entry_t
+ */
+ linked_list_t *attributes;
};
+/**
+ * Entry for an added attribute
+ */
+typedef struct {
+ configuration_attribute_type_t type;
+ chunk_t data;
+} attribute_entry_t;
+
METHOD(dhcp_transaction_t, get_id, u_int32_t,
private_dhcp_transaction_t *this)
{
@@ -86,12 +101,56 @@ METHOD(dhcp_transaction_t, get_server, host_t*,
return this->server;
}
+METHOD(dhcp_transaction_t, add_attribute, void,
+ private_dhcp_transaction_t *this, configuration_attribute_type_t type,
+ chunk_t data)
+{
+ attribute_entry_t *entry;
+
+ INIT(entry,
+ .type = type,
+ .data = chunk_clone(data),
+ );
+ this->attributes->insert_last(this->attributes, entry);
+}
+
+/**
+ * Filter function to map entries to type/data
+ */
+static bool attribute_filter(void *null, attribute_entry_t **entry,
+ configuration_attribute_type_t *type,
+ void **dummy, chunk_t *data)
+{
+ *type = (*entry)->type;
+ *data = (*entry)->data;
+ return TRUE;
+}
+
+METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*,
+ private_dhcp_transaction_t *this)
+{
+ return enumerator_create_filter(
+ this->attributes->create_enumerator(this->attributes),
+ (void*)attribute_filter, NULL, NULL);
+}
+
+/**
+ * Clean up an attribute entry
+ */
+static void attribute_entry_destroy(attribute_entry_t *entry)
+{
+ free(entry->data.ptr);
+ free(entry);
+}
+
METHOD(dhcp_transaction_t, destroy, void,
private_dhcp_transaction_t *this)
{
this->identity->destroy(this->identity);
DESTROY_IF(this->address);
DESTROY_IF(this->server);
+ this->attributes->destroy_function(this->attributes,
+ (void*)attribute_entry_destroy);
free(this);
}
@@ -111,10 +170,13 @@ dhcp_transaction_t *dhcp_transaction_create(u_int32_t id,
.get_address = _get_address,
.set_server = _set_server,
.get_server = _get_server,
+ .add_attribute = _add_attribute,
+ .create_attribute_enumerator = _create_attribute_enumerator,
.destroy = _destroy,
},
.id = id,
.identity = identity->clone(identity),
+ .attributes = linked_list_create(),
);
return &this->public;
diff --git a/src/libcharon/plugins/dhcp/dhcp_transaction.h b/src/libcharon/plugins/dhcp/dhcp_transaction.h
index e20572064..19c163f88 100644
--- a/src/libcharon/plugins/dhcp/dhcp_transaction.h
+++ b/src/libcharon/plugins/dhcp/dhcp_transaction.h
@@ -23,6 +23,7 @@
#include <utils/host.h>
#include <utils/identification.h>
+#include <attributes/attributes.h>
typedef struct dhcp_transaction_t dhcp_transaction_t;
@@ -74,6 +75,22 @@ struct dhcp_transaction_t {
host_t* (*get_server)(dhcp_transaction_t *this);
/**
+ * An an additional attribute to serve to peer.
+ *
+ * @param type type of attribute
+ * @param data attribute data
+ */
+ void (*add_attribute)(dhcp_transaction_t *this,
+ configuration_attribute_type_t type, chunk_t data);
+
+ /**
+ * Create an enumerator over added attributes.
+ *
+ * @return enumerator over (configuration_attribute_t, chunk_t)
+ */
+ enumerator_t* (*create_attribute_enumerator)(dhcp_transaction_t *this);
+
+ /**
* Destroy a dhcp_transaction_t.
*/
void (*destroy)(dhcp_transaction_t *this);