refactored TNC framework
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/src/libstrongswan \
|
||||
-I$(top_srcdir)/src/libtncif \
|
||||
-I$(top_srcdir)/src/libtnccs
|
||||
|
||||
AM_CFLAGS = -rdynamic
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES = libstrongswan-tnc-tnccs.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-tnc-tnccs.la
|
||||
libstrongswan_tnc_tnccs_la_LIBADD = \
|
||||
$(top_builddir)/src/libtncif/libtncif.la \
|
||||
$(top_builddir)/src/libtnccs/libtnccs.la
|
||||
endif
|
||||
|
||||
libstrongswan_tnc_tnccs_la_SOURCES = \
|
||||
tnc_tnccs_plugin.h tnc_tnccs_plugin.c \
|
||||
tnc_tnccs_manager.h tnc_tnccs_manager.c
|
||||
|
||||
libstrongswan_tnc_tnccs_la_LDFLAGS = -module -avoid-version
|
||||
@@ -0,0 +1,507 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 "tnc_tnccs_manager.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
#include <tnc/imv/imv_manager.h>
|
||||
#include <tnc/imc/imc_manager.h>
|
||||
#include <tnc/imv/imv_manager.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <threading/rwlock.h>
|
||||
|
||||
typedef struct private_tnc_tnccs_manager_t private_tnc_tnccs_manager_t;
|
||||
typedef struct tnccs_entry_t tnccs_entry_t;
|
||||
typedef struct tnccs_connection_entry_t tnccs_connection_entry_t;
|
||||
|
||||
/**
|
||||
* TNCCS constructor entry
|
||||
*/
|
||||
struct tnccs_entry_t {
|
||||
|
||||
/**
|
||||
* TNCCS protocol type
|
||||
*/
|
||||
tnccs_type_t type;
|
||||
|
||||
/**
|
||||
* constructor function to create instance
|
||||
*/
|
||||
tnccs_constructor_t constructor;
|
||||
};
|
||||
|
||||
/**
|
||||
* TNCCS connection entry
|
||||
*/
|
||||
struct tnccs_connection_entry_t {
|
||||
|
||||
/**
|
||||
* TNCCS connection ID
|
||||
*/
|
||||
TNC_ConnectionID id;
|
||||
|
||||
/**
|
||||
* TNCCS instance
|
||||
*/
|
||||
tnccs_t *tnccs;
|
||||
|
||||
/**
|
||||
* TNCCS send message function
|
||||
*/
|
||||
tnccs_send_message_t send_message;
|
||||
|
||||
/**
|
||||
* TNCCS request handshake retry flag
|
||||
*/
|
||||
bool *request_handshake_retry;
|
||||
|
||||
/**
|
||||
* collection of IMV recommendations
|
||||
*/
|
||||
recommendations_t *recs;
|
||||
};
|
||||
|
||||
/**
|
||||
* private data of tnc_tnccs_manager
|
||||
*/
|
||||
struct private_tnc_tnccs_manager_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
tnccs_manager_t public;
|
||||
|
||||
/**
|
||||
* list of TNCCS protocol entries
|
||||
*/
|
||||
linked_list_t *protocols;
|
||||
|
||||
/**
|
||||
* rwlock to lock the TNCCS protocol entries
|
||||
*/
|
||||
rwlock_t *protocol_lock;
|
||||
|
||||
/**
|
||||
* connection ID counter
|
||||
*/
|
||||
TNC_ConnectionID connection_id;
|
||||
|
||||
/**
|
||||
* list of TNCCS connection entries
|
||||
*/
|
||||
linked_list_t *connections;
|
||||
|
||||
/**
|
||||
* rwlock to lock TNCCS connection entries
|
||||
*/
|
||||
rwlock_t *connection_lock;
|
||||
|
||||
};
|
||||
|
||||
METHOD(tnccs_manager_t, add_method, void,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_type_t type,
|
||||
tnccs_constructor_t constructor)
|
||||
{
|
||||
tnccs_entry_t *entry;
|
||||
|
||||
entry = malloc_thing(tnccs_entry_t);
|
||||
entry->type = type;
|
||||
entry->constructor = constructor;
|
||||
|
||||
this->protocol_lock->write_lock(this->protocol_lock);
|
||||
this->protocols->insert_last(this->protocols, entry);
|
||||
this->protocol_lock->unlock(this->protocol_lock);
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, remove_method, void,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_constructor_t constructor)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_entry_t *entry;
|
||||
|
||||
this->protocol_lock->write_lock(this->protocol_lock);
|
||||
enumerator = this->protocols->create_enumerator(this->protocols);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (constructor == entry->constructor)
|
||||
{
|
||||
this->protocols->remove_at(this->protocols, enumerator);
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->protocol_lock->unlock(this->protocol_lock);
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, create_instance, tnccs_t*,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_type_t type, bool is_server)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_entry_t *entry;
|
||||
tnccs_t *protocol = NULL;
|
||||
|
||||
this->protocol_lock->read_lock(this->protocol_lock);
|
||||
enumerator = this->protocols->create_enumerator(this->protocols);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (type == entry->type)
|
||||
{
|
||||
protocol = entry->constructor(is_server);
|
||||
if (protocol)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->protocol_lock->unlock(this->protocol_lock);
|
||||
|
||||
return protocol;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, create_connection, TNC_ConnectionID,
|
||||
private_tnc_tnccs_manager_t *this, tnccs_t *tnccs,
|
||||
tnccs_send_message_t send_message, bool* request_handshake_retry,
|
||||
recommendations_t **recs)
|
||||
{
|
||||
tnccs_connection_entry_t *entry;
|
||||
|
||||
entry = malloc_thing(tnccs_connection_entry_t);
|
||||
entry->tnccs = tnccs;
|
||||
entry->send_message = send_message;
|
||||
entry->request_handshake_retry = request_handshake_retry;
|
||||
if (recs)
|
||||
{
|
||||
/* we assume a TNC Server needing recommendations from IMVs */
|
||||
if (!tnc->imvs)
|
||||
{
|
||||
DBG1(DBG_TNC, "no IMV manager available!");
|
||||
free(entry);
|
||||
return 0;
|
||||
}
|
||||
entry->recs = tnc->imvs->create_recommendations(tnc->imvs);
|
||||
*recs = entry->recs;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we assume a TNC Client */
|
||||
if (!tnc->imcs)
|
||||
{
|
||||
DBG1(DBG_TNC, "no IMC manager available!");
|
||||
free(entry);
|
||||
return 0;
|
||||
}
|
||||
entry->recs = NULL;
|
||||
}
|
||||
this->connection_lock->write_lock(this->connection_lock);
|
||||
entry->id = ++this->connection_id;
|
||||
this->connections->insert_last(this->connections, entry);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
DBG1(DBG_TNC, "assigned TNCCS Connection ID %u", entry->id);
|
||||
return entry->id;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, remove_connection, void,
|
||||
private_tnc_tnccs_manager_t *this, TNC_ConnectionID id, bool is_server)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
|
||||
if (is_server)
|
||||
{
|
||||
if (tnc->imvs)
|
||||
{
|
||||
tnc->imvs->notify_connection_change(tnc->imvs, id,
|
||||
TNC_CONNECTION_STATE_DELETE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tnc->imcs)
|
||||
{
|
||||
tnc->imcs->notify_connection_change(tnc->imcs, id,
|
||||
TNC_CONNECTION_STATE_DELETE);
|
||||
}
|
||||
}
|
||||
|
||||
this->connection_lock->write_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
this->connections->remove_at(this->connections, enumerator);
|
||||
if (entry->recs)
|
||||
{
|
||||
entry->recs->destroy(entry->recs);
|
||||
}
|
||||
free(entry);
|
||||
DBG1(DBG_TNC, "removed TNCCS Connection ID %u", id);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, request_handshake_retry, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, bool is_imc, TNC_UInt32 imcv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_RetryReason reason)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
|
||||
if (id == TNC_CONNECTIONID_ANY)
|
||||
{
|
||||
DBG2(DBG_TNC, "%s %u requests handshake retry for all connections "
|
||||
"(reason: %u)", is_imc ? "IMC":"IMV", reason);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_TNC, "%s %u requests handshake retry for Connection ID %u "
|
||||
"(reason: %u)", is_imc ? "IMC":"IMV", imcv_id, id, reason);
|
||||
}
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == TNC_CONNECTIONID_ANY || id == entry->id)
|
||||
{
|
||||
*entry->request_handshake_retry = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, send_message, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, TNC_IMCID imc_id, TNC_IMVID imv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_BufferReference msg,
|
||||
TNC_UInt32 msg_len,
|
||||
TNC_MessageType msg_type)
|
||||
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
tnccs_send_message_t send_message = NULL;
|
||||
tnccs_t *tnccs = NULL;
|
||||
TNC_VendorID msg_vid;
|
||||
TNC_MessageSubtype msg_subtype;
|
||||
|
||||
msg_vid = (msg_type >> 8) & TNC_VENDORID_ANY;
|
||||
msg_subtype = msg_type & TNC_SUBTYPE_ANY;
|
||||
|
||||
if (msg_vid == TNC_VENDORID_ANY || msg_subtype == TNC_SUBTYPE_ANY)
|
||||
{
|
||||
DBG1(DBG_TNC, "not sending message of invalid type 0x%08x", msg_type);
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
tnccs = entry->tnccs;
|
||||
send_message = entry->send_message;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (tnccs && send_message)
|
||||
{
|
||||
return send_message(tnccs, imc_id, imv_id, msg, msg_len, msg_type);
|
||||
}
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, provide_recommendation, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, TNC_IMVID imv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_IMV_Action_Recommendation rec,
|
||||
TNC_IMV_Evaluation_Result eval)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
recommendations_t *recs = NULL;
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
recs = entry->recs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (recs)
|
||||
{
|
||||
recs->provide_recommendation(recs, imv_id, rec, eval);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, get_attribute, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, TNC_IMVID imv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_AttributeID attribute_id,
|
||||
TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer,
|
||||
TNC_UInt32 *out_value_len)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
recommendations_t *recs = NULL;
|
||||
|
||||
if (id == TNC_CONNECTIONID_ANY ||
|
||||
attribute_id != TNC_ATTRIBUTEID_PREFERRED_LANGUAGE)
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
recs = entry->recs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (recs)
|
||||
{
|
||||
chunk_t pref_lang;
|
||||
|
||||
pref_lang = recs->get_preferred_language(recs);
|
||||
if (pref_lang.len == 0)
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
*out_value_len = pref_lang.len;
|
||||
if (buffer && buffer_len >= pref_lang.len)
|
||||
{
|
||||
memcpy(buffer, pref_lang.ptr, pref_lang.len);
|
||||
}
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, set_attribute, TNC_Result,
|
||||
private_tnc_tnccs_manager_t *this, TNC_IMVID imv_id,
|
||||
TNC_ConnectionID id,
|
||||
TNC_AttributeID attribute_id,
|
||||
TNC_UInt32 buffer_len,
|
||||
TNC_BufferReference buffer)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
tnccs_connection_entry_t *entry;
|
||||
recommendations_t *recs = NULL;
|
||||
|
||||
if (id == TNC_CONNECTIONID_ANY ||
|
||||
(attribute_id != TNC_ATTRIBUTEID_REASON_STRING &&
|
||||
attribute_id != TNC_ATTRIBUTEID_REASON_LANGUAGE))
|
||||
{
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
this->connection_lock->read_lock(this->connection_lock);
|
||||
enumerator = this->connections->create_enumerator(this->connections);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (id == entry->id)
|
||||
{
|
||||
recs = entry->recs;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
this->connection_lock->unlock(this->connection_lock);
|
||||
|
||||
if (recs)
|
||||
{
|
||||
chunk_t attribute = { buffer, buffer_len };
|
||||
|
||||
if (attribute_id == TNC_ATTRIBUTEID_REASON_STRING)
|
||||
{
|
||||
return recs->set_reason_string(recs, imv_id, attribute);
|
||||
}
|
||||
else
|
||||
{
|
||||
return recs->set_reason_language(recs, imv_id, attribute);
|
||||
}
|
||||
}
|
||||
return TNC_RESULT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
METHOD(tnccs_manager_t, destroy, void,
|
||||
private_tnc_tnccs_manager_t *this)
|
||||
{
|
||||
this->protocols->destroy_function(this->protocols, free);
|
||||
this->protocol_lock->destroy(this->protocol_lock);
|
||||
this->connections->destroy_function(this->connections, free);
|
||||
this->connection_lock->destroy(this->connection_lock);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
tnccs_manager_t *tnc_tnccs_manager_create()
|
||||
{
|
||||
private_tnc_tnccs_manager_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.add_method = _add_method,
|
||||
.remove_method = _remove_method,
|
||||
.create_instance = _create_instance,
|
||||
.create_connection = _create_connection,
|
||||
.remove_connection = _remove_connection,
|
||||
.request_handshake_retry = _request_handshake_retry,
|
||||
.send_message = _send_message,
|
||||
.provide_recommendation = _provide_recommendation,
|
||||
.get_attribute = _get_attribute,
|
||||
.set_attribute = _set_attribute,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.protocols = linked_list_create(),
|
||||
.connections = linked_list_create(),
|
||||
.protocol_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
.connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 tnc_tnccs_manager tnc_tnccs_manager
|
||||
* @{ @ingroup tnc_tnccs
|
||||
*/
|
||||
|
||||
#ifndef TNC_TNCCS_MANAGER_H_
|
||||
#define TNC_TNCCS_MANAGER_H_
|
||||
|
||||
#include <tnc/tnccs/tnccs_manager.h>
|
||||
|
||||
/**
|
||||
* Create a TNCCS manager instance.
|
||||
*/
|
||||
tnccs_manager_t *tnc_tnccs_manager_create();
|
||||
|
||||
#endif /** TNC_TNCCS_MANAGER_H_ @}*/
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 "tnc_tnccs_plugin.h"
|
||||
#include "tnc_tnccs_manager.h"
|
||||
|
||||
#include <tnc/tnc.h>
|
||||
|
||||
typedef struct private_tnc_tnccs_plugin_t private_tnc_tnccs_plugin_t;
|
||||
|
||||
/**
|
||||
* Private data of a tnc_tnccs_plugin_t object.
|
||||
*/
|
||||
struct private_tnc_tnccs_plugin_t {
|
||||
|
||||
/**
|
||||
* Public interface.
|
||||
*/
|
||||
tnc_tnccs_plugin_t public;
|
||||
|
||||
};
|
||||
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_tnc_tnccs_plugin_t *this)
|
||||
{
|
||||
return "tnc-tnccs";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_tnc_tnccs_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(tnc_manager_register, tnc_tnccs_manager_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "tnccs-manager"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_tnc_tnccs_plugin_t *this)
|
||||
{
|
||||
libtnccs_deinit();
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *tnc_tnccs_plugin_create(void)
|
||||
{
|
||||
private_tnc_tnccs_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
libtnccs_init();
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* 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 tnccs tnccs
|
||||
* @ingroup cplugins
|
||||
*
|
||||
* @defgroup tnc_tnccs_plugin tnc_tnccs_plugin
|
||||
* @{ @ingroup tnccs
|
||||
*/
|
||||
|
||||
#ifndef TNC_TNCCS_PLUGIN_H_
|
||||
#define TNC_TNCCS_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct tnc_tnccs_plugin_t tnc_tnccs_plugin_t;
|
||||
|
||||
/**
|
||||
* TNCCS manager plugin
|
||||
*/
|
||||
struct tnc_tnccs_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** TNC_TNCCS_PLUGIN_H_ @}*/
|
||||
Reference in New Issue
Block a user