/* * swap the order of an inet addr string */ int netsnmp_addrstr_hton(char *ptr, size_t len) { #ifndef WORDS_BIGENDIAN char tmp[8]; if (8 == len) { tmp[0] = ptr[6]; tmp[1] = ptr[7]; tmp[2] = ptr[4]; tmp[3] = ptr[5]; tmp[4] = ptr[2]; tmp[5] = ptr[3]; tmp[6] = ptr[0]; tmp[7] = ptr[1]; memcpy (ptr, &tmp, 8); } else if (32 == len) { netsnmp_addrstr_hton(ptr , 8); netsnmp_addrstr_hton(ptr+8 , 8); netsnmp_addrstr_hton(ptr+16, 8); netsnmp_addrstr_hton(ptr+24, 8); } else return -1; #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", (int)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", (int)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", (int)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", (int)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; /* * get the pid also */ ep->pid = netsnmp_get_pid_from_inode(inode); ep->index = (uintptr_t)(lpi->user_context); lpi->user_context = (void*)((char*)(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 _load6(netsnmp_container *container, u_int load_flags) { int rc = 0; FILE *in; char line[180]; static int log_open_err = 1; netsnmp_assert(NULL != container); #undef PROCFILE #define PROCFILE "/proc/net/tcp6" if (!(in = fopen(PROCFILE, "r"))) { snmp_log(LOG_ERR,"could not open " PROCFILE "\n"); if (1 == log_open_err) { snmp_log(LOG_ERR,"could not open " PROCFILE "\n"); log_open_err = 0; } return -2; } /* * if we turned off logging of open errors, turn it back on now that * we have been able to open the file. */ if (0 == log_open_err) log_open_err = 1; fgets(line, sizeof(line), in); /* skip header */ /* * Note: PPC (big endian) * * sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode * 0: 00000000000000000000000000000001:1466 00000000000000000000000000000000:0000 0A 00000000:00000000 00:00000000 00000000 500 0 326699 1 efb81580 3000 0 0 2 -1 */ 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; char local_addr[48], remote_addr[48]; u_char *tmp_ptr; 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, &inode))) { DEBUGMSGT(("access:tcpconn:container", "error parsing line (%d != 6)\n", rc)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); continue; } DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line)); /* * check if we care about listen state */ state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2; if (load_flags) { if (TCPCONNECTIONSTATE_LISTEN == state) { if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) { DEBUGMSGT(("verbose:access:tcpconn:container", " skipping listen\n")); continue; } } else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) { DEBUGMSGT(("verbose:access:tcpconn:container", " skipping non-listen\n")); continue; } } /* */ entry = netsnmp_access_tcpconn_entry_create(); if(NULL == entry) { rc = -3; break; } /** oddly enough, these appear to already be in network order */ entry->loc_port = (unsigned short) local_port; entry->rmt_port = (unsigned short) remote_port; entry->tcpConnState = state; entry->pid = netsnmp_get_pid_from_inode(inode); /** the addr string may need work */ buf_len = strlen(local_addr); if ((32 != buf_len) || (-1 == netsnmp_addrstr_hton(local_addr, 32))) { DEBUGMSGT(("verbose:access:tcpconn:container", " error processing local address\n")); netsnmp_access_tcpconn_entry_free(entry); continue; } offset = 0; tmp_ptr = entry->loc_addr; rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len, &offset, 0, local_addr, NULL); entry->loc_addr_len = offset; if (( 16 != entry->loc_addr_len ) && ( 20 != entry->loc_addr_len )) { DEBUGMSGT(("access:tcpconn:container", "error parsing local addr (%d != 16|20)\n", entry->loc_addr_len)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); netsnmp_access_tcpconn_entry_free(entry); continue; } buf_len = strlen((char*)remote_addr); if ((32 != buf_len) || (-1 == netsnmp_addrstr_hton(remote_addr, 32))) { DEBUGMSGT(("verbose:access:tcpconn:container", " error processing remote address\n")); netsnmp_access_tcpconn_entry_free(entry); continue; } offset = 0; tmp_ptr = entry->rmt_addr; rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len, &offset, 0, remote_addr, NULL); entry->rmt_addr_len = offset; if (( 16 != entry->rmt_addr_len ) && ( 20 != entry->rmt_addr_len )) { DEBUGMSGT(("access:tcpconn:container", "error parsing remote addr (%d != 16|20)\n", entry->rmt_addr_len)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); netsnmp_access_tcpconn_entry_free(entry); continue; } /* * add entry to container */ entry->arbitrary_index = CONTAINER_SIZE(container) + 1; CONTAINER_INSERT(container, entry); } fclose(in); if(rc<0) return rc; return 0; }
/** * * @retval 0 no errors * @retval !0 errors */ static int _load4(netsnmp_container *container, u_int load_flags) { int rc = 0; FILE *in; char line[160]; netsnmp_assert(NULL != container); #define PROCFILE "/proc/net/tcp" if (!(in = fopen(PROCFILE, "r"))) { snmp_log(LOG_ERR,"could not open " PROCFILE "\n"); return -2; } fgets(line, sizeof(line), in); /* skip header */ /* * sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode * 0: 00000000:8000 00000000:0000 0A 00000000:00000000 00:00000000 00000000 29 0 1028 1 df7b1b80 300 0 0 2 -1 */ while (fgets(line, sizeof(line), in)) { netsnmp_tcpconn_entry *entry; unsigned int state, local_port, remote_port, tmp_state; unsigned long long inode; size_t buf_len, offset; char local_addr[10], remote_addr[10]; u_char *tmp_ptr; 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, &inode))) { DEBUGMSGT(("access:tcpconn:container", "error parsing line (%d != 6)\n", rc)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); snmp_log(LOG_ERR, "tcp:_load4: bad line in " PROCFILE ": %s\n", line); rc = 0; continue; } DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line)); /* * check if we care about listen state */ state = (tmp_state & 0xf) < 12 ? linux_states[tmp_state & 0xf] : 2; if (load_flags) { if (TCPCONNECTIONSTATE_LISTEN == state) { if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) { DEBUGMSGT(("verbose:access:tcpconn:container", " skipping listen\n")); continue; } } else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) { DEBUGMSGT(("verbose:access:tcpconn:container", " skipping non-listen\n")); continue; } } /* */ entry = netsnmp_access_tcpconn_entry_create(); if(NULL == entry) { rc = -3; break; } /** oddly enough, these appear to already be in network order */ entry->loc_port = (unsigned short) local_port; entry->rmt_port = (unsigned short) remote_port; entry->tcpConnState = state; entry->pid = netsnmp_get_pid_from_inode(inode); /** the addr string may need work */ buf_len = strlen(local_addr); if ((8 != buf_len) || (-1 == netsnmp_addrstr_hton(local_addr, 8))) { DEBUGMSGT(("verbose:access:tcpconn:container", " error processing local address\n")); netsnmp_access_tcpconn_entry_free(entry); continue; } offset = 0; tmp_ptr = entry->loc_addr; rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len, &offset, 0, local_addr, NULL); entry->loc_addr_len = offset; if ( 4 != entry->loc_addr_len ) { DEBUGMSGT(("access:tcpconn:container", "error parsing local addr (%d != 4)\n", entry->loc_addr_len)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); netsnmp_access_tcpconn_entry_free(entry); continue; } /** the addr string may need work */ buf_len = strlen((char*)remote_addr); if ((8 != buf_len) || (-1 == netsnmp_addrstr_hton(remote_addr, 8))) { DEBUGMSGT(("verbose:access:tcpconn:container", " error processing remote address\n")); netsnmp_access_tcpconn_entry_free(entry); continue; } offset = 0; tmp_ptr = entry->rmt_addr; rc = netsnmp_hex_to_binary(&tmp_ptr, &buf_len, &offset, 0, remote_addr, NULL); entry->rmt_addr_len = offset; if ( 4 != entry->rmt_addr_len ) { DEBUGMSGT(("access:tcpconn:container", "error parsing remote addr (%d != 4)\n", entry->rmt_addr_len)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); netsnmp_access_tcpconn_entry_free(entry); continue; } /* * add entry to container */ entry->arbitrary_index = CONTAINER_SIZE(container) + 1; CONTAINER_INSERT(container, entry); } fclose(in); if(rc<0) return rc; return 0; }