diff options
Diffstat (limited to 'src/libcharon/plugins/tnc_imv/tnc_imv.c')
-rw-r--r-- | src/libcharon/plugins/tnc_imv/tnc_imv.c | 211 |
1 files changed, 180 insertions, 31 deletions
diff --git a/src/libcharon/plugins/tnc_imv/tnc_imv.c b/src/libcharon/plugins/tnc_imv/tnc_imv.c index fe628ee7e..f0b150743 100644 --- a/src/libcharon/plugins/tnc_imv/tnc_imv.c +++ b/src/libcharon/plugins/tnc_imv/tnc_imv.c @@ -1,6 +1,7 @@ /* * Copyright (C) 2006 Mike McCauley - * Copyright (C) 2010 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2010-2011 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 @@ -17,8 +18,11 @@ #include <dlfcn.h> +#include <tncif_pa_subtypes.h> + #include <debug.h> #include <library.h> +#include <utils/linked_list.h> #include <threading/mutex.h> typedef struct private_tnc_imv_t private_tnc_imv_t; @@ -54,9 +58,19 @@ struct private_tnc_imv_t { TNC_IMVID id; /** - * List of message types supported by IMC + * List of additional IMV IDs */ - TNC_MessageTypeList supported_types; + linked_list_t *additional_ids; + + /** + * List of message types supported by IMV - Vendor ID part + */ + TNC_VendorIDList supported_vids; + + /** + * List of message types supported by IMV - Subtype part + */ + TNC_MessageSubtypeList supported_subtypes; /** * Number of supported message types @@ -81,6 +95,50 @@ METHOD(imv_t, get_id, TNC_IMVID, return this->id; } +METHOD(imv_t, add_id, void, + private_tnc_imv_t *this, TNC_IMVID id) +{ + TNC_IMVID *new_id; + + new_id = malloc_thing(TNC_IMVID); + *new_id = id; + this->additional_ids->insert_last(this->additional_ids, new_id); +} + +METHOD(imv_t, has_id, bool, + private_tnc_imv_t *this, TNC_IMVID id) +{ + enumerator_t *enumerator; + TNC_IMVID *additional_id; + bool found = FALSE; + + /* check primary IMV ID */ + if (id == this->id) + { + return TRUE; + } + + /* return if there are no additional IMV IDs */ + if (this->additional_ids->get_count(this->additional_ids) == 0) + { + return FALSE; + } + + /* check additional IMV IDs */ + enumerator = this->additional_ids->create_enumerator(this->additional_ids); + while (enumerator->enumerate(enumerator, &additional_id)) + { + if (id == *additional_id) + { + found = TRUE; + break; + } + } + enumerator->destroy(enumerator); + + return found; +} + METHOD(imv_t, get_name, char*, private_tnc_imv_t *this) { @@ -91,67 +149,150 @@ METHOD(imv_t, set_message_types, void, private_tnc_imv_t *this, TNC_MessageTypeList supported_types, TNC_UInt32 type_count) { - char buf[512]; + char buf[BUF_LEN]; char *pos = buf; int len = sizeof(buf); - int written; + int i, written; + size_t size; + TNC_VendorID vid; + TNC_MessageSubtype subtype; + enum_name_t *pa_subtype_names; /* lock the imv_t instance */ this->mutex->lock(this->mutex); - /* Free an existing MessageType list */ - free(this->supported_types); - this->supported_types = NULL; + /* Free existing VendorID and MessageSubtype lists */ + free(this->supported_vids); + this->supported_vids = NULL; + free(this->supported_subtypes); + this->supported_subtypes = NULL; /* Store the new MessageType list */ this->type_count = type_count; if (type_count && supported_types) { - size_t size = type_count * sizeof(TNC_MessageType); - - int i; + size = type_count * sizeof(TNC_VendorID); + this->supported_vids = malloc(size); + size = type_count * sizeof(TNC_MessageSubtype); + this->supported_subtypes = malloc(size); for (i = 0; i < type_count; i++) { - written = snprintf(pos, len, " 0x%08x", supported_types[i]); + vid = (supported_types[i] >> 8) & TNC_VENDORID_ANY; + subtype = supported_types[i] & TNC_SUBTYPE_ANY; + + pa_subtype_names = get_pa_subtype_names(vid); + if (pa_subtype_names) + { + written = snprintf(pos, len," '%N/%N' 0x%06x/0x%02x", + pen_names, vid, pa_subtype_names, subtype, + vid, subtype); + } + else + { + written = snprintf(pos, len," '%N' 0x%06x/0x%02x", + pen_names, vid, vid, subtype); + } if (written >= len) { break; } pos += written; len -= written; + + this->supported_vids[i] = vid; + this->supported_subtypes[i] = subtype; } - this->supported_types = malloc(size); - memcpy(this->supported_types, supported_types, size); } *pos = '\0'; - DBG2(DBG_TNC, "IMV %u supports %u message types:%s", - this->id, type_count, buf); + DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s", + this->id, type_count, (type_count == 1) ? "":"s", buf); + + /* unlock the imv_t instance */ + this->mutex->unlock(this->mutex); +} + +METHOD(imv_t, set_message_types_long, void, + private_tnc_imv_t *this, TNC_VendorIDList supported_vids, + TNC_MessageSubtypeList supported_subtypes, TNC_UInt32 type_count) +{ + char buf[BUF_LEN]; + char *pos = buf; + int len = sizeof(buf); + int i, written; + size_t size; + TNC_VendorID vid; + TNC_MessageSubtype subtype; + enum_name_t *pa_subtype_names; /* lock the imv_t instance */ + this->mutex->lock(this->mutex); + + /* Free existing VendorID and MessageSubtype lists */ + free(this->supported_vids); + this->supported_vids = NULL; + free(this->supported_subtypes); + this->supported_subtypes = NULL; + + /* Store the new MessageType list */ + this->type_count = type_count; + if (type_count && supported_vids && supported_subtypes) + { + size = type_count * sizeof(TNC_VendorID); + this->supported_vids = malloc(size); + memcpy(this->supported_vids, supported_vids, size); + size = type_count * sizeof(TNC_MessageSubtype); + this->supported_subtypes = malloc(size); + memcpy(this->supported_subtypes, supported_subtypes, size); + + for (i = 0; i < type_count; i++) + { + vid = supported_vids[i]; + subtype = supported_subtypes[i]; + + pa_subtype_names = get_pa_subtype_names(vid); + if (pa_subtype_names) + { + written = snprintf(pos, len," '%N/%N' 0x%06x/0x%08x", + pen_names, vid, pa_subtype_names, subtype, + vid, subtype); + } + else + { + written = snprintf(pos, len," '%N' 0x%06x/0x%08x", + pen_names, vid, vid, subtype); + } + if (written >= len) + { + break; + } + pos += written; + len -= written; + } + } + *pos = '\0'; + DBG2(DBG_TNC, "IMV %u supports %u message type%s:%s", + this->id, type_count, (type_count == 1) ? "":"s", buf); + + /* unlock the imv_t instance */ this->mutex->unlock(this->mutex); } METHOD(imv_t, type_supported, bool, - private_tnc_imv_t *this, TNC_MessageType message_type) + private_tnc_imv_t *this, TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype) { - TNC_VendorID msg_vid, vid; - TNC_MessageSubtype msg_subtype, subtype; + TNC_VendorID vid; + TNC_MessageSubtype 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))) + vid = this->supported_vids[i]; + subtype = this->supported_subtypes[i]; + + if ((vid == TNC_VENDORID_ANY && subtype == TNC_SUBTYPE_ANY) || + (vid == msg_vid && (subtype == TNC_SUBTYPE_ANY || + subtype == msg_subtype))) { return TRUE; } @@ -164,7 +305,9 @@ METHOD(imv_t, destroy, void, { dlclose(this->handle); this->mutex->destroy(this->mutex); - free(this->supported_types); + this->additional_ids->destroy_function(this->additional_ids, free); + free(this->supported_vids); + free(this->supported_subtypes); free(this->name); free(this->path); free(this); @@ -181,13 +324,17 @@ imv_t* tnc_imv_create(char *name, char *path) .public = { .set_id = _set_id, .get_id = _get_id, + .add_id = _add_id, + .has_id = _has_id, .get_name = _get_name, .set_message_types = _set_message_types, + .set_message_types_long = _set_message_types_long, .type_supported = _type_supported, .destroy = _destroy, }, .name = name, .path = path, + .additional_ids = linked_list_create(), .mutex = mutex_create(MUTEX_TYPE_DEFAULT), ); @@ -222,6 +369,8 @@ imv_t* tnc_imv_create(char *name, char *path) } this->public.receive_message = dlsym(this->handle, "TNC_IMV_ReceiveMessage"); + this->public.receive_message_long = + dlsym(this->handle, "TNC_IMV_ReceiveMessageLong"); this->public.batch_ending = dlsym(this->handle, "TNC_IMV_BatchEnding"); this->public.terminate = |