| #include <net-snmp/net-snmp-config.h> |
| #include <net-snmp/net-snmp-features.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" |
| |
| netsnmp_feature_require(container_lifo) |
| |
| 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; |
| } |