From 757470fe3c79081b3b106f669f39e45f7aaa4baf Mon Sep 17 00:00:00 2001 From: Mitsuru Chinen Date: Mon, 20 Oct 2008 14:36:05 +0900 Subject: [PATCH] Fix for tcpConnnectionTable, tcpListenerTable, udpEndpointTable From net-snmp patch tracker: [ 1670511 ] agent returns 0 for process id in tcp and udp mib http://sourceforge.net/tracker/index.php?func=detail&aid=1670511&group_id=12694&atid=312694 Signed-off-by: Mitsuru Chinen --- agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c | 18 ++-- .../udp-mib/data_access/udp_endpoint_linux.c | 7 +- .../udp-mib/udpEndpointTable/udpEndpointTable.c | 17 +++- .../udp-mib/udpEndpointTable/udpEndpointTable.h | 12 ++- .../udpEndpointTable_data_access.c | 3 +- agent/mibgroup/util_funcs.c | 100 ++++++++++++++++++++ agent/mibgroup/util_funcs.h | 4 + include/net-snmp/data_access/udp_endpoint.h | 1 + 8 files changed, 146 insertions(+), 16 deletions(-) diff --git a/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c b/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c index 7ffebe6..72495a9 100644 --- a/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c +++ b/agent/mibgroup/tcp-mib/data_access/tcpConn_linux.c @@ -11,7 +11,7 @@ #include "tcp-mib/tcpConnectionTable/tcpConnectionTable_constants.h" #include "tcp-mib/data_access/tcpConn_private.h" - +#include "mibgroup/util_funcs.h" static int linux_states[12] = { 1, 5, 3, 4, 6, 7, 11, 1, 8, 9, 2, 10 }; @@ -135,15 +135,16 @@ _load4(netsnmp_container *container, u_int load_flags) while (fgets(line, sizeof(line), in)) { netsnmp_tcpconn_entry *entry; int state, rc, local_port, remote_port, tmp_state; + unsigned long long inode; size_t buf_len, offset; u_char local_addr[10], remote_addr[10]; u_char *tmp_ptr; - if (5 != (rc = sscanf(line, "%*d: %8[0-9A-Z]:%x %8[0-9A-Z]:%x %x", + if (6 != (rc = sscanf(line, "%*d: %8[0-9A-Z]:%x %8[0-9A-Z]:%x %x %*x:%*x %*x:%*x %*x %*x %*x %llu", local_addr, &local_port, - remote_addr, &remote_port, &tmp_state))) { + remote_addr, &remote_port, &tmp_state, &inode))) { DEBUGMSGT(("access:tcpconn:container", - "error parsing line (%d != 5)\n", rc)); + "error parsing line (%d != 6)\n", rc)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); continue; } @@ -180,6 +181,7 @@ _load4(netsnmp_container *container, u_int load_flags) entry->loc_port = (unsigned short) local_port; entry->rmt_port = (unsigned short) remote_port; entry->tcpConnState = state; + entry->pid = get_pid_from_inode(inode); /** the addr string may need work */ buf_len = strlen(local_addr); @@ -286,15 +288,16 @@ _load6(netsnmp_container *container, u_int load_flags) while (fgets(line, sizeof(line), in)) { netsnmp_tcpconn_entry *entry; int state, rc, local_port, remote_port, tmp_state; + unsigned long long inode; size_t buf_len, offset; u_char local_addr[48], remote_addr[48]; u_char *tmp_ptr; - if (5 != (rc = sscanf(line, "%*d: %47[0-9A-Z]:%x %47[0-9A-Z]:%x %x", + if (6 != (rc = sscanf(line, "%*d: %47[0-9A-Z]:%x %47[0-9A-Z]:%x %x %*x:%*x %*x:%*x %*x %*x %*x %llu", local_addr, &local_port, - remote_addr, &remote_port, &tmp_state))) { + remote_addr, &remote_port, &tmp_state, &inode))) { DEBUGMSGT(("access:tcpconn:container", - "error parsing line (%d != 5)\n", rc)); + "error parsing line (%d != 6)\n", rc)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); continue; } @@ -331,6 +334,7 @@ _load6(netsnmp_container *container, u_int load_flags) entry->loc_port = (unsigned short) local_port; entry->rmt_port = (unsigned short) remote_port; entry->tcpConnState = state; + entry->pid = get_pid_from_inode(inode); /** the addr string may need work */ buf_len = strlen((char*)local_addr); diff --git a/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c b/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c index 4e43e01..70dcace 100644 --- a/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c +++ b/agent/mibgroup/udp-mib/data_access/udp_endpoint_linux.c @@ -14,7 +14,7 @@ #include #include "udp-mib/udpEndpointTable/udpEndpointTable_constants.h" - +#include "mibgroup/util_funcs.h" #include "udp_endpoint_private.h" #include @@ -222,6 +222,11 @@ _process_line_udp_ep(netsnmp_line_info *line_info, void *mem, inode = strtoull(ptr, &ptr, 0); ep->instance = (u_int)inode; + /* + * get the pid also + */ + ep->pid = get_pid_from_inode(inode); + ep->index = (u_int)(lpi->user_context); lpi->user_context = (void*)((u_int)(lpi->user_context) + 1); diff --git a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.c b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.c index 5da022f..b2d8b23 100644 --- a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.c +++ b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.c @@ -223,7 +223,8 @@ udpEndpointTable_indexes_set_tbl_idx(udpEndpointTable_mib_index * tbl_idx, size_t udpEndpointRemoteAddress_val_ptr_len, u_long udpEndpointRemotePort_val, - u_long udpEndpointInstance_val) + u_long udpEndpointInstance_val, + u_long udpEndpointProcess_val) { DEBUGMSGTL(("verbose:udpEndpointTable:udpEndpointTable_indexes_set_tbl_idx", "called\n")); @@ -292,6 +293,10 @@ udpEndpointTable_indexes_set_tbl_idx(udpEndpointTable_mib_index * tbl_idx, * udpEndpointInstance(7)/UNSIGNED32/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/h */ tbl_idx->udpEndpointInstance = udpEndpointInstance_val; + /* + * udpEndpointProcess(8)/UNSIGNED32/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/h + */ + tbl_idx->udpEndpointProcess = udpEndpointProcess_val; return MFD_SUCCESS; @@ -320,7 +325,8 @@ udpEndpointTable_indexes_set(udpEndpointTable_rowreq_ctx * rowreq_ctx, char *udpEndpointRemoteAddress_val_ptr, size_t udpEndpointRemoteAddress_val_ptr_len, u_long udpEndpointRemotePort_val, - u_long udpEndpointInstance_val) + u_long udpEndpointInstance_val, + u_long udpEndpointProcess_val) { DEBUGMSGTL(("verbose:udpEndpointTable:udpEndpointTable_indexes_set", "called\n")); @@ -335,7 +341,8 @@ udpEndpointTable_indexes_set(udpEndpointTable_rowreq_ctx * rowreq_ctx, udpEndpointRemoteAddress_val_ptr, udpEndpointRemoteAddress_val_ptr_len, udpEndpointRemotePort_val, - udpEndpointInstance_val)) + udpEndpointInstance_val, + udpEndpointProcess_val)) return MFD_ERROR; /* @@ -402,9 +409,9 @@ udpEndpointProcess_get(udpEndpointTable_rowreq_ctx * rowreq_ctx, /* * TODO:231:o: |-> Extract the current value of the udpEndpointProcess data. - * copy (* udpEndpointProcess_val_ptr ) from rowreq_ctx->data + * copy (* udpEndpointProcess_val_ptr ) from rowreq_ctx->tbl_idx.udpEndpointProcess */ - (*udpEndpointProcess_val_ptr) = rowreq_ctx->data.udpEndpointProcess; + (*udpEndpointProcess_val_ptr) = rowreq_ctx->tbl_idx.udpEndpointProcess; return MFD_SUCCESS; } /* udpEndpointProcess_get */ diff --git a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.h b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.h index f023db8..fce1659 100644 --- a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.h +++ b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable.h @@ -132,6 +132,11 @@ config_require(udp-mib/udpEndpointTable/udpEndpointTable_data_access) */ u_long udpEndpointInstance; + /* + * udpEndpointProcess(8)/UNSIGNED32/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/h + */ + u_long udpEndpointProcess; + } udpEndpointTable_mib_index; @@ -257,7 +262,9 @@ config_require(udp-mib/udpEndpointTable/udpEndpointTable_data_access) u_long udpEndpointRemotePort_val, u_long - udpEndpointInstance_val); + udpEndpointInstance_val, + u_long + udpEndpointProcess_val); int udpEndpointTable_indexes_set(udpEndpointTable_rowreq_ctx * rowreq_ctx, @@ -273,7 +280,8 @@ config_require(udp-mib/udpEndpointTable/udpEndpointTable_data_access) size_t udpEndpointRemoteAddress_val_ptr_len, u_long udpEndpointRemotePort_val, - u_long udpEndpointInstance_val); + u_long udpEndpointInstance_val, + u_long udpEndpointProcess_val); diff --git a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c index af4762f..1e9ef0f 100644 --- a/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c +++ b/agent/mibgroup/udp-mib/udpEndpointTable/udpEndpointTable_data_access.c @@ -265,7 +265,8 @@ udpEndpointTable_container_load(netsnmp_container *container) ep->rmt_addr, ep->rmt_addr_len, ep->rmt_port, - ep->instance)) { + ep->instance, + ep->pid)) { snmp_log(LOG_ERR, "error setting index while loading " "udpEndpointTable data.\n"); diff --git a/agent/mibgroup/util_funcs.c b/agent/mibgroup/util_funcs.c index 95ee4bf..26826f7 100644 --- a/agent/mibgroup/util_funcs.c +++ b/agent/mibgroup/util_funcs.c @@ -86,6 +86,20 @@ #ifdef HAVE_SYS_STAT_H #include #endif +#if HAVE_DIRENT_H +#include +#else +# define dirent direct +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif #include #include @@ -1192,3 +1206,89 @@ Retrieve_Table_Data(mib_table_t t, int *max_idx) *max_idx = table->next_index - 1; return table->data; } + +#ifdef linux +# define PROC_PATH "/proc" +# define FILE_DISP "fd/" +# define SOCKET_TYPE_1 "socket:[" +# define SOCKET_TYPE_2 "[0000]:" + +unsigned long long +extract_inode(char *format) +{ + unsigned long long ret = 0; + + if (!strncmp(format, SOCKET_TYPE_1, 8)) { + ret = strtoull(format + 8, NULL, 0); + } else if (!strncmp(format, SOCKET_TYPE_2, 7)) { + ret = strtoull(format + 7, NULL, 0); + } + + return ret; +} + +unsigned int +get_pid_from_inode(unsigned long long inode) +{ + DIR *procdirs = NULL, *piddirs = NULL; + char *name = NULL; + char path_name[PATH_MAX + 1]; + char socket_lnk[NAME_MAX + 1]; + int filelen = 0, readlen = 0, iflag = 0; + struct dirent *procinfo, *pidinfo; + unsigned int pid; + unsigned long long temp_inode; + + if (!(procdirs = opendir(PROC_PATH))) { + snmp_log(LOG_ERR, "snmpd: cannot open /proc\n"); + return 0; + } + + while ((procinfo = readdir(procdirs)) != NULL) { + name = procinfo->d_name; + for (; *name; name++) { + if (!isdigit(*name)) + break; + } + if(*name) + continue; + + memset(path_name, '\0', PATH_MAX + 1); + filelen = snprintf(path_name, PATH_MAX, + PROC_PATH "/%s/" FILE_DISP, procinfo->d_name); + if (filelen <= 0 || PATH_MAX < filelen) + continue; + + pid = strtoul(procinfo->d_name, NULL, 0); + + if (!(piddirs = opendir(path_name))) + continue; + + while ((pidinfo = readdir(piddirs)) != NULL) { + if (filelen + strlen(pidinfo->d_name) > PATH_MAX) + continue; + + strcpy(path_name + filelen, pidinfo->d_name); + + memset(socket_lnk, '\0', NAME_MAX + 1); + readlen = readlink(path_name, socket_lnk, NAME_MAX); + if (readlen < 0) + continue; + socket_lnk[readlen] = '\0'; + + temp_inode = extract_inode(socket_lnk); + if (inode == temp_inode) { + iflag = 1; + break; + } + } + closedir(piddirs); + if (iflag == 1) + break; + } + if (procdirs) + closedir(procdirs); + return pid; +} + +#endif /* #ifdef linux */ diff --git a/agent/mibgroup/util_funcs.h b/agent/mibgroup/util_funcs.h index 1b3fefe..4a0b99e 100644 --- a/agent/mibgroup/util_funcs.h +++ b/agent/mibgroup/util_funcs.h @@ -34,6 +34,10 @@ void string_append_int(char *, int); void wait_on_exec(struct extensible *); const char *make_tempfile(void); +#ifdef linux +unsigned int get_pid_from_inode(unsigned long long); +#endif + #define satosin(x) ((struct sockaddr_in *) &(x)) #define SOCKADDR(x) (satosin(x)->sin_addr.s_addr) #ifndef MIB_STATS_CACHE_TIMEOUT diff --git a/include/net-snmp/data_access/udp_endpoint.h b/include/net-snmp/data_access/udp_endpoint.h index cc81b02..b9831ec 100644 --- a/include/net-snmp/data_access/udp_endpoint.h +++ b/include/net-snmp/data_access/udp_endpoint.h @@ -41,6 +41,7 @@ extern "C" { u_short rmt_port; u_int instance; + u_int pid; } netsnmp_udp_endpoint_entry; -- 1.6.0.2