--- agent/mibgroup/sctp-mib/sctpTables_freebsd.c.orig	2009-03-07 23:31:54.000000000 +0900
+++ agent/mibgroup/sctp-mib/sctpTables_freebsd.c	2009-03-07 23:55:04.000000000 +0900
@@ -0,0 +1,249 @@
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "sctpAssocTable.h"
+#include "sctpAssocLocalAddrTable.h"
+#include "sctpAssocRemAddrTable.h"
+#include "sctpTables_common.h"
+
+#include <util_funcs.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/sctp.h>
+#include <netinet/sctp_constants.h>
+
+
+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)
+{
+  long            inode;
+  char           *token;
+  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)
+{
+  char           *token;
+  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;
+  sa_family_t family;
+  void *addr;
+
+
+  *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;
+}
