#include #include #include #include "sctpAssocTable.h" #include "sctpAssocLocalAddrTable.h" #include "sctpAssocRemAddrTable.h" #include "sctpTables_common.h" #include #include #include #include #include #include #include #include #include #include #include #include static int parse_assoc_local_addresses(sctpTables_containers * containers, struct xsctp_laddr *xladdr) { int ret; sctpAssocLocalAddrTable_entry *entry; entry = sctpAssocLocalAddrTable_entry_create(); if (entry == NULL) return SNMP_ERR_GENERR; entry->sctpAssocId = 0; if (xladdr->address.sa.sa_family == AF_INET) { entry->sctpAssocLocalAddrType = INETADDRESSTYPE_IPV4; entry->sctpAssocLocalAddr_len = 4; memcpy(entry->sctpAssocLocalAddr, &xladdr->address.sin.sin_addr, entry->sctpAssocLocalAddr_len); } else if (xladdr->address.sa.sa_family == AF_INET6) { entry->sctpAssocLocalAddrType = INETADDRESSTYPE_IPV6; entry->sctpAssocLocalAddr_len = 16; memcpy(entry->sctpAssocLocalAddr, &xladdr->address.sin6.sin6_addr, entry->sctpAssocLocalAddr_len); } entry->sctpAssocLocalAddrStartTime = xladdr->start_time.tv_sec; ret = sctpAssocLocalAddrTable_add_or_update(containers->sctpAssocLocalAddrTable, entry); if (ret != SNMP_ERR_NOERROR) return SNMP_ERR_GENERR; return SNMP_ERR_NOERROR; } static int parse_assoc_xstcb(sctpTables_containers * containers, struct xsctp_tcb *xstcb) { int ret; sctpAssocTable_entry *entry; entry = sctpAssocTable_entry_create(); if (entry == NULL) return SNMP_ERR_GENERR; switch (xstcb->state) { case SCTP_STATE_INUSE: entry->sctpAssocState = SCTPASSOCSTATE_DELETETCB; break; case SCTP_STATE_COOKIE_WAIT: entry->sctpAssocState = SCTPASSOCSTATE_COOKIEWAIT; break; case SCTP_STATE_COOKIE_ECHOED: entry->sctpAssocState = SCTPASSOCSTATE_COOKIEECHOED; break; case SCTP_STATE_OPEN: entry->sctpAssocState = SCTPASSOCSTATE_ESTABLISHED; break; case SCTP_STATE_SHUTDOWN_SENT: entry->sctpAssocState = SCTPASSOCSTATE_SHUTDOWNSENT; break; case SCTP_STATE_SHUTDOWN_RECEIVED: entry->sctpAssocState = SCTPASSOCSTATE_SHUTDOWNRECEIVED; break; case SCTP_STATE_SHUTDOWN_ACK_SENT: entry->sctpAssocState = SCTPASSOCSTATE_SHUTDOWNACKSENT; break; default: case SCTP_STATE_EMPTY: entry->sctpAssocState = SCTPASSOCSTATE_CLOSED; break; }; entry->sctpAssocHeartBeatInterval = xstcb->heartbeat_interval; entry->sctpAssocId = 0; entry->sctpAssocPrimProcess = xstcb->primary_process; entry->sctpAssocLocalPort = xstcb->local_port; entry->sctpAssocRemPort = xstcb->remote_port; entry->sctpAssocHeartBeatInterval = xstcb->heartbeat_interval; entry->sctpAssocInStreams = xstcb->in_streams; entry->sctpAssocOutStreams = xstcb->out_streams; entry->sctpAssocMaxRetr = xstcb->max_nr_retrans; entry->sctpAssocT1expireds = xstcb->T1_expireries; entry->sctpAssocRtxChunks = xstcb->retransmitted_tsns; entry->sctpAssocT2expireds = xstcb->T2_expireries; entry->sctpAssocRemHostName[0] = 0; entry->sctpAssocRemHostName_len = 0; entry->sctpAssocDiscontinuityTime = xstcb->discontinuity_time.tv_sec; entry->sctpAssocStartTime = xstcb->start_time.tv_sec; ret = sctpAssocTable_add_or_update(containers->sctpAssocTable, entry); if (ret != SNMP_ERR_NOERROR) { return ret; } return SNMP_ERR_NOERROR; } static int parse_remaddr_xraddr(sctpTables_containers * containers, struct xsctp_raddr *xraddr) { int ret; sctpAssocRemAddrTable_entry *entry; entry = sctpAssocRemAddrTable_entry_create(); if (entry == NULL) return SNMP_ERR_GENERR; entry->sctpAssocId = 0; if(xraddr->active) entry->sctpAssocRemAddrActive = TRUTHVALUE_TRUE; else entry->sctpAssocRemAddrActive = TRUTHVALUE_FALSE; if (xraddr->heartbeat_enabled) entry->sctpAssocRemAddrHBActive = TRUTHVALUE_TRUE; else entry->sctpAssocRemAddrHBActive = TRUTHVALUE_FALSE; entry->sctpAssocRemAddrRTO = xraddr->rto; entry->sctpAssocRemAddrMaxPathRtx = xraddr->max_path_rtx; entry->sctpAssocRemAddrRtx = xraddr->rtx; entry->sctpAssocRemAddrStartTime = xraddr->start_time.tv_sec; if (xraddr->address.sa.sa_family == AF_INET) { entry->sctpAssocRemAddrType = INETADDRESSTYPE_IPV4; entry->sctpAssocRemAddr_len = 4; memcpy(entry->sctpAssocRemAddr, &xraddr->address.sin.sin_addr, entry->sctpAssocRemAddr_len); } else if (xraddr->address.sa.sa_family == AF_INET6) { entry->sctpAssocRemAddrType = INETADDRESSTYPE_IPV6; entry->sctpAssocRemAddr_len = 16; memcpy(entry->sctpAssocRemAddr, &xraddr->address.sin6.sin6_addr, entry->sctpAssocRemAddr_len); } ret = sctpAssocRemAddrTable_add_or_update(containers-> sctpAssocRemAddrTable, entry); if (ret != SNMP_ERR_NOERROR) { return ret; } return SNMP_ERR_NOERROR; } int sctpTables_arch_load(sctpTables_containers * containers, u_long * flags) { int ret = SNMP_ERR_NOERROR; size_t len; caddr_t buf; unsigned int offset; struct xsctp_inpcb *xinp; struct xsctp_tcb *xstcb; struct xsctp_laddr *xladdr; struct xsctp_raddr *xraddr; *flags |= SCTP_TABLES_LOAD_FLAG_DELETE_INVALID; *flags |= SCTP_TABLES_LOAD_FLAG_AUTO_LOOKUP; len = 0; if (sysctlbyname("net.inet.sctp.assoclist", 0, &len, 0, 0) < 0) { printf("Error %d (%s) could not get the assoclist\n", errno, strerror(errno)); return(-1); } if ((buf = (caddr_t)malloc(len)) == 0) { printf("malloc %lu bytes failed.\n", (long unsigned)len); return(-1); } if (sysctlbyname("net.inet.sctp.assoclist", buf, &len, 0, 0) < 0) { printf("Error %d (%s) could not get the assoclist\n", errno, strerror(errno)); free(buf); return(-1); } offset = 0; xinp = (struct xsctp_inpcb *)(buf + offset); while (xinp->last == 0) { /* for each INP */ offset += sizeof(struct xsctp_inpcb); /* Local addresses */ xladdr = (struct xsctp_laddr *)(buf + offset); while (xladdr->last == 0) { offset += sizeof(struct xsctp_laddr); xladdr = (struct xsctp_laddr *)(buf + offset); } offset += sizeof(struct xsctp_laddr); /* Associations */ xstcb = (struct xsctp_tcb *)(buf + offset); while (xstcb->last == 0) { xstcb = (struct xsctp_tcb *)(buf + offset); offset += sizeof(struct xsctp_tcb); parse_assoc_xstcb(containers, xstcb); /* Local addresses */ xladdr = (struct xsctp_laddr *)(buf + offset); while (xladdr->last == 0) { parse_assoc_local_addresses(containers, xladdr); offset += sizeof(struct xsctp_laddr); xladdr = (struct xsctp_laddr *)(buf + offset); } offset += sizeof(struct xsctp_laddr); /* Remote addresses */ xraddr = (struct xsctp_raddr *)(buf + offset); while (xraddr->last == 0) { parse_remaddr_xraddr(containers, xraddr); offset += sizeof(struct xsctp_raddr); xraddr = (struct xsctp_raddr *)(buf + offset); } offset += sizeof(struct xsctp_raddr); xstcb = (struct xsctp_tcb *)(buf + offset); } offset += sizeof(struct xsctp_tcb); xinp = (struct xsctp_inpcb *)(buf + offset); } free((void *)buf); return ret; }