diff options
Diffstat (limited to 'agent/mibgroup/sctp-mib/sctpTables_common.c')
-rw-r--r-- | agent/mibgroup/sctp-mib/sctpTables_common.c | 448 |
1 files changed, 448 insertions, 0 deletions
diff --git a/agent/mibgroup/sctp-mib/sctpTables_common.c b/agent/mibgroup/sctp-mib/sctpTables_common.c new file mode 100644 index 0000000..21ced90 --- /dev/null +++ b/agent/mibgroup/sctp-mib/sctpTables_common.c @@ -0,0 +1,448 @@ +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> + +#include "sctpTables_common.h" +#include "sctpAssocTable.h" +#include "sctpAssocRemAddrTable.h" +#include "sctpAssocLocalAddrTable.h" +#include "sctpLookupLocalPortTable.h" +#include "sctpLookupRemPortTable.h" +#include "sctpLookupRemHostNameTable.h" +#include "sctpLookupRemPrimIPAddrTable.h" +#include "sctpLookupRemIPAddrTable.h" + +static void +sctpAssocTable_collect_invalid(void *what, void *magic) +{ + sctpAssocTable_entry *entry = what; + netsnmp_container *to_delete = magic; + + if (entry->valid) + entry->valid = 0; + else + CONTAINER_INSERT(to_delete, entry); +} + +/* + * Remove all entries from sctpAssocTable, which are not marked as valid. + * All valid entries are then marked as invalid (to delete them in next cache + * load, if the entry is not updated). + */ +void +sctpAssocTable_delete_invalid(netsnmp_container *assocTable) +{ + netsnmp_container *to_delete = netsnmp_container_find("lifo"); + + CONTAINER_FOR_EACH(assocTable, sctpAssocTable_collect_invalid, + to_delete); + + while (CONTAINER_SIZE(to_delete)) { + sctpAssocTable_entry *entry = CONTAINER_FIRST(to_delete); + CONTAINER_REMOVE(assocTable, entry); + sctpAssocTable_entry_free(entry); + CONTAINER_REMOVE(to_delete, NULL); + } + CONTAINER_FREE(to_delete); +} + +static void +sctpAssocRemAddrTable_collect_invalid(void *what, void *magic) +{ + sctpAssocRemAddrTable_entry *entry = what; + netsnmp_container *to_delete = magic; + + if (entry->valid) + entry->valid = 0; + else + CONTAINER_INSERT(to_delete, entry); +} + +/* + * Remove all entries from sctpAssocRemAddrTable, which are not marked as valid. + * All valid entries are then marked as invalid (to delete them in next cache + * load, if the entry is not updated). + */ +void +sctpAssocRemAddrTable_delete_invalid(netsnmp_container *remAddrTable) +{ + netsnmp_container *to_delete = netsnmp_container_find("lifo"); + + CONTAINER_FOR_EACH(remAddrTable, sctpAssocRemAddrTable_collect_invalid, + to_delete); + + while (CONTAINER_SIZE(to_delete)) { + sctpAssocRemAddrTable_entry *entry = CONTAINER_FIRST(to_delete); + CONTAINER_REMOVE(remAddrTable, entry); + sctpAssocRemAddrTable_entry_free(entry); + CONTAINER_REMOVE(to_delete, NULL); + } + CONTAINER_FREE(to_delete); +} + +static void +sctpAssocLocalAddrTable_collect_invalid(void *what, void *magic) +{ + sctpAssocLocalAddrTable_entry *entry = what; + netsnmp_container *to_delete = magic; + + if (entry->valid) + entry->valid = 0; + else + CONTAINER_INSERT(to_delete, entry); +} + +/* + * Remove all entries from sctpAssocLocalAddrTable, which are not marked as valid. + * All valid entries are then marked as invalid (to delete them in next cache + * load, if the entry is not updated). + */ +void +sctpAssocLocalAddrTable_delete_invalid(netsnmp_container *localAddrTable) +{ + netsnmp_container *to_delete = netsnmp_container_find("lifo"); + + CONTAINER_FOR_EACH(localAddrTable, + sctpAssocLocalAddrTable_collect_invalid, to_delete); + + while (CONTAINER_SIZE(to_delete)) { + sctpAssocLocalAddrTable_entry *entry = CONTAINER_FIRST(to_delete); + CONTAINER_REMOVE(localAddrTable, entry); + sctpAssocLocalAddrTable_entry_free(entry); + CONTAINER_REMOVE(to_delete, NULL); + } + CONTAINER_FREE(to_delete); +} + + +int +sctpAssocRemAddrTable_add_or_update(netsnmp_container *remAddrTable, + sctpAssocRemAddrTable_entry * entry) +{ + /* + * we have full sctpAssocLocalAddrTable entry, update or add it in the container + */ + sctpAssocRemAddrTable_entry *old; + + entry->valid = 1; + + /* + * try to find it in the container + */ + sctpAssocRemAddrTable_entry_update_index(entry); + old = CONTAINER_FIND(remAddrTable, entry); + + if (old != NULL) { + /* + * update existing entry, don't overwrite the timestamp + */ + time_t timestamp = old->sctpAssocRemAddrStartTime; + if (timestamp == 0 && entry->sctpAssocRemAddrStartTime == 0) + timestamp = netsnmp_get_agent_uptime(); /* set the timestamp if it was not set before */ + sctpAssocRemAddrTable_entry_copy(entry, old); + old->sctpAssocRemAddrStartTime = timestamp; + sctpAssocRemAddrTable_entry_free(entry); + + } else { + /* + * the entry is new, add it there + */ + if (entry->sctpAssocRemAddrStartTime == 0) { + entry->sctpAssocRemAddrStartTime = netsnmp_get_agent_uptime(); + } + CONTAINER_INSERT(remAddrTable, entry); + } + + return SNMP_ERR_NOERROR; +} + +int +sctpAssocLocalAddrTable_add_or_update(netsnmp_container *localAddrTable, + sctpAssocLocalAddrTable_entry * + entry) +{ + /* + * we have full sctpAssocLocalAddrTable entry, update or add it in the container + */ + sctpAssocLocalAddrTable_entry *old; + + entry->valid = 1; + + /* + * try to find it in the container + */ + sctpAssocLocalAddrTable_entry_update_index(entry); + old = CONTAINER_FIND(localAddrTable, entry); + + if (old != NULL) { + /* + * update existing entry, don't overwrite the timestamp + */ + time_t timestamp = old->sctpAssocLocalAddrStartTime; + if (timestamp == 0 && entry->sctpAssocLocalAddrStartTime == 0) + timestamp = netsnmp_get_agent_uptime(); /* set the timestamp if it was not set before */ + sctpAssocLocalAddrTable_entry_copy(entry, old); + old->sctpAssocLocalAddrStartTime = timestamp; + sctpAssocLocalAddrTable_entry_free(entry); + + } else { + /* + * the entry is new, add it there + */ + if (entry->sctpAssocLocalAddrStartTime == 0) { + entry->sctpAssocLocalAddrStartTime = + netsnmp_get_agent_uptime(); + } + CONTAINER_INSERT(localAddrTable, entry); + } + + return SNMP_ERR_NOERROR; +} + +int +sctpAssocTable_add_or_update(netsnmp_container *assocTable, + sctpAssocTable_entry * entry) +{ + /* + * we have full sctpAssocTable entry, update or add it in the container + */ + sctpAssocTable_entry *old; + + entry->valid = 1; + + /* + * try to find it in the container + */ + sctpAssocTable_entry_update_index(entry); + old = CONTAINER_FIND(assocTable, entry); + + if (old != NULL) { + /* + * update existing entry, don't overwrite the timestamp + */ + time_t timestamp = old->sctpAssocStartTime; + if (timestamp == 0 && entry->sctpAssocStartTime == 0 + && entry->sctpAssocState >= SCTPASSOCSTATE_ESTABLISHED) + timestamp = netsnmp_get_agent_uptime(); /* set the timestamp if it was not set before and entry reaches the right state */ + sctpAssocTable_entry_copy(entry, old); + old->sctpAssocStartTime = timestamp; + sctpAssocTable_entry_free(entry); + + } else { + /* + * the entry is new, add it there + */ + if (entry->sctpAssocStartTime == 0 + && entry->sctpAssocState >= SCTPASSOCSTATE_ESTABLISHED) { + entry->sctpAssocStartTime = netsnmp_get_agent_uptime(); + } + CONTAINER_INSERT(assocTable, entry); + } + + return SNMP_ERR_NOERROR; +} + +static void +sctpTables_add_local_port(sctpAssocTable_entry * assoc, + sctpTables_containers * containers) +{ + sctpLookupLocalPortTable_entry *entry; + + entry = sctpLookupLocalPortTable_entry_create(); + if (entry == NULL) { + DEBUGMSGTL(("sctp:tables:fill_lookup", + "cannot create sctpLookupLocalPortTable_entry")); + return; + } + + entry->sctpAssocId = assoc->sctpAssocId; + entry->sctpAssocLocalPort = assoc->sctpAssocLocalPort; + entry->sctpLookupLocalPortStartTime = assoc->sctpAssocStartTime; + sctpLookupLocalPortTable_entry_update_index(entry); + CONTAINER_INSERT(containers->sctpLookupLocalPortTable, entry); +} + +static void +sctpTables_add_rem_port(sctpAssocTable_entry * assoc, + sctpTables_containers * containers) +{ + sctpLookupRemPortTable_entry *entry; + + entry = sctpLookupRemPortTable_entry_create(); + if (entry == NULL) { + DEBUGMSGTL(("sctp:tables:fill_lookup", + "cannot create sctpLookupRemPortTable_entry")); + return; + } + + entry->sctpAssocId = assoc->sctpAssocId; + entry->sctpAssocRemPort = assoc->sctpAssocRemPort; + entry->sctpLookupRemPortStartTime = assoc->sctpAssocStartTime; + sctpLookupRemPortTable_entry_update_index(entry); + CONTAINER_INSERT(containers->sctpLookupRemPortTable, entry); +} + +static void +sctpTables_add_rem_hostname(sctpAssocTable_entry * assoc, + sctpTables_containers * containers) +{ + sctpLookupRemHostNameTable_entry *entry; + + if (assoc->sctpAssocRemHostName_len == 0) + return; /* the association does not know its hostname */ + + entry = sctpLookupRemHostNameTable_entry_create(); + if (entry == NULL) { + DEBUGMSGTL(("sctp:tables:fill_lookup", + "cannot create sctpLookupRemHostNameTable_entry")); + return; + } + + entry->sctpAssocId = assoc->sctpAssocId; + entry->sctpAssocRemHostName_len = assoc->sctpAssocRemHostName_len; + memcpy(entry->sctpAssocRemHostName, assoc->sctpAssocRemHostName, + assoc->sctpAssocRemHostName_len); + entry->sctpLookupRemHostNameStartTime = assoc->sctpAssocStartTime; + + sctpLookupRemHostNameTable_entry_update_index(entry); + CONTAINER_INSERT(containers->sctpLookupRemHostNameTable, entry); +} + +static void +sctpTables_add_rem_prim_ip_addr(sctpAssocTable_entry * assoc, + sctpTables_containers * containers) +{ + sctpLookupRemPrimIPAddrTable_entry *entry; + + entry = sctpLookupRemPrimIPAddrTable_entry_create(); + if (entry == NULL) { + DEBUGMSGTL(("sctp:tables:fill_lookup", + "cannot create sctpLookupRemPrimIPAddrTable_entry")); + return; + } + + entry->sctpAssocId = assoc->sctpAssocId; + entry->sctpAssocRemPrimAddrType = assoc->sctpAssocRemPrimAddrType; + entry->sctpAssocRemPrimAddr_len = assoc->sctpAssocRemPrimAddr_len; + memcpy(entry->sctpAssocRemPrimAddr, assoc->sctpAssocRemPrimAddr, + assoc->sctpAssocRemPrimAddr_len); + entry->sctpLookupRemPrimIPAddrStartTime = assoc->sctpAssocStartTime; + + sctpLookupRemPrimIPAddrTable_entry_update_index(entry); + CONTAINER_INSERT(containers->sctpLookupRemPrimIPAddrTable, entry); +} + +static void +sctpTables_fill_lookup_assoc(void *what, void *magic) +{ + sctpAssocTable_entry *entry = what; + sctpTables_containers *containers = magic; + + sctpTables_add_local_port(entry, containers); + sctpTables_add_rem_port(entry, containers); + sctpTables_add_rem_hostname(entry, containers); + sctpTables_add_rem_prim_ip_addr(entry, containers); +} + +static void +sctpTables_add_rem_ip_addr(sctpAssocRemAddrTable_entry * rem_addr, + sctpTables_containers * containers) +{ + sctpLookupRemIPAddrTable_entry *entry; + + entry = sctpLookupRemIPAddrTable_entry_create(); + if (entry == NULL) { + DEBUGMSGTL(("sctp:tables:fill_lookup", + "cannot create sctpLookupRemIPAddrTable_entry")); + return; + } + + entry->sctpAssocId = rem_addr->sctpAssocId; + entry->sctpAssocRemAddrType = rem_addr->sctpAssocRemAddrType; + entry->sctpAssocRemAddr_len = rem_addr->sctpAssocRemAddr_len; + memcpy(entry->sctpAssocRemAddr, rem_addr->sctpAssocRemAddr, + rem_addr->sctpAssocRemAddr_len); + entry->sctpLookupRemIPAddrStartTime = + rem_addr->sctpAssocRemAddrStartTime; + + sctpLookupRemIPAddrTable_entry_update_index(entry); + CONTAINER_INSERT(containers->sctpLookupRemIPAddrTable, entry); +} + +static void +sctpTables_fill_lookup_rem_addr(void *what, void *magic) +{ + sctpAssocRemAddrTable_entry *entry = what; + sctpTables_containers *containers = magic; + sctpTables_add_rem_ip_addr(entry, containers); +} + +int +sctpTables_fill_lookup(sctpTables_containers * containers) +{ + /* + * clear all the lookup tables + */ + sctpLookupLocalPortTable_container_clear(containers-> + sctpLookupLocalPortTable); + sctpLookupRemPortTable_container_clear(containers-> + sctpLookupRemPortTable); + sctpLookupRemHostNameTable_container_clear(containers-> + sctpLookupRemHostNameTable); + sctpLookupRemPrimIPAddrTable_container_clear(containers-> + sctpLookupRemPrimIPAddrTable); + sctpLookupRemIPAddrTable_container_clear(containers-> + sctpLookupRemIPAddrTable); + + /* + * fill the lookup tables + */ + CONTAINER_FOR_EACH(containers->sctpAssocTable, + sctpTables_fill_lookup_assoc, containers); + CONTAINER_FOR_EACH(containers->sctpAssocRemAddrTable, + sctpTables_fill_lookup_rem_addr, containers); + + return SNMP_ERR_NOERROR; +} + + + +int +sctpTables_load(void) +{ + sctpTables_containers containers; + int ret; + u_long flags = 0; + + containers.sctpAssocTable = sctpAssocTable_get_container(); + containers.sctpAssocRemAddrTable = + sctpAssocRemAddrTable_get_container(); + containers.sctpAssocLocalAddrTable = + sctpAssocLocalAddrTable_get_container(); + containers.sctpLookupLocalPortTable = + sctpLookupLocalPortTable_get_container(); + containers.sctpLookupRemPortTable = + sctpLookupRemPortTable_get_container(); + containers.sctpLookupRemHostNameTable = + sctpLookupRemHostNameTable_get_container(); + containers.sctpLookupRemPrimIPAddrTable = + sctpLookupRemPrimIPAddrTable_get_container(); + containers.sctpLookupRemIPAddrTable = + sctpLookupRemIPAddrTable_get_container(); + + ret = sctpTables_arch_load(&containers, &flags); + + if (flags | SCTP_TABLES_LOAD_FLAG_DELETE_INVALID) { + sctpAssocTable_delete_invalid(containers.sctpAssocTable); + sctpAssocRemAddrTable_delete_invalid(containers. + sctpAssocRemAddrTable); + sctpAssocLocalAddrTable_delete_invalid(containers. + sctpAssocLocalAddrTable); + } + + if (flags | SCTP_TABLES_LOAD_FLAG_AUTO_LOOKUP) { + ret = sctpTables_fill_lookup(&containers); + } + + return ret; +} |