.BR libimcv.plugins.imv-scanner.udp_ports
List of UDP ports that can be open or must be closed
.TP
+.BR libimcv.plugins.imc-test.additional_ids " [0]"
+Number of additional IMC IDs
+.TP
.BR libimcv.plugins.imc-test.command " [none]"
Command to be sent to the Test IMV
.TP
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
return TNC_RESULT_NOT_INITIALIZED;
}
+
switch (new_state)
{
case TNC_CONNECTION_STATE_CREATE:
retry = lib->settings->get_bool(lib->settings,
"libimcv.plugins.imc-test.retry", FALSE);
state = imc_test_state_create(connection_id, command, retry);
+ test_state = (imc_test_state_t*)state;
result = imc_test->create_state(imc_test, state);
if (result != TNC_RESULT_SUCCESS)
"multiple IMC IDs", imc_id, imc_name);
return TNC_RESULT_SUCCESS;
}
- test_state = (imc_test_state_t*)state;
while (additional_ids-- > 0)
{
}
}
-static TNC_Result send_message(TNC_ConnectionID connection_id)
+static TNC_Result send_message(imc_state_t *state, TNC_UInt32 src_imc_id,
+ TNC_UInt32 dst_imv_id)
{
+ imc_test_state_t *test_state;
pa_tnc_msg_t *msg;
pa_tnc_attr_t *attr;
- imc_state_t *state;
- imc_test_state_t *test_state;
- enumerator_t *enumerator;
- void *pointer;
- TNC_UInt32 imc_id;
+ bool excl;
+ TNC_ConnectionID connection_id;
TNC_Result result;
- if (!imc_test->get_state(imc_test, connection_id, &state))
- {
- return TNC_RESULT_FATAL;
- }
+ connection_id = state->get_connection_id(state);
test_state = (imc_test_state_t*)state;
-
- /* send PA message for primary IMC ID */
attr = ita_attr_command_create(test_state->get_command(test_state));
attr->set_noskip_flag(attr, TRUE);
msg = pa_tnc_msg_create();
msg->add_attribute(msg, attr);
msg->build(msg);
- result = imc_test->send_message(imc_test, connection_id, FALSE, 0,
- TNC_IMVID_ANY, msg->get_encoding(msg));
+ excl = dst_imv_id != TNC_IMVID_ANY;
+ result = imc_test->send_message(imc_test, connection_id, excl, src_imc_id,
+ dst_imv_id, msg->get_encoding(msg));
msg->destroy(msg);
- /* send PA messages for additional IMC IDs */
- enumerator = test_state->create_id_enumerator(test_state);
- while (result == TNC_RESULT_SUCCESS &&
- enumerator->enumerate(enumerator, &pointer))
- {
- /* interpret pointer as scalar value */
- imc_id = (TNC_UInt32)pointer;
-
- attr = ita_attr_command_create(test_state->get_command(test_state));
- attr->set_noskip_flag(attr, TRUE);
- msg = pa_tnc_msg_create();
- msg->add_attribute(msg, attr);
- msg->build(msg);
- result = imc_test->send_message(imc_test, connection_id, FALSE, imc_id,
- TNC_IMVID_ANY, msg->get_encoding(msg));
- msg->destroy(msg);
- }
- enumerator->destroy(enumerator);
-
return result;
}
TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
TNC_ConnectionID connection_id)
{
+ imc_state_t *state;
+ imc_test_state_t *test_state;
+ enumerator_t *enumerator;
+ void *pointer;
+ TNC_UInt32 additional_id;
+ TNC_Result result;
+
if (!imc_test)
{
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
return TNC_RESULT_NOT_INITIALIZED;
}
- return send_message(connection_id);
+
+ /* get current IMC state */
+ if (!imc_test->get_state(imc_test, connection_id, &state))
+ {
+ return TNC_RESULT_FATAL;
+ }
+ test_state = (imc_test_state_t*)state;
+
+ /* send PA message for primary IMC ID */
+ result = send_message(state, imc_id, TNC_IMVID_ANY);
+
+ /* send PA messages for additional IMC IDs */
+ enumerator = test_state->create_id_enumerator(test_state);
+ while (result == TNC_RESULT_SUCCESS &&
+ enumerator->enumerate(enumerator, &pointer))
+ {
+ /* interpret pointer as scalar value */
+ additional_id = (TNC_UInt32)pointer;
+ result = send_message(state, additional_id, TNC_IMVID_ANY);
+ }
+ enumerator->destroy(enumerator);
+
+ return result;
}
static TNC_Result receive_message(TNC_IMCID imc_id,
pa_tnc_msg->destroy(pa_tnc_msg);
/* if no error occurred then always return the same response */
- return fatal_error ? TNC_RESULT_FATAL : send_message(connection_id);
+ return fatal_error ? TNC_RESULT_FATAL :
+ send_message(state, dst_imc_id, src_imv_id);
}
/**
TNC_ConnectionState new_state)
{
imv_state_t *state;
- imv_test_state_t *test_state;
- TNC_Result result;
- int rounds;
if (!imv_test)
{
return imv_test->create_state(imv_test, state);
case TNC_CONNECTION_STATE_DELETE:
return imv_test->delete_state(imv_test, connection_id);
- case TNC_CONNECTION_STATE_HANDSHAKE:
- /* get updated IMV state */
- result = imv_test->change_state(imv_test, connection_id,
- new_state, &state);
- if (result != TNC_RESULT_SUCCESS)
- {
- return result;
- }
- test_state = (imv_test_state_t*)state;
-
- /* set the number of measurement rounds */
- rounds = lib->settings->get_int(lib->settings,
- "libimcv.plugins.imv-test.rounds", 0);
- test_state->set_rounds(test_state, rounds);
- return TNC_RESULT_SUCCESS;
default:
return imv_test->change_state(imv_test, connection_id,
new_state, NULL);
}
}
-static TNC_Result send_message(TNC_ConnectionID connection_id)
-{
- pa_tnc_msg_t *msg;
- pa_tnc_attr_t *attr;
- TNC_Result result;
-
- attr = ita_attr_command_create("repeat");
- msg = pa_tnc_msg_create();
- msg->add_attribute(msg, attr);
- msg->build(msg);
- result = imv_test->send_message(imv_test, connection_id, FALSE, 0,
- TNC_IMCID_ANY, msg->get_encoding(msg));
- msg->destroy(msg);
-
- return result;
-}
-
static TNC_Result receive_message(TNC_IMVID imv_id,
TNC_ConnectionID connection_id,
TNC_UInt32 msg_flags,
pa_tnc_msg_t *pa_tnc_msg;
pa_tnc_attr_t *attr;
imv_state_t *state;
- imv_test_state_t *imv_test_state;
+ imv_test_state_t *test_state;
enumerator_t *enumerator;
TNC_Result result;
+ int rounds;
bool fatal_error, retry = FALSE;
if (!imv_test)
{
return TNC_RESULT_FATAL;
}
+ test_state = (imv_test_state_t*)state;
/* parse received PA-TNC message and automatically handle any errors */
result = imv_test->receive_message(imv_test, state, msg, msg_vid,
/* preprocess any IETF standard error attributes */
fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+ /* add any new IMC and set its number of rounds */
+ rounds = lib->settings->get_int(lib->settings,
+ "libimcv.plugins.imv-test.rounds", 0);
+ test_state->add_imc(test_state, src_imc_id, rounds);
+
/* analyze PA-TNC attributes */
enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
while (enumerator->enumerate(enumerator, &attr))
/* request a handshake retry ? */
if (retry)
{
+ test_state->set_rounds(test_state, rounds);
return imv_test->request_handshake_retry(imv_id, connection_id,
TNC_RETRY_REASON_IMV_SERIOUS_EVENT);
}
/* repeat the measurement ? */
- imv_test_state = (imv_test_state_t*)state;
- if (imv_test_state->another_round(imv_test_state))
+ if (test_state->another_round(test_state, src_imc_id))
{
- return send_message(connection_id);
+ attr = ita_attr_command_create("repeat");
+ pa_tnc_msg = pa_tnc_msg_create();
+ pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
+ pa_tnc_msg->build(pa_tnc_msg);
+ result = imv_test->send_message(imv_test, connection_id, TRUE, imv_id,
+ src_imc_id, pa_tnc_msg->get_encoding(pa_tnc_msg));
+ pa_tnc_msg->destroy(pa_tnc_msg);
+
+ return result;
}
return imv_test->provide_recommendation(imv_test, connection_id);
#include "imv_test_state.h"
#include <utils/lexparser.h>
+#include <utils/linked_list.h>
#include <debug.h>
typedef struct private_imv_test_state_t private_imv_test_state_t;
TNC_IMV_Evaluation_Result eval;
/**
- * IMC-IMV round-trip count
+ * List of IMCs
*/
- int rounds;
+ linked_list_t *imcs;
+
+};
+
+typedef struct imc_entry_t imc_entry_t;
+/**
+ * Define an internal IMC entry
+ */
+struct imc_entry_t {
+ TNC_UInt32 imc_id;
+ int rounds;
};
typedef struct entry_t entry_t;
METHOD(imv_state_t, destroy, void,
private_imv_test_state_t *this)
{
+ this->imcs->destroy_function(this->imcs, free);
free(this);
}
+METHOD(imv_test_state_t, add_imc, void,
+ private_imv_test_state_t *this, TNC_UInt32 imc_id, int rounds)
+{
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+ bool found = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ if (imc_entry->imc_id == imc_id)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ imc_entry = malloc_thing(imc_entry_t);
+ imc_entry->imc_id = imc_id;
+ imc_entry->rounds = rounds;
+ this->imcs->insert_last(this->imcs, imc_entry);
+ }
+}
+
METHOD(imv_test_state_t, set_rounds, void,
private_imv_test_state_t *this, int rounds)
{
- this->rounds = rounds;
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ imc_entry->rounds = rounds;
+ }
+ enumerator->destroy(enumerator);
}
METHOD(imv_test_state_t, another_round, bool,
- private_imv_test_state_t *this)
+ private_imv_test_state_t *this, TNC_UInt32 imc_id)
{
- return (this->rounds-- > 0);
+ enumerator_t *enumerator;
+ imc_entry_t *imc_entry;
+ bool not_finished = FALSE;
+
+ enumerator = this->imcs->create_enumerator(this->imcs);
+ while (enumerator->enumerate(enumerator, &imc_entry))
+ {
+ if (imc_entry->rounds > 0)
+ {
+ not_finished = TRUE;
+ }
+ if (imc_entry->imc_id == imc_id)
+ {
+ imc_entry->rounds--;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ return not_finished;
}
/**
.get_reason_string = _get_reason_string,
.destroy = _destroy,
},
+ .add_imc = _add_imc,
.set_rounds = _set_rounds,
.another_round = _another_round,
},
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
.eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
.connection_id = connection_id,
+ .imcs = linked_list_create(),
);
return &this->public.interface;
imv_state_t interface;
/**
+ * Add an IMC
+ *
+ * @param imc_id ID of the IMC to be added
+ * @param rounds number of re-measurement rounds
+ */
+ void (*add_imc)(imv_test_state_t *this, TNC_UInt32 imc_id, int rounds);
+
+ /**
* Set the IMC-IMV round-trip count
*
* @param rounds number of re-measurement rounds
/**
* Check and decrease IMC-IMV round-trip count
*
+ * @param imc_id ID of the IMC to be checked
* @return new connection state
*/
- bool (*another_round)(imv_test_state_t *this);
+ bool (*another_round)(imv_test_state_t *this, TNC_UInt32 imc_id);
};
/**
plugins {
imc-test {
command = allow
+ additional_ids = 2
}
}
}
plugins {
imc-test {
command = isolate
+ additional_ids = 1
}
}
}