191 lines
3.9 KiB
C
191 lines
3.9 KiB
C
/*
|
|
* 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"
|
|
|
|
#include <collections/linked_list.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
|
|
*/
|
|
uint32_t id;
|
|
|
|
/**
|
|
* Peer identity
|
|
*/
|
|
identification_t *identity;
|
|
|
|
/**
|
|
* received DHCP address
|
|
*/
|
|
host_t *address;
|
|
|
|
/**
|
|
* 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, uint32_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, set_server, void,
|
|
private_dhcp_transaction_t *this, host_t *server)
|
|
{
|
|
DESTROY_IF(this->server);
|
|
this->server = server;
|
|
}
|
|
|
|
METHOD(dhcp_transaction_t, get_server, host_t*,
|
|
private_dhcp_transaction_t *this)
|
|
{
|
|
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);
|
|
}
|
|
|
|
CALLBACK(attribute_filter, bool,
|
|
void *null, enumerator_t *orig, va_list args)
|
|
{
|
|
configuration_attribute_type_t *type;
|
|
attribute_entry_t *entry;
|
|
chunk_t *data;
|
|
|
|
VA_ARGS_VGET(args, type, data);
|
|
|
|
if (orig->enumerate(orig, &entry))
|
|
{
|
|
*type = entry->type;
|
|
*data = entry->data;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
METHOD(dhcp_transaction_t, create_attribute_enumerator, enumerator_t*,
|
|
private_dhcp_transaction_t *this)
|
|
{
|
|
return enumerator_create_filter(
|
|
this->attributes->create_enumerator(this->attributes),
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* See header
|
|
*/
|
|
dhcp_transaction_t *dhcp_transaction_create(uint32_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,
|
|
.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;
|
|
}
|
|
|