--- /dev/null
+/*
+ * Example IMC for TNC testing
+ * Copyright (c) 2014, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "includes.h"
+
+#include "common.h"
+#include "common/tnc.h"
+
+static int initialized = 0;
+static TNC_IMCID my_id = -1;
+static TNC_TNCC_SendMessagePointer send_message = NULL;
+static TNC_TNCC_ReportMessageTypesPointer report_message_types = NULL;
+static TNC_TNCC_RequestHandshakeRetryPointer request_retry = NULL;
+
+static TNC_MessageType message_types[] =
+{
+ (TNC_VENDORID_ANY << 8) | TNC_SUBTYPE_ANY
+};
+
+
+TNC_Result TNC_IMC_Initialize(
+ /*in*/ TNC_IMCID imcID,
+ /*in*/ TNC_Version minVersion,
+ /*in*/ TNC_Version maxVersion,
+ /*out*/ TNC_Version *pOutActualVersion)
+{
+ wpa_printf(MSG_INFO,
+ "IMC(hostap2) %s(imcID=%u, minVersion=%u, maxVersion=%u)",
+ __func__, (unsigned) imcID, (unsigned) minVersion,
+ (unsigned) maxVersion);
+
+ if (initialized)
+ return TNC_RESULT_ALREADY_INITIALIZED;
+
+ if (minVersion < TNC_IFIMC_VERSION_1 ||
+ maxVersion > TNC_IFIMC_VERSION_1)
+ return TNC_RESULT_NO_COMMON_VERSION;
+
+ if (!pOutActualVersion)
+ return TNC_RESULT_INVALID_PARAMETER;
+ *pOutActualVersion = TNC_IFIMC_VERSION_1;
+ my_id = imcID;
+
+ initialized = 1;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+
+TNC_Result TNC_IMC_BeginHandshake(
+ /*in*/ TNC_IMCID imcID,
+ /*in*/ TNC_ConnectionID connectionID)
+{
+ char *msg = "hello";
+ TNC_Result res;
+
+ wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u, connectionID=%u)",
+ __func__, (unsigned) imcID, (unsigned) connectionID);
+
+ if (!initialized)
+ return TNC_RESULT_NOT_INITIALIZED;
+
+ if (imcID != my_id)
+ return TNC_RESULT_INVALID_PARAMETER;
+
+ if (!send_message)
+ return TNC_RESULT_FATAL;
+
+ res = send_message(imcID, connectionID, msg, os_strlen(msg), 1);
+ if (res != TNC_RESULT_SUCCESS)
+ return res;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+
+TNC_Result TNC_IMC_ProvideBindFunction(
+ /*in*/ TNC_IMCID imcID,
+ /*in*/ TNC_TNCC_BindFunctionPointer bindFunction)
+{
+ TNC_Result res;
+
+ wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u)",
+ __func__, (unsigned) imcID);
+
+ if (!initialized)
+ return TNC_RESULT_NOT_INITIALIZED;
+
+ if (imcID != my_id || !bindFunction)
+ return TNC_RESULT_INVALID_PARAMETER;
+
+ if (bindFunction(imcID, "TNC_TNCC_SendMessage",
+ (void **) &send_message) != TNC_RESULT_SUCCESS ||
+ !send_message)
+ return TNC_RESULT_FATAL;
+
+ if (bindFunction(imcID, "TNC_TNCC_ReportMessageTypes",
+ (void **) &report_message_types) !=
+ TNC_RESULT_SUCCESS ||
+ !report_message_types)
+ return TNC_RESULT_FATAL;
+
+ if (bindFunction(imcID, "TNC_TNCC_RequestHandshakeRetry",
+ (void **) &request_retry) != TNC_RESULT_SUCCESS ||
+ !request_retry)
+ return TNC_RESULT_FATAL;
+
+ res = report_message_types(imcID, message_types,
+ ARRAY_SIZE(message_types));
+ if (res != TNC_RESULT_SUCCESS)
+ return res;
+
+ return TNC_RESULT_SUCCESS;
+}
+
+
+TNC_Result TNC_IMC_NotifyConnectionChange(
+ /*in*/ TNC_IMCID imcID,
+ /*in*/ TNC_ConnectionID connectionID,
+ /*in*/ TNC_ConnectionState newState)
+{
+ wpa_printf(MSG_INFO,
+ "IMC(hostap2) %s(imcID=%u, connectionID=%u, newState=%u)",
+ __func__, (unsigned) imcID, (unsigned) connectionID,
+ (unsigned) newState);
+
+ return TNC_RESULT_SUCCESS;
+}
+
+
+TNC_Result TNC_IMC_ReceiveMessage(
+ /*in*/ TNC_IMCID imcID,
+ /*in*/ TNC_ConnectionID connectionID,
+ /*in*/ TNC_BufferReference message,
+ /*in*/ TNC_UInt32 messageLength,
+ /*in*/ TNC_MessageType messageType)
+{
+ TNC_Result res;
+
+ wpa_printf(MSG_INFO,
+ "IMC(hostap2) %s(imcID=%u, connectionID=%u, messageType=%u)",
+ __func__, (unsigned) imcID, (unsigned) connectionID,
+ (unsigned) messageType);
+ wpa_hexdump_ascii(MSG_INFO, "IMC(hostap2) message",
+ message, messageLength);
+
+ if (messageType == 1 && messageLength == 5 &&
+ os_memcmp(message, "hello", 5) == 0) {
+ char *msg = "i'm fine";
+
+ res = send_message(imcID, connectionID, msg, os_strlen(msg), 1);
+ if (res != TNC_RESULT_SUCCESS)
+ return res;
+ }
+
+ return TNC_RESULT_SUCCESS;
+}
+
+
+TNC_Result TNC_IMC_BatchEnding(
+ /*in*/ TNC_IMCID imcID,
+ /*in*/ TNC_ConnectionID connectionID)
+{
+ wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u, connectionID=%u)",
+ __func__, (unsigned) imcID, (unsigned) connectionID);
+
+ return TNC_RESULT_SUCCESS;
+}
+
+
+TNC_Result TNC_IMC_Terminate(
+ /*in*/ TNC_IMCID imcID)
+{
+ wpa_printf(MSG_INFO, "IMC(hostap2) %s(imcID=%u)",
+ __func__, (unsigned) imcID);
+
+ return TNC_RESULT_SUCCESS;
+}