diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libcharon/plugins/dhcp/Makefile.am | 5 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_plugin.c | 26 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_provider.c | 177 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_provider.h | 54 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_socket.c | 329 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_socket.h | 53 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_transaction.c | 101 | ||||
-rw-r--r-- | src/libcharon/plugins/dhcp/dhcp_transaction.h | 78 |
8 files changed, 822 insertions, 1 deletions
diff --git a/src/libcharon/plugins/dhcp/Makefile.am b/src/libcharon/plugins/dhcp/Makefile.am index d082a19c8..74afcb48a 100644 --- a/src/libcharon/plugins/dhcp/Makefile.am +++ b/src/libcharon/plugins/dhcp/Makefile.am @@ -9,6 +9,9 @@ else plugin_LTLIBRARIES = libstrongswan-dhcp.la endif -libstrongswan_dhcp_la_SOURCES = dhcp_plugin.h dhcp_plugin.c +libstrongswan_dhcp_la_SOURCES = dhcp_plugin.h dhcp_plugin.c \ + dhcp_provider.h dhcp_provider.c \ + dhcp_socket.h dhcp_socket.c \ + dhcp_transaction.h dhcp_transaction.c libstrongswan_dhcp_la_LDFLAGS = -module -avoid-version diff --git a/src/libcharon/plugins/dhcp/dhcp_plugin.c b/src/libcharon/plugins/dhcp/dhcp_plugin.c index 0f7ab041d..e3dae9bb6 100644 --- a/src/libcharon/plugins/dhcp/dhcp_plugin.c +++ b/src/libcharon/plugins/dhcp/dhcp_plugin.c @@ -17,6 +17,9 @@ #include <daemon.h> +#include "dhcp_socket.h" +#include "dhcp_provider.h" + typedef struct private_dhcp_plugin_t private_dhcp_plugin_t; /** @@ -28,11 +31,24 @@ struct private_dhcp_plugin_t { * implements plugin interface */ dhcp_plugin_t public; + + /** + * DHCP communication socket + */ + dhcp_socket_t *socket; + + /** + * Attribute provider + */ + dhcp_provider_t *provider; }; METHOD(plugin_t, destroy, void, private_dhcp_plugin_t *this) { + lib->attributes->remove_provider(lib->attributes, &this->provider->provider); + this->provider->destroy(this->provider); + this->socket->destroy(this->socket); free(this); } @@ -45,8 +61,18 @@ plugin_t *dhcp_plugin_create() INIT(this, .public.plugin.destroy = _destroy, + .socket = dhcp_socket_create(), ); + if (!this->socket) + { + free(this); + return NULL; + } + + this->provider = dhcp_provider_create(this->socket); + lib->attributes->add_provider(lib->attributes, &this->provider->provider); + return &this->public.plugin; } diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.c b/src/libcharon/plugins/dhcp/dhcp_provider.c new file mode 100644 index 000000000..a3e2690ca --- /dev/null +++ b/src/libcharon/plugins/dhcp/dhcp_provider.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "dhcp_provider.h" + +#include <utils/hashtable.h> +#include <threading/mutex.h> + +typedef struct private_dhcp_provider_t private_dhcp_provider_t; + +/** + * Private data of an dhcp_provider_t object. + */ +struct private_dhcp_provider_t { + + /** + * Public dhcp_provider_t interface. + */ + dhcp_provider_t public; + + /** + * Completed DHCP transactions + */ + hashtable_t *transactions; + + /** + * Lock for transactions + */ + mutex_t *mutex; + + /** + * DHCP communication socket + */ + dhcp_socket_t *socket; +}; + +/** + * Hashtable hash function + */ +static u_int hash(void *key) +{ + return (uintptr_t)key; +} + +/** + * Hashtable equals function + */ +static bool equals(void *a, void *b) +{ + return a == b; +} + +/** + * Hash ID and host to a key + */ +static uintptr_t hash_id_host(identification_t *id, host_t *host) +{ + return chunk_hash_inc(id->get_encoding(id), + chunk_hash(host->get_address(host))); +} + +/** + * Hash a DHCP transaction to a key, using address and id + */ +static uintptr_t hash_transaction(dhcp_transaction_t *transaction) +{ + return hash_id_host(transaction->get_identity(transaction), + transaction->get_address(transaction)); +} + +METHOD(attribute_provider_t, acquire_address, host_t*, + private_dhcp_provider_t *this, char *pool, + identification_t *id, host_t *requested) +{ + if (streq(pool, "dhcp")) + { + dhcp_transaction_t *transaction, *old; + host_t *vip; + + transaction = this->socket->enroll(this->socket, id); + if (!transaction) + { + return NULL; + } + vip = transaction->get_address(transaction); + vip = vip->clone(vip); + this->mutex->lock(this->mutex); + old = this->transactions->put(this->transactions, + (void*)hash_transaction(transaction), transaction); + this->mutex->unlock(this->mutex); + DESTROY_IF(old); + return vip; + } + return NULL; +} + +METHOD(attribute_provider_t, release_address, bool, + private_dhcp_provider_t *this, char *pool, + host_t *address, identification_t *id) +{ + if (streq(pool, "dhcp")) + { + dhcp_transaction_t *transaction; + + this->mutex->lock(this->mutex); + transaction = this->transactions->remove(this->transactions, + (void*)hash_id_host(id, address)); + this->mutex->unlock(this->mutex); + if (transaction) + { + transaction->destroy(transaction); + return TRUE; + } + } + return FALSE; +} + +METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*, + private_dhcp_provider_t *this, identification_t *id, host_t *vip) +{ + return enumerator_create_empty(); +} + +METHOD(dhcp_provider_t, destroy, void, + private_dhcp_provider_t *this) +{ + enumerator_t *enumerator; + dhcp_transaction_t *value; + void *key; + + enumerator = this->transactions->create_enumerator(this->transactions); + while (enumerator->enumerate(enumerator, &key, &value)) + { + value->destroy(value); + } + enumerator->destroy(enumerator); + this->transactions->destroy(this->transactions); + this->mutex->destroy(this->mutex); + free(this); +} + +/** + * See header + */ +dhcp_provider_t *dhcp_provider_create(dhcp_socket_t *socket) +{ + private_dhcp_provider_t *this; + + INIT(this, + .public = { + .provider = { + .acquire_address = _acquire_address, + .release_address = _release_address, + .create_attribute_enumerator = _create_attribute_enumerator, + }, + .destroy = _destroy, + }, + .socket = socket, + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .transactions = hashtable_create(hash, equals, 8), + ); + + return &this->public; +} + diff --git a/src/libcharon/plugins/dhcp/dhcp_provider.h b/src/libcharon/plugins/dhcp/dhcp_provider.h new file mode 100644 index 000000000..e720e876c --- /dev/null +++ b/src/libcharon/plugins/dhcp/dhcp_provider.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup dhcp_provider dhcp_provider + * @{ @ingroup dhcp + */ + +#ifndef DHCP_PROVIDER_H_ +#define DHCP_PROVIDER_H_ + +typedef struct dhcp_provider_t dhcp_provider_t; + +#include "dhcp_socket.h" + +#include <attributes/attribute_provider.h> + +/** + * DHCP based attribute provider. + */ +struct dhcp_provider_t { + + /** + * Implements attribute_provier_t interface. + */ + attribute_provider_t provider; + + /** + * Destroy a dhcp_provider_t. + */ + void (*destroy)(dhcp_provider_t *this); +}; + +/** + * Create a dhcp_provider instance. + * + * @param socket socket to use for DHCP communication + * @return provider instance + */ +dhcp_provider_t *dhcp_provider_create(dhcp_socket_t *socket); + +#endif /** DHCP_PROVIDER_H_ @}*/ diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.c b/src/libcharon/plugins/dhcp/dhcp_socket.c new file mode 100644 index 000000000..6ad600f1a --- /dev/null +++ b/src/libcharon/plugins/dhcp/dhcp_socket.c @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "dhcp_socket.h" + +#include <unistd.h> +#include <errno.h> +#include <string.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/udp.h> +#include <linux/if_arp.h> + +#include <utils/linked_list.h> +#include <utils/identification.h> +#include <threading/mutex.h> +#include <threading/condvar.h> +#include <threading/thread.h> + +#include <daemon.h> +#include <processing/jobs/callback_job.h> + +#define DHCP_SERVER_PORT 67 +#define DHCP_CLIENT_PORT 68 + +typedef struct private_dhcp_socket_t private_dhcp_socket_t; + +/** + * Private data of an dhcp_socket_t object. + */ +struct private_dhcp_socket_t { + + /** + * Public dhcp_socket_t interface. + */ + dhcp_socket_t public; + + /** + * Random number generator + */ + rng_t *rng; + + /** + * List of active transactions + */ + linked_list_t *active; + + /** + * List of successfully completed transactions + */ + linked_list_t *completed; + + /** + * Lock for transactions + */ + mutex_t *mutex; + + /** + * Condvar to wait for transaction completion + */ + condvar_t *condvar; + + /** + * Threads waiting in condvar + */ + int waiting; + + /** + * RAW socket + */ + int skt; + + /** + * DHCP server address, or broadcast + */ + host_t *dst; + + /** + * Callback job receiving DHCP responses + */ + callback_job_t *job; +}; + +typedef enum { + BOOTREQUEST = 1, + BOOTREPLY = 2, +} dhcp_opcode_t; + +typedef enum { + DHCP_HOST_NAME = 12, + DHCP_MESSAGE_TYPE = 53, + DHCP_PARAM_REQ_LIST = 55, +} dhcp_option_type_t; + +typedef enum { + DHCP_DISCOVER = 1, +} dhcp_message_type_t; + +typedef enum { + DHCP_ROUTER = 3, + DHCP_DNS_SERVER = 6, +} dhcp_parameter_t; + +typedef struct __attribute__((packed)) { + u_int8_t type; + u_int8_t len; + char data[]; +} dhcp_option_t; + +typedef struct __attribute__((packed)) { + u_int8_t opcode; + u_int8_t hw_type; + u_int8_t hw_addr_len; + u_int8_t hop_count; + u_int32_t transaction_id; + u_int16_t number_of_seconds; + u_int16_t flags; + u_int32_t client_address; + u_int32_t your_address; + u_int32_t server_address; + u_int32_t gateway_address; + char client_hw_addr[6]; + char client_hw_padding[10]; + char server_hostname[64]; + char boot_filename[128]; + u_int32_t magic_cookie; + char options[252]; +} dhcp_t; + +/** + * Send DHCP discover using a given transaction + */ +static void discover(private_dhcp_socket_t *this, + dhcp_transaction_t *transaction) +{ + chunk_t id_data, broadcast = chunk_from_chars(0xFF,0xFF,0xFF,0xFF); + identification_t *identity; + dhcp_option_t *option; + dhcp_t dhcp; + int optlen = 0; + u_int hash; + host_t *src; + ssize_t len; + + memset(&dhcp, 0, sizeof(dhcp)); + dhcp.opcode = BOOTREQUEST; + dhcp.hw_type = ARPHRD_ETHER; + dhcp.hw_addr_len = 6; + dhcp.transaction_id = transaction->get_id(transaction); + if (chunk_equals(broadcast, this->dst->get_address(this->dst))) + { + /* TODO: send with 0.0.0.0 source address */ + } + else + { + /* act as relay agent */ + src = charon->kernel_interface->get_source_addr( + charon->kernel_interface, this->dst, NULL); + if (src) + { + memcpy(&dhcp.gateway_address, src->get_address(src).ptr, + sizeof(dhcp.gateway_address)); + src->destroy(src); + } + } + + identity = transaction->get_identity(transaction); + id_data = identity->get_encoding(identity); + + /* magic bytes, a locally administered unicast MAC */ + dhcp.client_hw_addr[0] = 0x7A; + dhcp.client_hw_addr[1] = 0xA7; + /* with ID specific postfix */ + hash = htonl(chunk_hash(id_data)); + memcpy(&dhcp.client_hw_addr[2], &hash, 4); + + dhcp.magic_cookie = htonl(0x63825363); + + option = (dhcp_option_t*)&dhcp.options[optlen]; + option->type = DHCP_MESSAGE_TYPE; + option->len = 1; + option->data[0] = DHCP_DISCOVER; + optlen += sizeof(dhcp_option_t) + option->len; + + option = (dhcp_option_t*)&dhcp.options[optlen]; + option->type = DHCP_HOST_NAME; + option->len = min(id_data.len, 64); + memcpy(option->data, id_data.ptr, option->len); + optlen += sizeof(dhcp_option_t) + option->len; + + option = (dhcp_option_t*)&dhcp.options[optlen]; + option->type = DHCP_PARAM_REQ_LIST; + option->len = 2; + option->data[0] = DHCP_ROUTER; + option->data[1] = DHCP_DNS_SERVER; + optlen += sizeof(dhcp_option_t) + option->len; + + dhcp.options[optlen++] = 0xFF; + + len = offsetof(dhcp_t, magic_cookie) + ((optlen + 4) / 64 * 64 + 64); + if (sendto(this->skt, &dhcp, len, 0, this->dst->get_sockaddr(this->dst), + *this->dst->get_sockaddr_len(this->dst)) != len) + { + DBG1(DBG_CFG, "sending DHCP DISCOVER failed: %s", strerror(errno)); + } +} + +METHOD(dhcp_socket_t, enroll, dhcp_transaction_t*, + private_dhcp_socket_t *this, identification_t *identity) +{ + dhcp_transaction_t *transaction; + u_int32_t id; + + this->rng->get_bytes(this->rng, sizeof(id), (u_int8_t*)&id); + transaction = dhcp_transaction_create(id, identity); + discover(this, transaction); + transaction->destroy(transaction); + + return NULL; +} + +METHOD(dhcp_socket_t, destroy, void, + private_dhcp_socket_t *this) +{ + if (this->job) + { + this->job->cancel(this->job); + } + while (this->waiting) + { + this->condvar->signal(this->condvar); + } + if (this->skt > 0) + { + close(this->skt); + } + this->mutex->destroy(this->mutex); + this->condvar->destroy(this->condvar); + this->active->destroy(this->active); + this->completed->destroy(this->completed); + DESTROY_IF(this->rng); + DESTROY_IF(this->dst); + free(this); +} + +/** + * See header + */ +dhcp_socket_t *dhcp_socket_create() +{ + private_dhcp_socket_t *this; + struct sockaddr_in src; + int on = 1; + + INIT(this, + .public = { + .enroll = _enroll, + .destroy = _destroy, + }, + .rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK), + .mutex = mutex_create(MUTEX_TYPE_DEFAULT), + .condvar = condvar_create(CONDVAR_TYPE_DEFAULT), + .active = linked_list_create(), + .completed = linked_list_create(), + ); + + if (!this->rng) + { + DBG1(DBG_CFG, "unable to create RNG"); + destroy(this); + return NULL; + } + + this->dst = host_create_from_string(lib->settings->get_str(lib->settings, + "charon.plugins.dhcp.server", "255.255.255.255"), + DHCP_SERVER_PORT); + if (!this->dst) + { + DBG1(DBG_CFG, "configured DHCP server address invalid"); + destroy(this); + return NULL; + } + + this->skt = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (this->skt == -1) + { + DBG1(DBG_CFG, "unable to create DHCP send socket: %s", strerror(errno)); + destroy(this); + return NULL; + } + + if (setsockopt(this->skt, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) + { + DBG1(DBG_CFG, "unable to reuse DHCP socket address: %s", strerror(errno)); + destroy(this); + return NULL; + } + if (setsockopt(this->skt, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) == -1) + { + DBG1(DBG_CFG, "unable to broadcast on DHCP socket: %s", strerror(errno)); + destroy(this); + return NULL; + } + + src.sin_family = AF_INET; + src.sin_port = htons(DHCP_CLIENT_PORT); + src.sin_addr.s_addr = INADDR_ANY; + if (bind(this->skt, (struct sockaddr*)&src, sizeof(src)) == -1) + { + DBG1(DBG_CFG, "unable to bind DHCP send socket: %s", strerror(errno)); + destroy(this); + return NULL; + } + + return &this->public; +} + diff --git a/src/libcharon/plugins/dhcp/dhcp_socket.h b/src/libcharon/plugins/dhcp/dhcp_socket.h new file mode 100644 index 000000000..687e95bc7 --- /dev/null +++ b/src/libcharon/plugins/dhcp/dhcp_socket.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup dhcp_socket dhcp_socket + * @{ @ingroup dhcp + */ + +#ifndef DHCP_SOCKET_H_ +#define DHCP_SOCKET_H_ + +typedef struct dhcp_socket_t dhcp_socket_t; + +#include "dhcp_transaction.h" + +/** + * DHCP socket implementation + */ +struct dhcp_socket_t { + + /** + * Enroll a client address using DHCP. + * + * @param identity peer identity to enroll an address for + * @return completed DHCP transaction, NULL on failure + */ + dhcp_transaction_t* (*enroll)(dhcp_socket_t *this, + identification_t *identity); + + /** + * Destroy a dhcp_socket_t. + */ + void (*destroy)(dhcp_socket_t *this); +}; + +/** + * Create a dhcp_socket instance. + */ +dhcp_socket_t *dhcp_socket_create(); + +#endif /** DHCP_SOCKET_H_ @}*/ diff --git a/src/libcharon/plugins/dhcp/dhcp_transaction.c b/src/libcharon/plugins/dhcp/dhcp_transaction.c new file mode 100644 index 000000000..14e65409f --- /dev/null +++ b/src/libcharon/plugins/dhcp/dhcp_transaction.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "dhcp_transaction.h" + +typedef struct private_dhcp_transaction_t private_dhcp_transaction_t; + +/** + * Private data of an dhcp_transaction_t object. + */ +struct private_dhcp_transaction_t { + + /** + * Public dhcp_transaction_t interface. + */ + dhcp_transaction_t public; + + /** + * DHCP transaction ID + */ + u_int32_t id; + + /** + * Peer identity + */ + identification_t *identity; + + /** + * received DHCP address + */ + host_t *address; +}; + +METHOD(dhcp_transaction_t, get_id, u_int32_t, + private_dhcp_transaction_t *this) +{ + return this->id; +} + +METHOD(dhcp_transaction_t, get_identity, identification_t*, + private_dhcp_transaction_t *this) +{ + return this->identity; +} + +METHOD(dhcp_transaction_t, set_address, void, + private_dhcp_transaction_t *this, host_t *address) +{ + DESTROY_IF(this->address); + this->address = address; +} + +METHOD(dhcp_transaction_t, get_address, host_t*, + private_dhcp_transaction_t *this) +{ + return this->address; +} + +METHOD(dhcp_transaction_t, destroy, void, + private_dhcp_transaction_t *this) +{ + this->identity->destroy(this->identity); + DESTROY_IF(this->address); + free(this); +} + +/** + * See header + */ +dhcp_transaction_t *dhcp_transaction_create(u_int32_t id, + identification_t *identity) +{ + private_dhcp_transaction_t *this; + + INIT(this, + .public = { + .get_id = _get_id, + .get_identity = _get_identity, + .set_address = _set_address, + .get_address = _get_address, + .destroy = _destroy, + }, + .id = id, + .identity = identity->clone(identity), + ); + + return &this->public; +} + diff --git a/src/libcharon/plugins/dhcp/dhcp_transaction.h b/src/libcharon/plugins/dhcp/dhcp_transaction.h new file mode 100644 index 000000000..e8215e93b --- /dev/null +++ b/src/libcharon/plugins/dhcp/dhcp_transaction.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Martin Willi + * Copyright (C) 2010 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup dhcp_transaction dhcp_transaction + * @{ @ingroup dhcp + */ + +#ifndef DHCP_TRANSACTION_H_ +#define DHCP_TRANSACTION_H_ + +#include <utils/host.h> +#include <utils/identification.h> + +typedef struct dhcp_transaction_t dhcp_transaction_t; + +/** + * DHCP transaction class. + */ +struct dhcp_transaction_t { + + /** + * Get the DCHP transaction ID. + * + * @return DHCP transaction identifier + */ + u_int32_t (*get_id)(dhcp_transaction_t *this); + + /** + * Get the peer identity this transaction is used for. + * + * @return peer Identity + */ + identification_t* (*get_identity)(dhcp_transaction_t *this); + + /** + * Set the DHCP address received using this transaction. + * + * @param host received DHCP address + */ + void (*set_address)(dhcp_transaction_t *this, host_t *address); + + /** + * Get the DHCP address received using this transaction. + * + * @return received DHCP address + */ + host_t* (*get_address)(dhcp_transaction_t *this); + + /** + * Destroy a dhcp_transaction_t. + */ + void (*destroy)(dhcp_transaction_t *this); +}; + +/** + * Create a dhcp_transaction instance. + * + * @param id DHCP transaction identifier + * @param identity peer identity this transaction is used for + * @return transaction instance + */ +dhcp_transaction_t *dhcp_transaction_create(u_int32_t id, + identification_t *identity); + +#endif /** DHCP_TRANSACTION_H_ @}*/ |