}
}
+METHOD(imc_t, type_supported, bool,
+ private_tnc_imc_t *this, TNC_MessageType message_type)
+{
+ TNC_VendorID msg_vid, vid;
+ TNC_MessageSubtype msg_subtype, subtype;
+ int i;
+
+ msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = message_type & TNC_SUBTYPE_ANY;
+
+ for (i = 0; i < this->type_count; i++)
+ {
+ vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
+
+ if (this->supported_types[i] == message_type
+ || (subtype == TNC_SUBTYPE_ANY
+ && (msg_vid == vid || vid == TNC_VENDORID_ANY))
+ || (vid == TNC_VENDORID_ANY
+ && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
METHOD(imc_t, destroy, void,
private_tnc_imc_t *this)
{
.get_id = _get_id,
.get_name = _get_name,
.set_message_types = _set_message_types,
+ .type_supported = _type_supported,
.destroy = _destroy,
},
);
return result;
}
+METHOD(imc_manager_t, receive_message, void,
+ private_tnc_imc_manager_t *this, TNC_ConnectionID connection_id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type)
+{
+ enumerator_t *enumerator;
+ imc_t *imc;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc))
+ {
+ if (imc->receive_message && imc->type_supported(imc, message_type))
+ {
+ imc->receive_message(imc->get_id(imc), connection_id,
+ message, message_len, message_type);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
METHOD(imc_manager_t, destroy, void,
private_tnc_imc_manager_t *this)
.notify_connection_change = _notify_connection_change,
.begin_handshake = _begin_handshake,
.set_message_types = _set_message_types,
+ .receive_message = _receive_message,
.destroy = _destroy,
},
.imcs = linked_list_create(),
}
}
+METHOD(imv_t, type_supported, bool,
+ private_tnc_imv_t *this, TNC_MessageType message_type)
+{
+ TNC_VendorID msg_vid, vid;
+ TNC_MessageSubtype msg_subtype, subtype;
+ int i;
+
+ msg_vid = (message_type >> 8) & TNC_VENDORID_ANY;
+ msg_subtype = message_type & TNC_SUBTYPE_ANY;
+
+ for (i = 0; i < this->type_count; i++)
+ {
+ vid = (this->supported_types[i] >> 8) & TNC_VENDORID_ANY;
+ subtype = this->supported_types[i] & TNC_SUBTYPE_ANY;
+
+ if (this->supported_types[i] == message_type
+ || (subtype == TNC_SUBTYPE_ANY
+ && (msg_vid == vid || vid == TNC_VENDORID_ANY))
+ || (vid == TNC_VENDORID_ANY
+ && (msg_subtype == subtype || subtype == TNC_SUBTYPE_ANY)))
+ {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
METHOD(imv_t, destroy, void,
private_tnc_imv_t *this)
{
.get_id = _get_id,
.get_name = _get_name,
.set_message_types = _set_message_types,
+ .type_supported = _type_supported,
.destroy = _destroy,
},
);
return result;
}
+METHOD(imv_manager_t, receive_message, void,
+ private_tnc_imv_manager_t *this, TNC_ConnectionID connection_id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type)
+{
+ enumerator_t *enumerator;
+ imv_t *imv;
+
+ enumerator = this->imvs->create_enumerator(this->imvs);
+ while (enumerator->enumerate(enumerator, &imv))
+ {
+ if (imv->receive_message && imv->type_supported(imv, message_type))
+ {
+ imv->receive_message(imv->get_id(imv), connection_id,
+ message, message_len, message_type);
+ }
+ }
+ enumerator->destroy(enumerator);
+}
+
METHOD(imv_manager_t, destroy, void,
private_tnc_imv_manager_t *this)
{
.add = _add,
.notify_connection_change = _notify_connection_change,
.set_message_types = _set_message_types,
+ .receive_message = _receive_message,
.destroy = _destroy,
},
.imvs = linked_list_create(),
METHOD(tls_t, process, status_t,
private_tnccs_20_t *this, void *buf, size_t buflen)
{
+ char *pos;
+ size_t len;
+
if (this->is_server && !this->connection_id)
{
this->connection_id = charon->tnccs->create_connection(charon->tnccs,
DBG1(DBG_TNC, "received TNCCS Batch (%u bytes) for Connection ID %u",
buflen, this->connection_id);
DBG3(DBG_TNC, "%.*s", buflen, buf);
-
+ pos = strchr(buf, '|');
+ if (pos)
+ {
+ pos++;
+ len = buflen - ((char*)buf - pos);
+ }
+ else
+ {
+ pos = buf;
+ len = buflen;
+ }
+ if (this->is_server)
+ {
+ charon->imvs->receive_message(charon->imvs, this->connection_id,
+ pos, len, 0x0080ab31);
+ }
+ else
+ {
+ charon->imcs->receive_message(charon->imcs, this->connection_id,
+ pos, len, 0x0080ab31);
+ }
return NEED_MORE;
}
METHOD(tls_t, build, status_t,
private_tnccs_20_t *this, void *buf, size_t *buflen, size_t *msglen)
{
- char *msg = this->is_server ? "|tncs->tncc 2.0|" : "|tncc->tncs 2.0|";
+ char *msg = this->is_server ? "tncs->tncc 2.0|" : "tncc->tncs 2.0|";
size_t len;
this->batch = chunk_clone(chunk_create(msg, strlen(msg)));
#include <tnc/tncifimc.h>
+#include <library.h>
+
typedef struct imc_t imc_t;
struct imc_t {
TNC_UInt32 type_count);
/**
+ * Check if the IMC supports a given message type.
+ *
+ * @param message_type message type
+ * @return TRUE if supported
+ */
+ bool (*type_supported)(imc_t *this, TNC_MessageType message_type);
+
+ /**
* Destroys an imc_t object.
*/
void (*destroy)(imc_t *this);
TNC_UInt32 type_count);
/**
+ * Delivers a message to interested IMCs.
+ *
+ * @param connection_id ID of connection over which message was received
+ * @param message message
+ * @param message_len message length
+ * @param message_type message type
+ */
+ void (*receive_message)(imc_manager_t *this,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type);
+
+ /**
* Destroy an IMC manager and all its controlled instances.
*/
void (*destroy)(imc_manager_t *this);
#include <tnc/tncifimv.h>
+#include <library.h>
+
typedef struct imv_t imv_t;
struct imv_t {
TNC_UInt32 type_count);
/**
+ * Check if the IMV supports a given message type.
+ *
+ * @param message_type message type
+ * @return TRUE if supported
+ */
+ bool (*type_supported)(imv_t *this, TNC_MessageType message_type);
+
+ /**
* Destroys an imv_t object.
*/
void (*destroy)(imv_t *this);
TNC_UInt32 type_count);
/**
+ * Delivers a message to interested IMVs.
+ *
+ * @param connection_id ID of connection over which message was received
+ * @param message message
+ * @param message_len message length
+ * @param message_type message type
+ */
+ void (*receive_message)(imv_manager_t *this,
+ TNC_ConnectionID connection_id,
+ TNC_BufferReference message,
+ TNC_UInt32 message_len,
+ TNC_MessageType message_type);
+
+ /**
* Destroy an IMV manager and all its controlled instances.
*/
void (*destroy)(imv_manager_t *this);