static int _load_tcpconn_table_v4(netsnmp_container *container, int flag) { mib2_tcpConnEntry_t tc; netsnmp_tcpconn_entry *ep; req_e req = GET_FIRST; DEBUGMSGT(("access:tcpconn:container", "load v4\n")); while (getMibstat(MIB_TCP_CONN, &tc, sizeof(tc), req, &Get_everything, 0)==0) { req = GET_NEXT; if ((flag & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN && tc.tcpConnState != MIB2_TCP_listen) || (flag & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN && tc.tcpConnState == MIB2_TCP_listen)) { continue; } ep = netsnmp_access_tcpconn_entry_create(); if (ep == NULL) return (-1); DEBUGMSGT(("access:tcpconn:container", "add entry\n")); /* * local address/port. */ ep->loc_addr_len = sizeof(tc.tcpConnLocalAddress); if (sizeof(ep->loc_addr) < ep->loc_addr_len) { netsnmp_access_tcpconn_entry_free(ep); return (-1); } (void)memcpy(&ep->loc_addr, &tc.tcpConnLocalAddress, ep->loc_addr_len); ep->loc_port = tc.tcpConnLocalPort; /* * remote address/port. The address length is the same as the * local address, so no check needed. */ ep->rmt_addr_len = sizeof(tc.tcpConnRemAddress); (void)memcpy(&ep->rmt_addr, &tc.tcpConnRemAddress, ep->rmt_addr_len); ep->rmt_port = tc.tcpConnRemPort; /* state/pid */ ep->tcpConnState = tc.tcpConnState; ep->pid = 0; ep->arch_data = NULL; /* index */ ep->arbitrary_index = CONTAINER_SIZE(container) + 1; CONTAINER_INSERT(container, (void *)ep); } return (0); }
/** * * @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 */ int netsnmp_arch_tcpconn_container_load(netsnmp_container *container) { int rc = 0; FILE *in; char line[160]; u_char *buf; netsnmp_tcpconn_entry *entry; 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; static int linux_states[12] = { 1, 5, 3, 4, 6, 7, 11, 1, 8, 9, 2, 10 }; int state, rc, local_port, remote_port; /* */ entry = netsnmp_access_tcpconn_entry_create(); if(NULL == entry) { rc = -3; break; } if (5 != (rc = sscanf(line, "%*d: %x:%x %x:%x %x", &entry->indexes[NETSNMP_TCPCONN_IDX_LOCAL_ADDR], &local_port, &entry->indexes[NETSNMP_TCPCONN_IDX_REMOTE_ADDR], &remote_port, &state))) { DEBUGMSGT(("access:tcpconn:container", "error parsing line (%d != 5)\n", rc)); DEBUGMSGT(("access:tcpconn:container"," line '%s'\n", line)); netsnmp_access_tcpconn_entry_free(entry); continue; } DEBUGMSGT(("verbose:access:tcpconn:container"," line '%s'\n", line)); entry->indexes[NETSNMP_TCPCONN_IDX_LOCAL_PORT] = htons((unsigned short) local_port); entry->indexes[NETSNMP_TCPCONN_IDX_REMOTE_PORT] = htons((unsigned short) remote_port); entry->tcpConnState = (state & 0xf) < 12 ? linux_states[state & 0xf] : 2; /* * add entry to container */ CONTAINER_INSERT(container, entry); } fclose(in); if(rc<0) return rc; return 0; }
/** * * @retval 0 no errors * @retval !0 errors */ static int _load(netsnmp_container *container, u_int load_flags) { struct inpcbtable table; struct inpcb *head, *next, *prev; struct inpcb inpcb; struct tcpcb tcpcb; int StateMap[] = { 1, 2, 3, 4, 5, 8, 6, 10, 9, 7, 11 }; netsnmp_tcpconn_entry *entry; int state; int rc = 0; /* * Read in the buffer containing the TCP table data */ if (!auto_nlist(TCP_SYMBOL, (char *)&table, sizeof(table))) { DEBUGMSGTL(("tcp-mib/tcpConn_openbsd", "Failed to read tcp_symbol\n")); return -1; } prev = (struct inpcb *)&CIRCLEQ_FIRST(&table.inpt_queue); prev = NULL; head = next = CIRCLEQ_FIRST(&table.inpt_queue); while (next) { if (!NETSNMP_KLOOKUP(next, (char *)&inpcb, sizeof(inpcb))) { DEBUGMSGTL(("tcp-mib/data_access/tcpConn", "klookup inpcb failed\n")); break; } if (prev && CIRCLEQ_PREV(&inpcb, inp_queue) != prev) { snmp_log(LOG_ERR,"tcbtable link error\n"); break; } prev = next; next = CIRCLEQ_NEXT(&inpcb, inp_queue); if (!NETSNMP_KLOOKUP(inpcb.inp_ppcb, (char *)&tcpcb, sizeof(tcpcb))) { DEBUGMSGTL(("tcp-mib/data_access/tcpConn", "klookup tcpcb failed\n")); break; } state = StateMap[tcpcb.t_state]; if (load_flags) { if (state == TCPCONNECTIONSTATE_LISTEN) { if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_NOLISTEN) { DEBUGMSGT(("verbose:access:tcpconn:container", " skipping listen\n")); goto skip; } } else if (load_flags & NETSNMP_ACCESS_TCPCONN_LOAD_ONLYLISTEN) { DEBUGMSGT(("verbose:access:tcpconn:container", " skipping non-listen\n")); goto skip; } } #if !defined(NETSNMP_ENABLE_IPV6) if (inpcb.inp_flags & INP_IPV6) goto skip; #endif 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 = ntohs(inpcb.inp_lport); entry->rmt_port = ntohs(inpcb.inp_fport); entry->tcpConnState = state; entry->pid = 0; /** the addr string may need work */ if (inpcb.inp_flags & INP_IPV6) { entry->loc_addr_len = entry->rmt_addr_len = 16; memcpy(entry->loc_addr, &inpcb.inp_laddr6, 16); memcpy(entry->rmt_addr, &inpcb.inp_faddr6, 16); } else { entry->loc_addr_len = entry->rmt_addr_len = 4; memcpy(entry->loc_addr, &inpcb.inp_laddr, 4); memcpy(entry->rmt_addr, &inpcb.inp_faddr, 4); } DEBUGMSGTL(("tcp-mib/data_access", "tcp %d %d %d\n", entry->loc_addr_len, entry->loc_port, entry->rmt_port)); /* * add entry to container */ entry->arbitrary_index = CONTAINER_SIZE(container) + 1; CONTAINER_INSERT(container, entry); skip: if (head == next) break; } if(rc<0) return rc; return 0; }
/** * * @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]; 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"); 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: 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, buf_len, offset, tmp_state; 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", local_addr, &local_port, remote_addr, &remote_port, &tmp_state))) { DEBUGMSGT(("access:tcpconn:container", "error parsing line (%d != 5)\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; } entry->loc_port = htons((unsigned short) local_port); entry->rmt_port = htons((unsigned short) remote_port); entry->tcpConnState = state; buf_len = strlen(local_addr); 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(remote_addr); 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; }