/* * tcpConnTable MIB architecture support for NetBSD */ #include #include #include #include #include "tcp-mib/tcpConnectionTable/tcpConnectionTable_constants.h" #include "tcp-mib/data_access/tcpConn_private.h" #include "mibII/mibII_common.h" #if HAVE_NETINET_TCP_H #include #endif #if HAVE_NETINET_TCP_TIMER_H #include #endif #if HAVE_NETINET_TCPIP_H #include #endif #if HAVE_NETINET_TCP_VAR_H #include #endif static int _load(netsnmp_container *container, u_int flags, int var); /* * initialize arch specific storage * * @retval 0: success * @retval <0: error */ int netsnmp_arch_tcpconn_entry_init(netsnmp_tcpconn_entry *entry) { /* * init */ return 0; } /* * cleanup arch specific storage */ void netsnmp_arch_tcpconn_entry_cleanup(netsnmp_tcpconn_entry *entry) { /* * cleanup */ } /* * copy arch specific storage */ int netsnmp_arch_tcpconn_entry_copy(netsnmp_tcpconn_entry *lhs, netsnmp_tcpconn_entry *rhs) { return 0; } /* * delete an entry */ int netsnmp_arch_tcpconn_entry_delete(netsnmp_tcpconn_entry *entry) { if (NULL == entry) return -1; /** xxx-rks:9 tcpConn delete not implemented */ return -1; } /** * * @retval 0 no errors * @retval !0 errors */ int netsnmp_arch_tcpconn_container_load(netsnmp_container *container, u_int load_flags ) { int rc = 0; DEBUGMSGTL(("access:tcpconn:container", "tcpconn_container_arch_load (flags %x)\n", load_flags)); if (NULL == container) { snmp_log(LOG_ERR, "no container specified/found for access_tcpconn\n"); return -1; } rc = _load(container, load_flags, 4); #if defined(NETSNMP_ENABLE_IPV6) rc = _load(container, load_flags, 6); #endif return rc; } /** * * @retval 0 no errors * @retval !0 errors */ static int _load(netsnmp_container *container, u_int load_flags, int ver) { const char *mibname; int mib[8]; size_t mib_len; struct kinfo_pcb *pcblist; size_t pcb_len; int StateMap[] = { 1, 2, 3, 4, 5, 8, 6, 10, 9, 7, 11 }; netsnmp_tcpconn_entry *entry; int state; int i, rc = 0; /* * Read in the buffer containing the TCP table data */ switch (ver) { case 4: mibname = "net.inet.tcp.pcblist"; break; case 6: mibname = "net.inet6.tcp6.pcblist"; break; default: snmp_log(LOG_ERR, "tcp-mib:data_access:_load: bad version %d\n", ver); return -1; } if (sysctlnametomib(mibname, mib, &mib_len) == -1) { snmp_log(LOG_ERR, "tcp-mib:data_access:_load: cant resolve mib %s\n", mibname); return -1; } if (sysctl(mib, sizeof(mib) / sizeof(*mib), NULL, &pcb_len, NULL, 0) == -1) { snmp_log(LOG_ERR, "tcp-mib:data_access:_load: cant size mib %s\n", mibname); return -1; } if ((pcblist = malloc(pcb_len)) == NULL) { snmp_log(LOG_ERR, "tcp-mib:data_access:_load: cant allocate mib %s\n", mibname); return -1; } memset(pcblist, 0, pcb_len); mib[6] = sizeof(*pcblist); mib[7] = pcb_len / sizeof(*pcblist); if (sysctl(mib, sizeof(mib) / sizeof(*mib), pcblist, &pcb_len, NULL, 0) == -1) { snmp_log(LOG_ERR, "tcp-mib:data_access:_load: cant size mib %s\n", mibname); return -1; } /* * Unpick this into the constituent structures, and extract * the 'inpcb' elements into a linked list (built in reverse) */ for (i = 0; i < pcb_len / sizeof(*pcblist); i++) { struct kinfo_pcb *pcb = pcblist+i; state = StateMap[pcb->ki_tstate]; if (load_flags) { if (state == TCPCONNECTIONSTATE_LISTEN) { 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->tcpConnState = state; entry->pid = 0; if (ver == 6) { struct sockaddr_in6 src, dst; memcpy(&src, &pcb->ki_s, sizeof(src)); memcpy(&dst, &pcb->ki_d, sizeof(dst)); entry->loc_addr_len = entry->rmt_addr_len = 16; memcpy(entry->loc_addr, &src.sin6_addr, 16); memcpy(entry->rmt_addr, &dst.sin6_addr, 16); entry->loc_port = ntohs(src.sin6_port); entry->rmt_port = ntohs(dst.sin6_port); } else { struct sockaddr_in src, dst; memcpy(&src, &pcb->ki_s, sizeof(src)); memcpy(&dst, &pcb->ki_d, sizeof(dst)); entry->loc_addr_len = entry->rmt_addr_len = 4; memcpy(entry->loc_addr, &src.sin_addr, 4); memcpy(entry->rmt_addr, &dst.sin_addr, 4); entry->loc_port = ntohs(src.sin_port); entry->rmt_port = ntohs(dst.sin_port); } /* * add entry to container */ entry->arbitrary_index = CONTAINER_SIZE(container) + 1; CONTAINER_INSERT(container, entry); } if(rc<0) return rc; return 0; }