implemented receive_message() function
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 7 Nov 2010 00:17:21 +0000 (01:17 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 9 Nov 2010 19:43:50 +0000 (20:43 +0100)
src/libcharon/plugins/tnc_imc/tnc_imc.c
src/libcharon/plugins/tnc_imc/tnc_imc_manager.c
src/libcharon/plugins/tnc_imv/tnc_imv.c
src/libcharon/plugins/tnc_imv/tnc_imv_manager.c
src/libcharon/plugins/tnccs_20/tnccs_20.c
src/libcharon/tnc/imc/imc.h
src/libcharon/tnc/imc/imc_manager.h
src/libcharon/tnc/imv/imv.h
src/libcharon/tnc/imv/imv_manager.h

index f87853b..29f34d9 100644 (file)
@@ -84,6 +84,33 @@ METHOD(imc_t, set_message_types, void,
        }
 }
 
+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)
 {
@@ -106,6 +133,7 @@ imc_t* tnc_imc_create(char* name, char *filename)
                        .get_id = _get_id,
                        .get_name = _get_name,
                        .set_message_types = _set_message_types,
+                       .type_supported = _type_supported,
                        .destroy = _destroy,
         },
        );
index e6555cb..8e05644 100644 (file)
@@ -124,6 +124,26 @@ METHOD(imc_manager_t, set_message_types, TNC_Result,
        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)
@@ -157,6 +177,7 @@ imc_manager_t* tnc_imc_manager_create(void)
                        .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(),
index 722f6d9..3dfc50b 100644 (file)
@@ -84,6 +84,33 @@ METHOD(imv_t, set_message_types, void,
        }
 }
 
+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)
 {
@@ -106,6 +133,7 @@ imv_t* tnc_imv_create(char *name, char *filename)
                        .get_id = _get_id,
                        .get_name = _get_name,
                        .set_message_types = _set_message_types,
+                       .type_supported = _type_supported,
                        .destroy = _destroy,
         },
        );
index a5309e4..fa6d35d 100644 (file)
@@ -109,6 +109,27 @@ METHOD(imv_manager_t, set_message_types, TNC_Result,
        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)
 {
@@ -140,6 +161,7 @@ imv_manager_t* tnc_imv_manager_create(void)
                        .add = _add,
                        .notify_connection_change = _notify_connection_change,
                        .set_message_types = _set_message_types,
+                       .receive_message = _receive_message,
                        .destroy = _destroy,
         },
                .imvs = linked_list_create(),
index 5afc6e1..8f6f11e 100644 (file)
@@ -63,6 +63,9 @@ METHOD(tnccs_t, send_message, void,
 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,
@@ -73,14 +76,34 @@ METHOD(tls_t, process, status_t,
        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)));
index 2f859e8..0a50767 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <tnc/tncifimc.h>
 
+#include <library.h>
+
 typedef struct imc_t imc_t;
 
 struct imc_t {
@@ -152,6 +154,14 @@ 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);
index 9621f05..da78d80 100644 (file)
@@ -70,6 +70,20 @@ struct imc_manager_t {
                                                                        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);
index fa8e048..e5194a9 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <tnc/tncifimv.h>
 
+#include <library.h>
+
 typedef struct imv_t imv_t;
 
 struct imv_t {
@@ -152,6 +154,14 @@ 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);
index 4d98555..b78c948 100644 (file)
@@ -63,6 +63,20 @@ struct imv_manager_t {
                                                                        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);