diff options
Diffstat (limited to 'agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c')
-rw-r--r-- | agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c b/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c new file mode 100644 index 0000000..9e14664 --- /dev/null +++ b/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c @@ -0,0 +1,298 @@ +/* + * udpEndpointTable MIB architecture support + * + * $Id: udp_endpoint_linux.c 17723 2009-08-05 20:07:38Z dts12 $ + */ +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> + +#include <net-snmp/agent/net-snmp-agent-includes.h> +#include <net-snmp/library/file_utils.h> +#include <net-snmp/library/text_utils.h> + +#include <net-snmp/data_access/ipaddress.h> +#include <net-snmp/data_access/udp_endpoint.h> + +#include "udp-mib/udpEndpointTable/udpEndpointTable_constants.h" + +#include "udp_endpoint_private.h" + +#include <fcntl.h> + +static int _load4(netsnmp_container *container, u_int flags); +#if defined (NETSNMP_ENABLE_IPV6) +static int _load6(netsnmp_container *container, u_int flags); +#endif + +/* + * initialize arch specific storage + * + * @retval 0: success + * @retval <0: error + */ +int +netsnmp_arch_udp_endpoint_entry_init(netsnmp_udp_endpoint_entry *entry) +{ + /* + * init + */ + return 0; +} + +/* + * cleanup arch specific storage + */ +void +netsnmp_arch_udp_endpoint_entry_cleanup(netsnmp_udp_endpoint_entry *entry) +{ + /* + * cleanup + */ +} + +/* + * copy arch specific storage + */ +int +netsnmp_arch_udp_endpoint_entry_copy(netsnmp_udp_endpoint_entry *lhs, + netsnmp_udp_endpoint_entry *rhs) +{ + return 0; +} + +/* + * delete an entry + */ +int +netsnmp_arch_udp_endpoint_delete(netsnmp_udp_endpoint_entry *entry) +{ + if (NULL == entry) + return -1; + /** xxx-rks:9 udp_endpoint delete not implemented */ + return -1; +} + + +/** + * + * @retval 0 no errors + * @retval !0 errors + */ +int +netsnmp_arch_udp_endpoint_container_load(netsnmp_container *container, + u_int load_flags ) +{ + int rc = 0; + + rc = _load4(container, load_flags); + if(rc < 0) { + u_int flags = NETSNMP_ACCESS_UDP_ENDPOINT_FREE_KEEP_CONTAINER; + netsnmp_access_udp_endpoint_container_free(container, flags); + return rc; + } + +#if defined (NETSNMP_ENABLE_IPV6) + rc = _load6(container, load_flags); + if(rc < 0) { + u_int flags = NETSNMP_ACCESS_UDP_ENDPOINT_FREE_KEEP_CONTAINER; + netsnmp_access_udp_endpoint_container_free(container, flags); + return rc; + } +#endif + + return 0; +} + +/** + * @internal + * process token value index line + */ +static int +_process_line_udp_ep(netsnmp_line_info *line_info, void *mem, + struct netsnmp_line_process_info_s* lpi) +{ + netsnmp_udp_endpoint_entry *ep = (netsnmp_udp_endpoint_entry *)mem; + char *ptr, *sep; + u_char *u_ptr; + size_t u_ptr_len, offset, len; + unsigned long long inode; + size_t count = 0; + + /* + * skip 'sl' + */ + ptr = skip_not_white(line_info->start); + if (NULL == ptr) { + DEBUGMSGTL(("access:udp_endpoint", "no sl '%s'\n", + line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + ptr = skip_white(ptr); + if (NULL == ptr) { + DEBUGMSGTL(("text:util:tvi", "no space after sl '%s'\n", + line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + + /* + * get local address. ignore error on hex conversion, since that + * function doesn't like the ':' between address and port. check the + * offset to see if it worked. May need to flip string too. + */ + u_ptr = ep->loc_addr; + u_ptr_len = sizeof(ep->loc_addr); + sep = strchr(ptr, ':'); + if (NULL == sep) { + DEBUGMSGTL(("text:util:tvi", "no ':' '%s'\n", + line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + len = (sep - ptr); + if (-1 == netsnmp_addrstr_hton(ptr, len)) { + DEBUGMSGTL(("text:util:tvi", "bad length %d for loc addr '%s'\n", + u_ptr_len, line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + offset = 0; + netsnmp_hex_to_binary(&u_ptr, &u_ptr_len, &offset, 0, ptr, NULL); + if ((4 != offset) && (16 != offset)) { + DEBUGMSGTL(("text:util:tvi", "bad offset %d for loc addr '%s'\n", + offset, line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + ep->loc_addr_len = offset; + ptr += (offset * 2); + ++ptr; /* skip ':' */ + + /* + * get local port + */ + ep->loc_port = strtol(ptr, &ptr, 16); + ptr = skip_white(ptr); + + /* + * get remote address. ignore error on hex conversion, since that + * function doesn't like the ':' between address and port. check the + * offset to see if it worked. May need to flip string too. + */ + u_ptr = ep->rmt_addr; + u_ptr_len = sizeof(ep->rmt_addr); + sep = strchr(ptr, ':'); + if (NULL == sep) { + DEBUGMSGTL(("text:util:tvi", "no ':' '%s'\n", + line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + len = (sep - ptr); + if (-1 == netsnmp_addrstr_hton(ptr, len)) { + DEBUGMSGTL(("text:util:tvi", "bad length %d for rmt addr '%s'\n", + u_ptr_len, line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + offset = 0; + netsnmp_hex_to_binary(&u_ptr, &u_ptr_len, &offset, 0, ptr, NULL); + if ((4 != offset) && (16 != offset)) { + DEBUGMSGTL(("text:util:tvi", "bad offset %d for rmt addr '%s'\n", + offset, line_info->start)); + return PMLP_RC_MEMORY_UNUSED; + } + ep->rmt_addr_len = offset; + ptr += (offset * 2); + ++ptr; /* skip ':' */ + + /* + * get remote port + */ + ep->rmt_port = strtol(ptr, &ptr, 16); + ptr = skip_white(ptr); + + /* + * get state too + */ + ep->state = strtol(ptr, &ptr, 16); + + /* + * Use inode as instance value. + */ + while (count != 5) { + ptr = skip_white(ptr); + ptr = skip_not_white(ptr); + count++; + } + inode = strtoull(ptr, &ptr, 0); + ep->instance = (u_int)inode; + + ep->index = (u_int)(lpi->user_context); + lpi->user_context = (void*)((u_int)(lpi->user_context) + 1); + + ep->oid_index.oids = &ep->index; + ep->oid_index.len = 1; + + return PMLP_RC_MEMORY_USED; +} + +/** + * + * @retval 0 no errors + * @retval !0 errors + */ +static int +_load4(netsnmp_container *container, u_int load_flags) +{ + netsnmp_file *fp; + netsnmp_line_process_info lpi; + + if (NULL == container) + return -1; + + /* + * allocate file resources + */ + fp = netsnmp_file_fill(NULL, "/proc/net/udp" , O_RDONLY, 0, 0); + if (NULL == fp) /** msg already logged */ + return -2; + + memset(&lpi, 0x0, sizeof(lpi)); + lpi.mem_size = sizeof(netsnmp_udp_endpoint_entry); + lpi.process = _process_line_udp_ep; + lpi.user_context = (void*)0; + + container = netsnmp_file_text_parse(fp, container, PM_USER_FUNCTION, + 0, &lpi); + netsnmp_file_release(fp); + return (NULL == container); +} + +#if defined (NETSNMP_ENABLE_IPV6) +/** + * + * @retval 0 no errors + * @retval !0 errors + */ +static int +_load6(netsnmp_container *container, u_int load_flags) +{ + netsnmp_file *fp; + netsnmp_line_process_info lpi; + + if (NULL == container) + return -1; + + /* + * allocate file resources + */ + fp = netsnmp_file_fill(NULL, "/proc/net/udp6" , O_RDONLY, 0, 0); + if (NULL == fp) /** msg already logged */ + return -2; + + memset(&lpi, 0x0, sizeof(lpi)); + lpi.mem_size = sizeof(netsnmp_udp_endpoint_entry); + lpi.process = _process_line_udp_ep; + lpi.user_context = (void*)CONTAINER_SIZE(container); + + container = netsnmp_file_text_parse(fp, container, PM_USER_FUNCTION, + 0, &lpi); + netsnmp_file_release(fp); + return (NULL == container); +} +#endif /* NETSNMP_ENABLE_IPV6 */ |