Merge from Chromium at DEPS revision 262940

This commit was generated by merge_to_master.py.

Change-Id: I1ee1405458f60b20f9d8bb679bc13679abe7e5fe
diff --git a/netinet/sctp.h b/netinet/sctp.h
index 50bb8ea..012acec 100755
--- a/netinet/sctp.h
+++ b/netinet/sctp.h
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 254248 2013-08-12 13:52:15Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #ifndef _NETINET_SCTP_H_
@@ -53,13 +53,13 @@
 #endif
 
 /*
- * SCTP protocol - RFC2960.
+ * SCTP protocol - RFC4960.
  */
 struct sctphdr {
 	uint16_t src_port;	/* source port */
 	uint16_t dest_port;	/* destination port */
 	uint32_t v_tag;		/* verification tag of packet */
-	uint32_t checksum;	/* Adler32 C-Sum */
+	uint32_t checksum;	/* CRC32C checksum */
 	/* chunks follow... */
 } SCTP_PACKED;
 
@@ -379,6 +379,12 @@
 /*
  * error cause parameters (user visible)
  */
+struct sctp_gen_error_cause {
+	uint16_t code;
+	uint16_t length;
+	uint8_t info[];
+} SCTP_PACKED;
+
 struct sctp_error_cause {
 	uint16_t code;
 	uint16_t length;
diff --git a/netinet/sctp_bsd_addr.c b/netinet/sctp_bsd_addr.c
index 71e781b..fe20ea9 100755
--- a/netinet/sctp_bsd_addr.c
+++ b/netinet/sctp_bsd_addr.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 258221 2013-11-16 15:04:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_bsd_addr.c 258765 2013-11-30 12:51:19Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -178,6 +178,9 @@
 		/* You only get one */
 		return;
 	}
+	/* Initialize global locks here, thus only once. */
+	SCTP_ITERATOR_LOCK_INIT();
+	SCTP_IPI_ITERATOR_WQ_INIT();
 	TAILQ_INIT(&sctp_it_ctl.iteratorhead);
 #if defined(__FreeBSD__)
 #if __FreeBSD_version <= 701000
@@ -822,12 +825,12 @@
 		return (NULL);
 	}
 	if (allonebuf == 0)
-                mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
+		mbuf_threshold = SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count);
 	else
 		mbuf_threshold = 1;
 
 
-	if (space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
+	if ((int)space_needed > (((mbuf_threshold - 1) * MLEN) + MHLEN)) {
 		MCLGET(m, how);
 		if (m == NULL) {
 			return (NULL);
diff --git a/netinet/sctp_constants.h b/netinet/sctp_constants.h
index 2c60521..12e0c13 100755
--- a/netinet/sctp_constants.h
+++ b/netinet/sctp_constants.h
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 256556 2013-10-15 20:21:27Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_constants.h 263921 2014-03-29 20:21:36Z tuexen $");
 #endif
 
 #ifndef _NETINET_SCTP_CONSTANTS_H_
@@ -41,20 +41,10 @@
 #if defined(__Userspace_os_Windows)
 extern void getwintimeofday(struct timeval *tv);
 #endif
+
 /* IANA assigned port number for SCTP over UDP encapsulation */
-#ifdef __FreeBSD__
-/* For freebsd we cannot bind the port at
- * startup. Otherwise what will happen is
- * we really won't be bound. The user must
- * put it into the sysctl... or we need
- * to build a special timer for this to allow
- * us to wait 1 second or so after the system
- * comes up.
- */
-#define SCTP_OVER_UDP_TUNNELING_PORT 0
-#else
 #define SCTP_OVER_UDP_TUNNELING_PORT 9899
-#endif
+
 /* Number of packets to get before sack sent by default */
 #define SCTP_DEFAULT_SACK_FREQ 2
 
@@ -819,6 +809,9 @@
  */
 #define SCTP_DEFAULT_SPLIT_POINT_MIN 2904
 
+/* Maximum length of diagnostic information in error causes */
+#define SCTP_DIAG_INFO_LEN 64
+
 /* ABORT CODES and other tell-tale location
  * codes are generated by adding the below
  * to the instance id.
diff --git a/netinet/sctp_crc32.c b/netinet/sctp_crc32.c
index 0a39d7a..b994aaa 100755
--- a/netinet/sctp_crc32.c
+++ b/netinet/sctp_crc32.c
@@ -785,6 +785,7 @@
 #endif				/* !defined(SCTP_WITH_NO_CSUM) */
 
 
+#if defined(__FreeBSD__)
 void
 sctp_delayed_cksum(struct mbuf *m, uint32_t offset)
 {
@@ -813,4 +814,5 @@
 	*(uint32_t *) (m->m_data + offset) = checksum;
 #endif
 }
+#endif
 
diff --git a/netinet/sctp_crc32.h b/netinet/sctp_crc32.h
index 24eb541..2cc14f4 100755
--- a/netinet/sctp_crc32.h
+++ b/netinet/sctp_crc32.h
@@ -42,7 +42,9 @@
 #if !defined(SCTP_WITH_NO_CSUM)
 uint32_t sctp_calculate_cksum(struct mbuf *, uint32_t);
 #endif
+#if defined(__FreeBSD__)
 void sctp_delayed_cksum(struct mbuf *, uint32_t offset);
+#endif
 #endif				/* _KERNEL */
 #if defined(__Userspace__)
 #if !defined(SCTP_WITH_NO_CSUM)
diff --git a/netinet/sctp_indata.c b/netinet/sctp_indata.c
index bbcc8aa..2801704 100755
--- a/netinet/sctp_indata.c
+++ b/netinet/sctp_indata.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 258228 2013-11-16 16:09:09Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_indata.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -579,7 +579,8 @@
 	struct sctp_queued_to_read *at;
 	int queue_needed;
 	uint16_t nxt_todel;
-	struct mbuf *oper;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 
 	queue_needed = 1;
 	asoc->size_on_all_streams += control->length;
@@ -596,7 +597,7 @@
 		(uint32_t) nxt_todel);
 	if (SCTP_SSN_GE(strm->last_sequence_delivered, control->sinfo_ssn)) {
 		/* The incoming sseq is behind where we last delivered? */
-		SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d from peer, Abort  association\n",
+		SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ:%d delivered:%d from peer, Abort association\n",
 			control->sinfo_ssn, strm->last_sequence_delivered);
 	protocol_error:
 		/*
@@ -604,25 +605,12 @@
 		 * association destruction
 		 */
 		TAILQ_INSERT_HEAD(&strm->inqueue, control, next);
-		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					     0, M_NOWAIT, 1, MT_DATA);
-		if (oper) {
-			struct sctp_paramhdr *ph;
-			uint32_t *ippp;
-			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-			    (sizeof(uint32_t) * 3);
-			ph = mtod(oper, struct sctp_paramhdr *);
-			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-			ph->param_length = htons(SCTP_BUF_LEN(oper));
-			ippp = (uint32_t *) (ph + 1);
-			*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_1);
-			ippp++;
-			*ippp = control->sinfo_tsn;
-			ippp++;
-			*ippp = ((control->sinfo_stream << 16) | control->sinfo_ssn);
-		}
+		snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+		         strm->last_sequence_delivered, control->sinfo_tsn,
+			 control->sinfo_stream, control->sinfo_ssn);
+		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_1;
-		sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		*abort_flag = 1;
 		return;
 
@@ -854,7 +842,9 @@
 sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
     struct sctp_tmit_chunk *chk, int *abort_flag)
 {
-	struct mbuf *oper;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
+	
 	uint32_t cum_ackp1, prev_tsn, post_tsn;
 	struct sctp_tmit_chunk *at, *prev, *next;
 
@@ -879,30 +869,14 @@
 				 * a FIRST fragment mark.
 				 */
 				SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, its not first, no fragmented delivery in progress\n");
-				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-							       0, M_NOWAIT, 1, MT_DATA);
-
-				if (oper) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(oper) =
-					    sizeof(struct sctp_paramhdr) +
-					    (sizeof(uint32_t) * 3);
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_2);
-					ippp++;
-					*ippp = chk->rec.data.TSN_seq;
-					ippp++;
-					*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-				}
+				snprintf(msg, sizeof(msg),
+				         "Expected B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+				         chk->rec.data.TSN_seq,
+			 	         chk->rec.data.stream_number,
+				         chk->rec.data.stream_seq);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_2;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
 			} else if (asoc->fragmented_delivery_inprogress &&
 			    (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) == SCTP_DATA_FIRST_FRAG) {
@@ -912,28 +886,14 @@
 				 * MIDDLE fragment NOT a FIRST
 				 */
 				SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS a first and fragmented delivery in progress\n");
-				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-							     0, M_NOWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(oper) =
-					    sizeof(struct sctp_paramhdr) +
-					    (3 *sizeof(uint32_t));
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_3);
-					ippp++;
-					*ippp = chk->rec.data.TSN_seq;
-					ippp++;
-					*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-				}
+				snprintf(msg, sizeof(msg),
+				         "Didn't expect B-bit for TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+				         chk->rec.data.TSN_seq,
+			 	         chk->rec.data.stream_number,
+				         chk->rec.data.stream_seq);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_3;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
 			} else if (asoc->fragmented_delivery_inprogress) {
 				/*
@@ -946,30 +906,15 @@
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream number %d vs %d\n",
 						chk->rec.data.stream_number,
 						asoc->str_of_pdapi);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (sizeof(uint32_t) * 3);
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_4);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					         "Expected SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         asoc->str_of_pdapi,
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_4;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 				} else if ((asoc->fragment_flags & SCTP_DATA_UNORDERED) !=
 					    SCTP_DATA_UNORDERED &&
@@ -978,31 +923,15 @@
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it IS not same stream seq %d vs %d\n",
 						chk->rec.data.stream_seq,
 						asoc->ssn_of_pdapi);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_5);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					         "Expected SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         asoc->ssn_of_pdapi,
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_5;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 				}
 			}
@@ -1072,31 +1001,14 @@
 				    SCTP_DATA_FIRST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - It can be a midlle or last but not a first\n");
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, it's a FIRST!\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_6);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					         "Can't handle B-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_6;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1106,33 +1018,18 @@
 					 * Huh, need the correct STR here,
 					 * they must be the same.
 					 */
-					SCTP_PRINTF("Prev check - Gak, Evil plot, ssn:%d not the same as at:%d\n",
+					SCTP_PRINTF("Prev check - Gak, Evil plot, sid:%d not the same as at:%d\n",
 						    chk->rec.data.stream_number,
 						    prev->rec.data.stream_number);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_7);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					         "Expect SID=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         prev->rec.data.stream_number,
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_7;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1146,30 +1043,15 @@
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, Evil plot, sseq:%d not the same as at:%d\n",
 						chk->rec.data.stream_seq,
 						prev->rec.data.stream_seq);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_8);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					         "Expect SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         prev->rec.data.stream_seq,
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_8;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1179,31 +1061,14 @@
 				if ((chk->rec.data.rcv_flags & SCTP_DATA_FRAG_MASK) !=
 				    SCTP_DATA_FIRST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Prev check - Gak, evil plot, its not FIRST and it must be!\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_9);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					         "Expect B-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_9;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1223,30 +1088,14 @@
 				    != SCTP_DATA_LAST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Next is FIRST, we must be LAST\n");
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, its not a last!\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    ( 3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_10);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					         "Expect only E-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_10;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1262,31 +1111,14 @@
 				    SCTP_DATA_LAST_FRAG) {
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Next is a MIDDLE/LAST\n");
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Gak, Evil plot, new prev chunk is a LAST\n");
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_11);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					         "Didn't expect E-bit, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_11;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1299,31 +1131,15 @@
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Gak, Evil plot, ssn:%d not the same as at:%d\n",
 						chk->rec.data.stream_number,
 						next->rec.data.stream_number);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_12);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-
-					}
+					snprintf(msg, sizeof(msg),
+					         "Required SID %4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         next->rec.data.stream_number,
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_12;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1337,30 +1153,15 @@
 					SCTPDBG(SCTP_DEBUG_INDATA1, "Next chk - Gak, Evil plot, sseq:%d not the same as at:%d\n",
 						chk->rec.data.stream_seq,
 						next->rec.data.stream_seq);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_13);
-						ippp++;
-						*ippp = chk->rec.data.TSN_seq;
-						ippp++;
-						*ippp = ((chk->rec.data.stream_number << 16) | chk->rec.data.stream_seq);
-					}
+					snprintf(msg, sizeof(msg),
+					         "Required SSN %4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         next->rec.data.stream_seq,
+					         chk->rec.data.TSN_seq,
+					         chk->rec.data.stream_number,
+					         chk->rec.data.stream_seq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_13;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return;
 				}
@@ -1445,7 +1246,8 @@
 	int the_len;
 	int need_reasm_check = 0;
 	uint16_t strmno, strmseq;
-	struct mbuf *oper;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	struct sctp_queued_to_read *control;
 	int ordered;
 	uint32_t protocol_id;
@@ -1512,15 +1314,12 @@
 	 */
 	if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) ||
 	     (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
-	     (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET))
-		) {
+	     (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET))) {
 		/*
 		 * wait a minute, this guy is gone, there is no longer a
 		 * receiver. Send peer an ABORT!
 		 */
-		struct mbuf *op_err;
-
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		*abort_flag = 1;
 		return (0);
@@ -1648,27 +1447,13 @@
 		/* The incoming sseq is behind where we last delivered? */
 		SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ:%d delivered:%d from peer, Abort!\n",
 			strmseq, asoc->strmin[strmno].last_sequence_delivered);
-		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					     0, M_NOWAIT, 1, MT_DATA);
-		if (oper) {
-			struct sctp_paramhdr *ph;
-			uint32_t *ippp;
 
-			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-			    (3 * sizeof(uint32_t));
-			ph = mtod(oper, struct sctp_paramhdr *);
-			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-			ph->param_length = htons(SCTP_BUF_LEN(oper));
-			ippp = (uint32_t *) (ph + 1);
-			*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_14);
-			ippp++;
-			*ippp = tsn;
-			ippp++;
-			*ippp = ((strmno << 16) | strmseq);
-
-		}
+		snprintf(msg, sizeof(msg), "Delivered SSN=%4.4x, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+		         asoc->strmin[strmno].last_sequence_delivered,
+		         tsn, strmno, strmseq);
+		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 		stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_14;
-		sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+		sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		*abort_flag = 1;
 		return (0);
 	}
@@ -1903,28 +1688,11 @@
 					control->whoFrom = NULL;
 				}
 				sctp_free_a_readq(stcb, control);
-				oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-							     0, M_NOWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(oper) =
-					    sizeof(struct sctp_paramhdr) +
-					    (3 * sizeof(uint32_t));
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type =
-					    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_15);
-					ippp++;
-					*ippp = tsn;
-					ippp++;
-					*ippp = ((strmno << 16) | strmseq);
-				}
+				snprintf(msg, sizeof(msg), "Reas. queue emtpy, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+				         tsn, strmno, strmseq);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_15;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				*abort_flag = 1;
 				return (0);
 			} else {
@@ -1936,31 +1704,11 @@
 						control->whoFrom = NULL;
 					}
 					sctp_free_a_readq(stcb, control);
-
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    ( 3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_16);
-						ippp++;
-						*ippp = tsn;
-						ippp++;
-						*ippp = ((strmno << 16) | strmseq);
-					}
+					snprintf(msg, sizeof(msg), "PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         tsn, strmno, strmseq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_16;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return (0);
 				}
@@ -1982,30 +1730,11 @@
 						control->whoFrom = NULL;
 					}
 					sctp_free_a_readq(stcb, control);
-					oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-								     0, M_NOWAIT, 1, MT_DATA);
-					if (oper) {
-						struct sctp_paramhdr *ph;
-						uint32_t *ippp;
-
-						SCTP_BUF_LEN(oper) =
-						    sizeof(struct sctp_paramhdr) +
-						    (3 * sizeof(uint32_t));
-						ph = mtod(oper,
-						    struct sctp_paramhdr *);
-						ph->param_type =
-						    htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-						ph->param_length =
-						    htons(SCTP_BUF_LEN(oper));
-						ippp = (uint32_t *) (ph + 1);
-						*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_17);
-						ippp++;
-						*ippp = tsn;
-						ippp++;
-						*ippp = ((strmno << 16) | strmseq);
-					}
+					snprintf(msg, sizeof(msg), "No PD ongoing, got TSN=%8.8x, SID=%4.4x, SSN=%4.4x",
+					         tsn, strmno, strmseq);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_17;
-					sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+					sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 					*abort_flag = 1;
 					return (0);
 				}
@@ -2616,26 +2345,11 @@
 				 * invalid data chunk.
 				 */
 				struct mbuf *op_err;
+				char msg[SCTP_DIAG_INFO_LEN];
 
-				op_err = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 2 * sizeof(uint32_t)),
-							       0, M_NOWAIT, 1, MT_DATA);
-
-				if (op_err) {
-					struct sctp_paramhdr *ph;
-					uint32_t *ippp;
-
-					SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr) +
-						(2 * sizeof(uint32_t));
-					ph = mtod(op_err, struct sctp_paramhdr *);
-					ph->param_type =
-						htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-					ph->param_length = htons(SCTP_BUF_LEN(op_err));
-					ippp = (uint32_t *) (ph + 1);
-					*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_19);
-					ippp++;
-					*ippp = asoc->cumulative_tsn;
-
-				}
+				snprintf(msg, sizeof(msg), "DATA chunk of length %d",
+				         chk_length);
+				op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_19;
 				sctp_abort_association(inp, stcb, m, iphlen,
 				                       src, dst, sh, op_err,
@@ -2705,7 +2419,7 @@
 				if (SCTP_BASE_SYSCTL(sctp_strict_data_order)) {
 					struct mbuf *op_err;
 
-					op_err = sctp_generate_invmanparam(SCTP_CAUSE_PROTOCOL_VIOLATION);
+					op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, "");
 					sctp_abort_association(inp, stcb,
 					                       m, iphlen,
 					                       src, dst,
@@ -3690,6 +3404,7 @@
 	struct sctp_tmit_chunk *chk;
 	int inflight = 0, resend = 0, inbetween = 0, acked = 0, above = 0;
 	int entry_flight, entry_cnt, ret;
+
 	entry_flight = asoc->total_flight;
 	entry_cnt = asoc->total_flight_count;
 	ret = 0;
@@ -3842,7 +3557,8 @@
 		}
 		if (SCTP_TSN_GE(cumack, send_s)) {
 #ifndef INVARIANTS
-			struct mbuf *oper;
+			struct mbuf *op_err;
+			char msg[SCTP_DIAG_INFO_LEN];
 
 #endif
 #ifdef INVARIANTS
@@ -3851,22 +3567,11 @@
 
 			*abort_now = 1;
 			/* XXX */
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-						     0, M_NOWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-					sizeof(uint32_t);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
-			}
+			snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x",
+			         cumack, send_s);
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
-			sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			return;
 #endif
 		}
@@ -4233,23 +3938,14 @@
 		    (asoc->stream_queue_cnt == 0)) {
 			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
 				/* Need to abort here */
-				struct mbuf *oper;
+				struct mbuf *op_err;
 
 			abort_out_now:
 				*abort_now = 1;
 				/* XXX */
-				oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-							     0, M_NOWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			} else {
 				struct sctp_nets *netp;
 
@@ -4442,7 +4138,9 @@
 			send_s = asoc->sending_seq;
 		}
 		if (SCTP_TSN_GE(cum_ack, send_s)) {
-			struct mbuf *oper;
+			struct mbuf *op_err;
+			char msg[SCTP_DIAG_INFO_LEN];
+
 			/*
 			 * no way, we have not even sent this TSN out yet.
 			 * Peer is hopelessly messed up with us.
@@ -4456,22 +4154,11 @@
 		hopeless_peer:
 			*abort_now = 1;
 			/* XXX */
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-			                             0, M_NOWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-					sizeof(uint32_t);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_INDATA + SCTP_LOC_25);
-			}
+			snprintf(msg, sizeof(msg), "Cum ack %8.8x greater or equal then TSN %8.8x",
+			         cum_ack, send_s);
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25;
-			sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			return;
 		}
 	}
@@ -4987,22 +4674,14 @@
 		    (asoc->stream_queue_cnt == 0)) {
 			if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
 				/* Need to abort here */
-				struct mbuf *oper;
+				struct mbuf *op_err;
+
 			abort_out_now:
 				*abort_now = 1;
 				/* XXX */
-				oper = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-				                             0, M_NOWAIT, 1, MT_DATA);
-				if (oper) {
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr);
-					ph = mtod(oper, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(oper));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_31;
-				sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+				sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 				return;
 			} else {
 				struct sctp_nets *netp;
@@ -5427,31 +5106,20 @@
 	asoc->cumulative_tsn = new_cum_tsn;
 	if (gap >= m_size) {
 		if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) {
-			struct mbuf *oper;
+			struct mbuf *op_err;
+			char msg[SCTP_DIAG_INFO_LEN];
+
 			/*
 			 * out of range (of single byte chunks in the rwnd I
 			 * give out). This must be an attacker.
 			 */
 			*abort_flag = 1;
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + 3 * sizeof(uint32_t)),
-					     0, M_NOWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-					(sizeof(uint32_t) * 3);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_INDATA+SCTP_LOC_33);
-				ippp++;
-				*ippp = asoc->highest_tsn_inside_map;
-				ippp++;
-				*ippp = new_cum_tsn;
-			}
+			snprintf(msg, sizeof(msg),
+			         "New cum ack %8.8x too high, highest TSN %8.8x",
+			         new_cum_tsn, asoc->highest_tsn_inside_map);
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 			stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA+SCTP_LOC_33;
-			sctp_abort_an_association(stcb->sctp_ep, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 			return;
 		}
 		SCTP_STAT_INCR(sctps_fwdtsn_map_over);
diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c
index f8f177a..889f9bb 100755
--- a/netinet/sctp_input.c
+++ b/netinet/sctp_input.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 254854 2013-08-25 12:44:03Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -108,7 +108,7 @@
 	}
 	/* validate length */
 	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
@@ -122,7 +122,7 @@
 	init = &cp->init;
 	if (init->initiate_tag == 0) {
 		/* protocol error... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
@@ -134,7 +134,7 @@
 	}
 	if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
 		/* invalid parameter... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
@@ -146,7 +146,7 @@
 	}
 	if (init->num_inbound_streams == 0) {
 		/* protocol error... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
@@ -158,7 +158,7 @@
 	}
 	if (init->num_outbound_streams == 0) {
 		/* protocol error... send abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
@@ -171,7 +171,9 @@
 	if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
 					   offset + ntohs(cp->ch.chunk_length))) {
 		/* auth parameter(s) error... send abort */
-		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, NULL,
+		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+		                             "Problem with AUTH parameters");
+		sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
 #endif
@@ -199,7 +201,9 @@
 		 * this state :-)
 		 */
 		if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
-			sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			                             "No listener");
+			sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
 #if defined(__FreeBSD__)
 			                use_mflowid, mflowid,
 #endif
@@ -464,7 +468,6 @@
 
 	/* First verify that we have no illegal param's */
 	abort_flag = 0;
-	op_err = NULL;
 
 	op_err = sctp_arethere_unrecognized_parameters(m,
 						       (offset + sizeof(struct sctp_init_chunk)),
@@ -487,12 +490,13 @@
 	if ((retval = sctp_load_addresses_from_init(stcb, m,
 	    (offset + sizeof(struct sctp_init_chunk)), initack_limit,
 	    src, dst, NULL))) {
-		/* Huh, we should abort */
+		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+		                             "Problem with address parameters");
 		SCTPDBG(SCTP_DEBUG_INPUT1,
 			"Load addresses from INIT causes an abort %d\n",
 			retval);
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
-		                       src, dst, sh, NULL,
+		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 		                       use_mflowid, mflowid,
 #endif
@@ -550,8 +554,7 @@
 		 */
 		if (retval == -3) {
 			/* We abort with an error of missing mandatory param */
-			op_err =
-			    sctp_generate_invmanparam(SCTP_CAUSE_MISSING_PARAM);
+			op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, "");
 			if (op_err) {
 				/*
 				 * Expand beyond to include the mandatory
@@ -1346,7 +1349,7 @@
 	}
 	if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
 		/* Invalid length */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1360,7 +1363,7 @@
 	/* validate parameters */
 	if (init_ack->initiate_tag == 0) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1372,7 +1375,7 @@
 	}
 	if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1384,7 +1387,7 @@
 	}
 	if (init_ack->num_inbound_streams == 0) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1396,7 +1399,7 @@
 	}
 	if (init_ack->num_outbound_streams == 0) {
 		/* protocol error... send an abort */
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+		op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
 		sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
 		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1514,7 +1517,6 @@
 	struct sctp_init_ack_chunk *initack_cp, initack_buf;
 	struct sctp_nets *net;
 	struct mbuf *op_err;
-	struct sctp_paramhdr *ph;
 	int init_offset, initack_offset, i;
 	int retval;
 	int spec_flag = 0;
@@ -1533,17 +1535,7 @@
 	if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
 		/* SHUTDOWN came in after sending INIT-ACK */
 		sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
-		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-					       0, M_NOWAIT, 1, MT_DATA);
-		if (op_err == NULL) {
-			/* FOOBAR */
-			return (NULL);
-		}
-		/* Set the len */
-		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-		ph = mtod(op_err, struct sctp_paramhdr *);
-		ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
+		op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
 		sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
 #if defined(__FreeBSD__)
 		                   use_mflowid, mflowid,
@@ -1611,7 +1603,7 @@
 			return (NULL);
 
 		}
- 		switch SCTP_GET_STATE(asoc) {
+ 		switch (SCTP_GET_STATE(asoc)) {
 			case SCTP_STATE_COOKIE_WAIT:
 			case SCTP_STATE_COOKIE_ECHOED:
 				/*
@@ -1750,25 +1742,7 @@
 		 * from hsot-2 (or 1). Now we have colliding state. We must
 		 * send an abort here with colliding state indication.
 		 */
-		op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-		                               0, M_NOWAIT, 1, MT_DATA);
-		if (op_err == NULL) {
-			/* FOOBAR */
-			return (NULL);
-		}
-		/* pre-reserve some space */
-#ifdef INET6
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
-		SCTP_BUF_RESV_UF(op_err,  sizeof(struct sctp_chunkhdr));
-		/* Set the len */
-		SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-		ph = mtod(op_err, struct sctp_paramhdr *);
-		ph->param_type = htons(SCTP_CAUSE_NAT_COLLIDING_STATE);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
+		op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
 		sctp_send_abort(m, iphlen,  src, dst, sh, 0, op_err,
 #if defined(__FreeBSD__)
 		                use_mflowid, mflowid,
@@ -2186,8 +2160,7 @@
 		/* memory problem? */
 		SCTPDBG(SCTP_DEBUG_INPUT1,
 			"process_cookie_new: no room for another TCB!\n");
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
-
+		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
 		                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -2223,7 +2196,7 @@
 		 * association.
 		 */
 		atomic_add_int(&stcb->asoc.refcnt, 1);
-		op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+		op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 		sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
 				       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -2912,7 +2885,7 @@
 #endif
 				/* Too many sockets */
 				SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
-				op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 				sctp_abort_association(*inp_p, NULL, m, iphlen,
 						       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -4533,6 +4506,8 @@
     uint32_t vrf_id, uint16_t port)
 {
 	struct sctp_association *asoc;
+	struct mbuf *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	uint32_t vtag_in;
 	int num_chunks = 0;	/* number of control chunks processed */
 	uint32_t chk_length;
@@ -4683,8 +4658,11 @@
 			}
 		}
 		if (stcb == NULL) {
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			                             msg);
 			/* no association, so it's out of the blue... */
-			sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp,
+			sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
 			                 use_mflowid, mflowid,
 #endif
@@ -4726,8 +4704,11 @@
 				if (locked_tcb) {
 					SCTP_TCB_UNLOCK(locked_tcb);
 				}
+				snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+				                             msg);
 				sctp_handle_ootb(m, iphlen, *offset, src, dst,
-				                 sh, inp,
+				                 sh, inp, op_err,
 #if defined(__FreeBSD__)
 				                 use_mflowid, mflowid,
 #endif
@@ -4872,8 +4853,10 @@
 			/* The INIT chunk must be the only chunk. */
 			if ((num_chunks > 1) ||
 			    (length - *offset > (int)SCTP_SIZE32(chk_length))) {
+				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+				                             "INIT not the only chunk");
 				sctp_abort_association(inp, stcb, m, iphlen,
-				                       src, dst, sh, NULL,
+				                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
 				                       use_mflowid, mflowid,
 #endif
@@ -4883,9 +4866,7 @@
 			}
 			/* Honor our resource limit. */
 			if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
-				struct mbuf *op_err;
-
-				op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+				op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 				sctp_abort_association(inp, stcb, m, iphlen,
 						       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -5252,9 +5233,7 @@
 			if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
 				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
 				    (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
-					struct mbuf *op_err;
-
-					op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+					op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
 					sctp_abort_association(inp, stcb, m, iphlen,
 					                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -5749,7 +5728,8 @@
 {
 	uint32_t high_tsn;
 	int fwd_tsn_seen = 0, data_processed = 0;
-	struct mbuf *m = *mm;
+	struct mbuf *m = *mm, *op_err;
+	char msg[SCTP_DIAG_INFO_LEN];
 	int un_sent;
 	int cnt_ctrl_ready = 0;
 	struct sctp_inpcb *inp = NULL, *inp_decr = NULL;
@@ -5843,8 +5823,10 @@
 			if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
 			    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
 			     (ch->chunk_type != SCTP_INIT))) {
+				op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+				                             "Out of the blue");
 				sctp_send_abort(m, iphlen, src, dst,
-				                sh, 0, NULL,
+				                sh, 0, op_err,
 #if defined(__FreeBSD__)
 				                use_mflowid, mflowid,
 #endif
@@ -5912,7 +5894,10 @@
 			 */
  			SCTP_TCB_UNLOCK(stcb);
 			stcb = NULL;
-			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			                             msg);
+			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
 			                 use_mflowid, mflowid,
 #endif
@@ -5963,7 +5948,10 @@
 		}
 		if (stcb == NULL) {
 			/* out of the blue DATA chunk */
-			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			                             msg);
+			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
 			                 use_mflowid, mflowid,
 #endif
@@ -6035,7 +6023,10 @@
 			/*
 			 * We consider OOTB any data sent during asoc setup.
 			 */
-			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+			snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			                             msg);
+			sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
 			                 use_mflowid, mflowid,
 #endif
diff --git a/netinet/sctp_os_userspace.h b/netinet/sctp_os_userspace.h
index dc4e280..bf501d0 100755
--- a/netinet/sctp_os_userspace.h
+++ b/netinet/sctp_os_userspace.h
@@ -77,25 +77,32 @@
 #define ADDRESS_FAMILY	unsigned __int8
 #define IPVERSION  4
 #define MAXTTL     255
+/* VS2010 comes with stdint.h */
+#if _MSC_VER >= 1600
+#include <stdint.h>
+#else
 #define uint64_t   unsigned __int64
+#define uint32_t   unsigned __int32
+#define int32_t    __int32
+#define uint16_t   unsigned __int16
+#define int16_t    __int16
+#define uint8_t    unsigned __int8
+#define int8_t     __int8
+#endif
+#ifndef _SIZE_T_DEFINED
+#define size_t     __int32
+#endif
 #define u_long     unsigned __int64
 #define u_int      unsigned __int32
-#define uint32_t   unsigned __int32
 #define u_int32_t  unsigned __int32
-#define int32_t	   __int32
-#define int16_t	   __int16
-#define uint16_t   unsigned __int16
 #define u_int16_t  unsigned __int16
-#define uint8_t    unsigned __int8
 #define u_int8_t   unsigned __int8
-#define int8_t     __int8
 #define u_char     unsigned char
 #define n_short    unsigned __int16
 #define u_short    unsigned __int16
-#define ssize_t    __int64
-#define size_t     __int32
 #define n_time     unsigned __int32
 #define sa_family_t unsigned __int8
+#define ssize_t    __int64
 #define IFNAMSIZ   64
 #define __func__	__FUNCTION__
 
@@ -395,7 +402,7 @@
 #else /* !defined(Userspace_os_Windows) */
 #include <sys/cdefs.h> /* needed? added from old __FreeBSD__ */
 #include <sys/socket.h>
-#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Linux)
+#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD)
 #include <pthread.h>
 #endif
 typedef pthread_mutex_t userland_mutex_t;
@@ -409,7 +416,9 @@
 #define MA_OWNED 7 /* sys/mutex.h typically on FreeBSD */
 #if !defined(__Userspace_os_FreeBSD)
 struct mtx {int dummy;};
+#if !defined(__Userspace_os_NetBSD)
 struct selinfo {int dummy;};
+#endif
 struct sx {int dummy;};
 #endif
 
@@ -512,7 +521,7 @@
 #include <netinet/ip6.h>
 #include <netinet/icmp6.h>
 #endif
-#if defined(__Userspace_os_Linux) || defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) ||defined(__Userspace_os_Windows)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Linux) || defined(__Userspace_os_NetBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Windows)
 #include "user_ip6_var.h"
 #else
 #include <netinet6/ip6_var.h>
@@ -1082,9 +1091,11 @@
 /* with the current included files, this is defined in Linux but
  *  in FreeBSD, it is behind a _KERNEL in sys/socket.h ...
  */
-#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
+#if defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD)
 /* stolen from /usr/include/sys/socket.h */
 #define CMSG_ALIGN(n)   _ALIGN(n)
+#elif defined(__Userspace_os_NetBSD)
+#define CMSG_ALIGN(n)   (((n) + __ALIGNBYTES) & ~__ALIGNBYTES)
 #elif defined(__Userspace_os_Darwin)
 #if !defined(__DARWIN_ALIGNBYTES)
 #define	__DARWIN_ALIGNBYTES	(sizeof(__darwin_size_t) - 1)
@@ -1134,4 +1145,8 @@
               (var) = (tvar))
 #endif
 #endif
+#if defined(__Userspace_os_DragonFly)
+#define TAILQ_FOREACH_SAFE TAILQ_FOREACH_MUTABLE
+#define LIST_FOREACH_SAFE LIST_FOREACH_MUTABLE
+#endif
 #endif
diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c
index dac5a29..46ca9d7 100755
--- a/netinet/sctp_output.c
+++ b/netinet/sctp_output.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 258235 2013-11-16 19:57:56Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -3742,7 +3742,6 @@
 	int sig_offset;
 	uint16_t cookie_sz;
 
-	mret = NULL;
 	mret = sctp_get_mbuf_for_msg((sizeof(struct sctp_state_cookie) +
 				      sizeof(struct sctp_paramhdr)), 0,
 				     M_NOWAIT, 1, MT_DATA);
@@ -4243,7 +4242,7 @@
 #else
 #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
 			m->m_pkthdr.csum_flags = CSUM_SCTP;
-			m->m_pkthdr.csum_data = 0;
+			m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 			SCTP_STAT_INCR(sctps_sendhwcrc);
 #else
 			if (!(SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) &&
@@ -4349,7 +4348,11 @@
 			 * This means especially, that it is not set at the
 			 * SCTP layer. So use the value from the IP layer.
 			 */
+#if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
+			flowlabel = ntohl(inp->ip_inp.inp.inp_flow);
+#else
 			flowlabel = ntohl(((struct in6pcb *)inp)->in6p_flowinfo);
+#endif
 		}
 		flowlabel &= 0x000fffff;
 		len = sizeof(struct ip6_hdr) + sizeof(struct sctphdr);
@@ -4429,8 +4432,12 @@
 			 * SCTP layer. So use the value from the IP layer.
 			 */
 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Panda__) || defined(__Windows__) || defined(__Userspace__)
+#if defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
+			tos_value = (ntohl(inp->ip_inp.inp.inp_flow) >> 20) & 0xff;
+#else
 			tos_value = (ntohl(((struct in6pcb *)inp)->in6p_flowinfo) >> 20) & 0xff;
 #endif
+#endif
 		}
 		tos_value &= 0xfc;
 		if (ecn_ok) {
@@ -4690,7 +4697,7 @@
 #else
 			m->m_pkthdr.csum_flags = CSUM_SCTP;
 #endif
-			m->m_pkthdr.csum_data = 0;
+			m->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 			SCTP_STAT_INCR(sctps_sendhwcrc);
 #endif
 #else
@@ -5457,16 +5464,16 @@
 #endif
 		l_len += (2 * sizeof(struct sctp_paramhdr));
 		op_err = sctp_get_mbuf_for_msg(l_len, 0, M_NOWAIT, 1, MT_DATA);
-        if (op_err) {
-    		SCTP_BUF_LEN(op_err) = 0;
+		if (op_err) {
+			SCTP_BUF_LEN(op_err) = 0;
 #ifdef INET6
-	    	SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
+			SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
 #else
-	    	SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
+			SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
 #endif
-		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
-    		SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
-        }
+			SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
+			SCTP_BUF_RESV_UF(op_err, sizeof(struct sctp_chunkhdr));
+		}
 	}
 	if ((op_err) && phdr) {
 		struct sctp_paramhdr s;
@@ -5714,7 +5721,9 @@
 		 * though we even set the T bit and copy in the 0 tag.. this
 		 * looks no different than if no listener was present.
 		 */
-		sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, NULL,
+		op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+		                             "Address added");
+		sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, op_err,
 #if defined(__FreeBSD__)
 		                use_mflowid, mflowid,
 #endif
@@ -5727,6 +5736,13 @@
 						       &abort_flag, (struct sctp_chunkhdr *)init_chk, &nat_friendly);
 	if (abort_flag) {
 	do_a_abort:
+		if (op_err == NULL) {
+			char msg[SCTP_DIAG_INFO_LEN];
+
+			snprintf(msg, sizeof(msg), "%s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+			op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+			                             msg);
+		}
 		sctp_send_abort(init_pkt, iphlen, src, dst, sh,
 				init_chk->init.initiate_tag, op_err,
 #if defined(__FreeBSD__)
@@ -9356,7 +9372,6 @@
 	struct sctp_chunkhdr *hdr;
 	struct sctp_tmit_chunk *chk;
 
-	cookie_ack = NULL;
 	SCTP_TCB_LOCK_ASSERT(stcb);
 
 	cookie_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_chunkhdr), 0, M_NOWAIT, 1, MT_HEADER);
@@ -11526,7 +11541,7 @@
 #else
 #if defined(__FreeBSD__) && __FreeBSD_version >= 800000
 			mout->m_pkthdr.csum_flags = CSUM_SCTP;
-			mout->m_pkthdr.csum_data = 0;
+			mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 			SCTP_STAT_INCR(sctps_sendhwcrc);
 #else
 			shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip));
@@ -11578,7 +11593,7 @@
 #else
 			mout->m_pkthdr.csum_flags = CSUM_SCTP;
 #endif
-			mout->m_pkthdr.csum_data = 0;
+			mout->m_pkthdr.csum_data = offsetof(struct sctphdr, checksum);
 			SCTP_STAT_INCR(sctps_sendhwcrc);
 #else
 			shout->checksum = sctp_calculate_cksum(mout, sizeof(struct ip6_hdr));
diff --git a/netinet/sctp_pcb.c b/netinet/sctp_pcb.c
index bd5e3bb..393069d 100755
--- a/netinet/sctp_pcb.c
+++ b/netinet/sctp_pcb.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 258224 2013-11-16 15:34:14Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_pcb.c 263922 2014-03-29 21:26:45Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -865,7 +865,13 @@
 		}
 		SCTPDBG(SCTP_DEBUG_PCB4, "Deleting ifa %p\n", (void *)sctp_ifap);
 		sctp_ifap->localifa_flags &= SCTP_ADDR_VALID;
-		sctp_ifap->localifa_flags |= SCTP_BEING_DELETED;
+                /*
+		 * We don't set the flag. This means that the structure will
+		 * hang around in EP's that have bound specific to it until
+		 * they close. This gives us TCP like behavior if someone
+		 * removes an address (or for that matter adds it right back).
+		 */
+		/* sctp_ifap->localifa_flags |= SCTP_BEING_DELETED; */
 		vrf->total_ifa_count--;
 		LIST_REMOVE(sctp_ifap, next_bucket);
 		sctp_remove_ifa_from_ifn(sctp_ifap);
@@ -2877,7 +2883,7 @@
 
 #if defined(__APPLE__)
 #if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD)
-	inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(mtx_grp), SCTP_BASE_INFO(mtx_attr));
+	inp->ip_inp.inp.inpcb_mtx = lck_mtx_alloc_init(SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
 	if (inp->ip_inp.inp.inpcb_mtx == NULL) {
 		SCTP_PRINTF("in_pcballoc: can't alloc mutex! so=%p\n", (void *)so);
 #ifdef SCTP_MVRF
@@ -2886,12 +2892,14 @@
 		SCTP_HASH_FREE(inp->sctp_tcbhash, inp->sctp_hashmark);
 		so->so_pcb = NULL;
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
-		SCTP_UNLOCK_EXC(SCTP_BASE_INFO(ipi_ep_mtx));
+		SCTP_UNLOCK_EXC(SCTP_BASE_INFO(sctbinfo).ipi_lock);
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOMEM);
 		return (ENOMEM);
 	}
+#elif defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
+	lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).mtx_grp, SCTP_BASE_INFO(sctbinfo).mtx_attr);
 #else
-	lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(mtx_grp), SCTP_BASE_INFO(mtx_attr));
+	lck_mtx_init(&inp->ip_inp.inp.inpcb_mtx, SCTP_BASE_INFO(sctbinfo).ipi_lock_grp, SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
 #endif
 #endif
 	SCTP_INP_INFO_WLOCK();
@@ -2907,7 +2915,12 @@
 	/* add it to the info area */
 	LIST_INSERT_HEAD(&SCTP_BASE_INFO(listhead), inp, sctp_list);
 #if defined(__APPLE__)
-	LIST_INSERT_HEAD(&SCTP_BASE_INFO(inplisthead), &inp->ip_inp.inp, inp_list);
+	inp->ip_inp.inp.inp_pcbinfo = &SCTP_BASE_INFO(sctbinfo);
+#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
+	LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).listhead, &inp->ip_inp.inp, inp_list);
+#else
+	LIST_INSERT_HEAD(SCTP_BASE_INFO(sctbinfo).ipi_listhead, &inp->ip_inp.inp, inp_list);
+#endif
 #endif
 	SCTP_INP_INFO_WUNLOCK();
 
@@ -3900,17 +3913,7 @@
 				/* Left with Data unread */
 				struct mbuf *op_err;
 
-				op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-							       0, M_NOWAIT, 1, MT_DATA);
-				if (op_err) {
-					/* Fill in the user initiated abort */
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-					ph = mtod(op_err, struct sctp_paramhdr *);
-					ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(op_err));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_3;
 				sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
 				SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -3980,17 +3983,7 @@
 				    (asoc->asoc.state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
 					struct mbuf *op_err;
 				abort_anyway:
-					op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-								       0, M_NOWAIT, 1, MT_DATA);
-					if (op_err) {
-						/* Fill in the user initiated abort */
-						struct sctp_paramhdr *ph;
-
-						SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-						ph = mtod(op_err, struct sctp_paramhdr *);
-						ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-						ph->param_length = htons(SCTP_BUF_LEN(op_err));
-					}
+					op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 					asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_5;
 					sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
 					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -4057,17 +4050,7 @@
 		    ((asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) {
 			struct mbuf *op_err;
 
-			op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-						       0, M_NOWAIT, 1, MT_DATA);
-			if (op_err) {
-				/* Fill in the user initiated abort */
-				struct sctp_paramhdr *ph;
-
-				SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-				ph = mtod(op_err, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-				ph->param_length = htons(SCTP_BUF_LEN(op_err));
-			}
+			op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 			asoc->sctp_ep->last_abort_code = SCTP_FROM_SCTP_PCB+SCTP_LOC_7;
 			sctp_send_abort_tcb(asoc, op_err, SCTP_SO_LOCKED);
 			SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -6540,7 +6523,7 @@
 	}
 }
 #endif
-#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1100000
+#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
 static struct mbuf *
 sctp_netisr_hdlr(struct mbuf *m, uintptr_t source)
 {
@@ -6615,6 +6598,25 @@
 	LIST_INIT(&SCTP_BASE_INFO(listhead));
 #if defined(__APPLE__)
 	LIST_INIT(&SCTP_BASE_INFO(inplisthead));
+#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
+	SCTP_BASE_INFO(sctbinfo).listhead = &SCTP_BASE_INFO(inplisthead);
+	SCTP_BASE_INFO(sctbinfo).mtx_grp_attr = lck_grp_attr_alloc_init();
+	lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
+	SCTP_BASE_INFO(sctbinfo).mtx_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
+	SCTP_BASE_INFO(sctbinfo).mtx_attr = lck_attr_alloc_init();
+	lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).mtx_attr);
+#else
+	SCTP_BASE_INFO(sctbinfo).ipi_listhead = &SCTP_BASE_INFO(inplisthead);
+	SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr = lck_grp_attr_alloc_init();
+	lck_grp_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
+	SCTP_BASE_INFO(sctbinfo).ipi_lock_grp = lck_grp_alloc_init("sctppcb", SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
+	SCTP_BASE_INFO(sctbinfo).ipi_lock_attr = lck_attr_alloc_init();
+	lck_attr_setdefault(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
+#endif
+#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
+	SCTP_BASE_INFO(sctbinfo).ipi_gc = sctp_gc;
+	in_pcbinfo_attach(&SCTP_BASE_INFO(sctbinfo));
+#endif
 #endif
 
 
@@ -6688,17 +6690,6 @@
 
 
 	/* Master Lock INIT for info structure */
-#if defined(__APPLE__)
-	/* allocate the lock group attribute for SCTP PCB mutexes */
-	SCTP_BASE_INFO(mtx_grp_attr) = lck_grp_attr_alloc_init();
-	lck_grp_attr_setdefault(SCTP_BASE_INFO(mtx_grp_attr));
-	/* allocate the lock group for SCTP PCB mutexes */
-	SCTP_BASE_INFO(mtx_grp) = lck_grp_alloc_init("sctppcb",
-						     SCTP_BASE_INFO(mtx_grp_attr));
-	/* allocate the lock attribute for SCTP PCB mutexes */
-	SCTP_BASE_INFO(mtx_attr) = lck_attr_alloc_init();
-	lck_attr_setdefault(SCTP_BASE_INFO(mtx_attr));
-#endif				/* __APPLE__ */
 	SCTP_INP_INFO_LOCK_INIT();
 	SCTP_STATLOG_INIT_LOCK();
 
@@ -6736,8 +6727,6 @@
 	for (i = 0; i < SCTP_STACK_VTAG_HASH_SIZE; i++) {
 		LIST_INIT(&SCTP_BASE_INFO(vtag_timewait)[i]);
 	}
-	SCTP_ITERATOR_LOCK_INIT();
-	SCTP_IPI_ITERATOR_WQ_INIT();
 #if defined(SCTP_PROCESS_LEVEL_LOCKS)
 #if defined(__Userspace_os_Windows)
 	InitializeConditionVariable(&sctp_it_ctl.iterator_wakeup);
@@ -6759,7 +6748,7 @@
 	 */
 	sctp_init_vrf_list(SCTP_DEFAULT_VRF);
 #endif
-#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1100000
+#if defined(__FreeBSD__) && __FreeBSD_cc_version >= 1200000
 	if (ip_register_flow_handler(sctp_netisr_hdlr, IPPROTO_SCTP)) {
 		SCTP_PRINTF("***SCTP- Error can't register netisr handler***\n");
 	}
@@ -6792,33 +6781,9 @@
 	struct sctp_tagblock *twait_block, *prev_twait_block;
 	struct sctp_laddr *wi, *nwi;
 	int i;
-#if defined(__FreeBSD__)
 	struct sctp_iterator *it, *nit;
 	
-	/* In FreeBSD the iterator thread never exits
-	 * but we do clean up.
-	 * The only way FreeBSD reaches here is if we have VRF's
-	 * but we still add the ifdef to make it compile on old versions.
-	 */
-	SCTP_IPI_ITERATOR_WQ_LOCK();
-	TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
-		if (it->vn != curvnet) {
-			continue;
-		}
-		TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
-		if (it->function_atend != NULL) {
-			(*it->function_atend) (it->pointer, it->val);
-		}
-		SCTP_FREE(it,SCTP_M_ITER);
-	}
-	SCTP_IPI_ITERATOR_WQ_UNLOCK();
-	SCTP_ITERATOR_LOCK();
-	if ((sctp_it_ctl.cur_it) &&
-	    (sctp_it_ctl.cur_it->vn == curvnet)) {
-		sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
-	}
-	SCTP_ITERATOR_UNLOCK();
-#else
+#if !defined(__FreeBSD__)
 	/* Notify the iterator to exit. */
 	SCTP_IPI_ITERATOR_WQ_LOCK();
 	sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_MUST_EXIT;
@@ -6826,6 +6791,9 @@
 	SCTP_IPI_ITERATOR_WQ_UNLOCK();
 #endif
 #if defined(__APPLE__)
+#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
+	in_pcbinfo_detach(&SCTP_BASE_INFO(sctbinfo));
+#endif
 	SCTP_IPI_ITERATOR_WQ_LOCK();
 	do {
 		msleep(&sctp_it_ctl.iterator_flags,
@@ -6867,6 +6835,33 @@
 	pthread_cond_destroy(&sctp_it_ctl.iterator_wakeup);
 #endif
 #endif
+	/* In FreeBSD the iterator thread never exits
+	 * but we do clean up.
+	 * The only way FreeBSD reaches here is if we have VRF's
+	 * but we still add the ifdef to make it compile on old versions.
+	 */
+	SCTP_IPI_ITERATOR_WQ_LOCK();
+	TAILQ_FOREACH_SAFE(it, &sctp_it_ctl.iteratorhead, sctp_nxt_itr, nit) {
+#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
+		if (it->vn != curvnet) {
+			continue;
+		}
+#endif
+		TAILQ_REMOVE(&sctp_it_ctl.iteratorhead, it, sctp_nxt_itr);
+		if (it->function_atend != NULL) {
+			(*it->function_atend) (it->pointer, it->val);
+		}
+		SCTP_FREE(it,SCTP_M_ITER);
+	}
+	SCTP_IPI_ITERATOR_WQ_UNLOCK();
+#if defined(__FreeBSD__) && __FreeBSD_version >= 801000
+	SCTP_ITERATOR_LOCK();
+	if ((sctp_it_ctl.cur_it) &&
+	    (sctp_it_ctl.cur_it->vn == curvnet)) {
+		sctp_it_ctl.iterator_flags |= SCTP_ITERATOR_STOP_CUR_IT;
+	}
+	SCTP_ITERATOR_UNLOCK();
+#endif
 #if !defined(__FreeBSD__)
 	SCTP_IPI_ITERATOR_WQ_DESTROY();
  	SCTP_ITERATOR_LOCK_DESTROY();
@@ -6947,9 +6942,15 @@
 	SCTP_WQ_ADDR_DESTROY();
 
 #if defined(__APPLE__)
-	lck_grp_attr_free(SCTP_BASE_INFO(mtx_grp_attr));
-	lck_grp_free(SCTP_BASE_INFO(mtx_grp));
-	lck_attr_free(SCTP_BASE_INFO(mtx_attr));
+#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
+	lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_grp_attr);
+	lck_grp_free(SCTP_BASE_INFO(sctbinfo).mtx_grp);
+	lck_attr_free(SCTP_BASE_INFO(sctbinfo).mtx_attr);
+#else
+	lck_grp_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp_attr);
+	lck_grp_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_grp);
+	lck_attr_free(SCTP_BASE_INFO(sctbinfo).ipi_lock_attr);
+#endif
 #endif
 #if defined(__Userspace__)
 	SCTP_TIMERQ_LOCK_DESTROY();
diff --git a/netinet/sctp_pcb.h b/netinet/sctp_pcb.h
index e1cad80..bcd2864 100755
--- a/netinet/sctp_pcb.h
+++ b/netinet/sctp_pcb.h
@@ -189,6 +189,7 @@
 
 #if defined(__APPLE__)
 	struct inpcbhead inplisthead;
+	struct inpcbinfo sctbinfo;
 #endif
 	/* ep zone info */
 	sctp_zone_t ipi_zone_ep;
@@ -223,20 +224,12 @@
 	userland_mutex_t wq_addr_mtx;
 #elif defined(__APPLE__)
 #ifdef _KERN_LOCKS_H_
-	lck_grp_attr_t *mtx_grp_attr;
-	lck_grp_t *mtx_grp;
-	lck_attr_t *mtx_attr;
-	lck_rw_t *ipi_ep_mtx;
 	lck_mtx_t *ipi_addr_mtx;
 	lck_mtx_t *ipi_count_mtx;
 	lck_mtx_t *ipi_pktlog_mtx;
 	lck_mtx_t *logging_mtx;
 	lck_mtx_t *wq_addr_mtx;
 #else
-	void *mtx_grp_attr;
-	void *mtx_grp;
-	void *mtx_attr;
-	void *ipi_ep_mtx;
 	void *ipi_count_mtx;
 	void *logging_mtx;
 #endif /* _KERN_LOCKS_H_ */
diff --git a/netinet/sctp_structs.h b/netinet/sctp_structs.h
index e25d74c..f333ec8 100755
--- a/netinet/sctp_structs.h
+++ b/netinet/sctp_structs.h
@@ -236,6 +236,9 @@
 #endif
 #endif
 #if defined(__APPLE__)
+#if !defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) && !defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION)
+	struct ifaddr *ro_srcia;
+#endif
 #if !defined(APPLE_LEOPARD)
 	uint32_t ro_flags;
 #endif
diff --git a/netinet/sctp_sysctl.c b/netinet/sctp_sysctl.c
index 6d02ccf..1374dba 100755
--- a/netinet/sctp_sysctl.c
+++ b/netinet/sctp_sysctl.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 254672 2013-08-22 20:29:57Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -128,7 +128,7 @@
 	SCTP_BASE_SYSCTL(sctp_steady_step) = SCTPCTL_RTTVAR_STEADYS_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_use_dccc_ecn) = SCTPCTL_RTTVAR_DCCCECN_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_blackhole) = SCTPCTL_BLACKHOLE_DEFAULT;
-
+	SCTP_BASE_SYSCTL(sctp_diag_info_code) = SCTPCTL_DIAG_INFO_CODE_DEFAULT;
 #if defined(SCTP_LOCAL_TRACE_BUF)
 #if defined(__Windows__)
 	/* On Windows, the resource for global variables is limited. */
@@ -743,7 +743,7 @@
 #endif
 	int error;
 
-#if defined(__FreeBSD__) && __FreeBSD_version >= 800056
+#if defined(__FreeBSD__) && __FreeBSD_version >= 800056 && __FreeBSD_version < 1000100
 #ifdef VIMAGE
 	error = vnet_sysctl_handle_int(oidp, oidp->oid_arg1, oidp->oid_arg2, req);
 #else
@@ -836,6 +836,7 @@
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_diag_info_code), SCTPCTL_DIAG_INFO_CODE_MIN, SCTPCTL_DIAG_INFO_CODE_MAX);
 
 #ifdef SCTP_DEBUG
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX);
@@ -1345,8 +1346,12 @@
 		 SCTPCTL_RTTVAR_DCCCECN_DESC);
 
 SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, blackhole, CTLTYPE_UINT|CTLFLAG_RW,
-			 &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check, "IU",
-			 SCTPCTL_BLACKHOLE_DESC);
+                 &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check, "IU",
+                 SCTPCTL_BLACKHOLE_DESC);
+
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, diag_info_code, CTLTYPE_UINT|CTLFLAG_RW,
+                 &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sysctl_sctp_check, "IU",
+                 SCTPCTL_DIAG_INFO_CODE_DESC);
 
 #ifdef SCTP_DEBUG
 SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, debug, CTLTYPE_UINT|CTLFLAG_RW,
@@ -1676,6 +1681,10 @@
 		       &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check,
 		       SCTPCTL_BLACKHOLE_DESC);
 
+	sysctl_add_oid(&sysctl_oid_top, "diag_info_code", CTLTYPE_INT|CTLFLAG_RW,
+		       &SCTP_BASE_SYSCTL(sctp_diag_info_code), 0, sysctl_sctp_check,
+		       SCTPCTL_DIAG_INFO_CODE_DESC);
+
 #ifdef SCTP_DEBUG
 	sysctl_add_oid(&sysctl_oid_top, "debug", CTLTYPE_INT|CTLFLAG_RW,
 	    &SCTP_BASE_SYSCTL(sctp_debug_on), sizeof(SCTP_BASE_SYSCTL(sctp_debug_on)), NULL,
diff --git a/netinet/sctp_sysctl.h b/netinet/sctp_sysctl.h
index 98eb176..0b6cb16 100755
--- a/netinet/sctp_sysctl.h
+++ b/netinet/sctp_sysctl.h
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 252779 2013-07-05 10:08:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_sysctl.h 263921 2014-03-29 20:21:36Z tuexen $");
 #endif
 
 #ifndef _NETINET_SCTP_SYSCTL_H_
@@ -111,6 +111,7 @@
 	uint32_t sctp_rttvar_eqret;
 	uint32_t sctp_steady_step;
 	uint32_t sctp_use_dccc_ecn;
+	uint32_t sctp_diag_info_code;
 #if defined(SCTP_LOCAL_TRACE_BUF)
 #if defined(__Windows__)
 	struct sctp_log *sctp_log;
@@ -482,7 +483,11 @@
 #define SCTPCTL_UDP_TUNNELING_PORT_DESC		"Set the SCTP/UDP tunneling port"
 #define SCTPCTL_UDP_TUNNELING_PORT_MIN		0
 #define SCTPCTL_UDP_TUNNELING_PORT_MAX		65535
+#if defined(__FreeBSD__)
+#define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT	0
+#else
 #define SCTPCTL_UDP_TUNNELING_PORT_DEFAULT	SCTP_OVER_UDP_TUNNELING_PORT
+#endif
 
 /* Enable sending of the SACK-IMMEDIATELY bit */
 #define SCTPCTL_SACK_IMMEDIATELY_ENABLE_DESC	"Enable sending of the SACK-IMMEDIATELY-bit."
@@ -546,6 +551,11 @@
 #define SCTPCTL_BLACKHOLE_MAX		2
 #define SCTPCTL_BLACKHOLE_DEFAULT	SCTPCTL_BLACKHOLE_MIN
 
+#define SCTPCTL_DIAG_INFO_CODE_DESC	"Diagnostic information error cause code"
+#define SCTPCTL_DIAG_INFO_CODE_MIN	0
+#define SCTPCTL_DIAG_INFO_CODE_MAX	65535
+#define SCTPCTL_DIAG_INFO_CODE_DEFAULT	0
+
 #if defined(SCTP_DEBUG)
 /* debug: Configure debug output */
 #define SCTPCTL_DEBUG_DESC	"Configure debug output"
diff --git a/netinet/sctp_timer.c b/netinet/sctp_timer.c
index 7ae0842..0ad6de0 100755
--- a/netinet/sctp_timer.c
+++ b/netinet/sctp_timer.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 257359 2013-10-29 20:04:50Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_timer.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #define _IP_VHL
@@ -157,24 +157,12 @@
 	 */
 	if (stcb->asoc.overall_error_count > threshold) {
 		/* Abort notification sends a ULP notify */
-		struct mbuf *oper;
+		struct mbuf *op_err;
 
-		oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-					       0, M_NOWAIT, 1, MT_DATA);
-		if (oper) {
-			struct sctp_paramhdr *ph;
-			uint32_t *ippp;
-
-			SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-			    sizeof(uint32_t);
-			ph = mtod(oper, struct sctp_paramhdr *);
-			ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-			ph->param_length = htons(SCTP_BUF_LEN(oper));
-			ippp = (uint32_t *) (ph + 1);
-			*ippp = htonl(SCTP_FROM_SCTP_TIMER+SCTP_LOC_1);
-		}
+		op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
+		                             "Association error couter exceeded");
 		inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_1;
-		sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
+		sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		return (1);
 	}
 	return (0);
@@ -1058,24 +1046,12 @@
 	if (cookie == NULL) {
 		if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
 			/* FOOBAR! */
-			struct mbuf *oper;
+			struct mbuf *op_err;
 
-			oper = sctp_get_mbuf_for_msg((sizeof(struct sctp_paramhdr) + sizeof(uint32_t)),
-						       0, M_NOWAIT, 1, MT_DATA);
-			if (oper) {
-				struct sctp_paramhdr *ph;
-				uint32_t *ippp;
-
-				SCTP_BUF_LEN(oper) = sizeof(struct sctp_paramhdr) +
-				    sizeof(uint32_t);
-				ph = mtod(oper, struct sctp_paramhdr *);
-				ph->param_type = htons(SCTP_CAUSE_PROTOCOL_VIOLATION);
-				ph->param_length = htons(SCTP_BUF_LEN(oper));
-				ippp = (uint32_t *) (ph + 1);
-				*ippp = htonl(SCTP_FROM_SCTP_TIMER+SCTP_LOC_3);
-			}
+			op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION,
+			                             "Cookie timer expired, but no cookie");
 			inp->last_abort_code = SCTP_FROM_SCTP_TIMER+SCTP_LOC_4;
-			sctp_abort_an_association(inp, stcb, oper, SCTP_SO_NOT_LOCKED);
+			sctp_abort_an_association(inp, stcb, op_err, SCTP_SO_NOT_LOCKED);
 		} else {
 #ifdef INVARIANTS
 			panic("Cookie timer expires in wrong state?");
diff --git a/netinet/sctp_timer.h b/netinet/sctp_timer.h
index 673cc41..3662bd2 100755
--- a/netinet/sctp_timer.h
+++ b/netinet/sctp_timer.h
@@ -96,8 +96,11 @@
 void sctp_iterator_timer(struct sctp_iterator *it);
 
 #if defined(__APPLE__)
-void sctp_slowtimo();
-
+#if defined(APPLE_LEOPARD) || defined(APPLE_SNOWLEOPARD) || defined(APPLE_LION) || defined(APPLE_MOUNTAINLION)
+void sctp_slowtimo(void);
+#else
+void sctp_gc(struct inpcbinfo *);
+#endif
 #endif
 
 #endif
diff --git a/netinet/sctp_uio.h b/netinet/sctp_uio.h
index 96551ae..7d84313 100755
--- a/netinet/sctp_uio.h
+++ b/netinet/sctp_uio.h
@@ -690,9 +690,7 @@
 /* AUTH hmac_id */
 #define SCTP_AUTH_HMAC_ID_RSVD		0x0000
 #define SCTP_AUTH_HMAC_ID_SHA1		0x0001	/* default, mandatory */
-#if defined(SCTP_SUPPORT_HMAC_SHA256)
 #define SCTP_AUTH_HMAC_ID_SHA256	0x0003
-#endif
 
 /* SCTP_AUTH_ACTIVE_KEY / SCTP_AUTH_DELETE_KEY */
 struct sctp_authkeyid {
diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c
index 92d7140..a3b9641 100755
--- a/netinet/sctp_usrreq.c
+++ b/netinet/sctp_usrreq.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 257555 2013-11-02 20:12:19Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -76,6 +76,8 @@
 sctp_init(uint16_t port,
           int (*conn_output)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
           void (*debug_printf)(const char *format, ...))
+#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
+sctp_init(struct protosw *pp SCTP_UNUSED, struct domain *dp SCTP_UNUSED)
 #else
 sctp_init(void)
 #endif
@@ -84,6 +86,7 @@
 	u_long sb_max_adj;
 
 #endif
+#if defined(__Userspace__)
 #if defined(__Userspace_os_Windows)
 #if defined(INET) || defined(INET6)
 	WSADATA wsaData;
@@ -95,6 +98,10 @@
 #endif
 	InitializeConditionVariable(&accept_cond);
 	InitializeCriticalSection(&accept_mtx);
+#else
+	pthread_cond_init(&accept_cond, NULL);
+	pthread_mutex_init(&accept_mtx, NULL);
+#endif
 #endif
 	/* Initialize and modify the sysctled variables */
 	sctp_init_sysctls();
@@ -172,8 +179,7 @@
 #if defined(__APPLE__)
 	SCTP_BASE_VAR(sctp_main_timer_ticks) = 0;
 	sctp_start_main_timer();
-	sctp_address_monitor_start();
-	sctp_over_udp_start();
+	timeout(sctp_delayed_startup, NULL, 1);
 #endif
 }
 
@@ -181,6 +187,7 @@
 sctp_finish(void)
 {
 #if defined(__APPLE__)
+	untimeout(sctp_delayed_startup, NULL);
 	sctp_over_udp_stop();
 	sctp_address_monitor_stop();
 	sctp_stop_main_timer();
@@ -430,8 +437,10 @@
 	    (icmph->icmp_code == ICMP_UNREACH_ISOLATED) ||
 	    (icmph->icmp_code == ICMP_UNREACH_NET_PROHIB) ||
 	    (icmph->icmp_code == ICMP_UNREACH_HOST_PROHIB) ||
-#ifdef __Panda__
+#if defined(__Panda__)
 	    (icmph->icmp_code == ICMP_UNREACH_ADMIN)) {
+#elif defined(__Userspace_os_NetBSD)
+	    (icmph->icmp_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
 #else
 	    (icmph->icmp_code == ICMP_UNREACH_FILTER_PROHIB)) {
 #endif
@@ -1286,17 +1295,7 @@
 				    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
 					struct mbuf *op_err;
 				abort_anyway:
-					op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-								       0, M_NOWAIT, 1, MT_DATA);
-					if (op_err) {
-						/* Fill in the user initiated abort */
-						struct sctp_paramhdr *ph;
-
-						SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-						ph = mtod(op_err, struct sctp_paramhdr *);
-						ph->param_type = htons(SCTP_CAUSE_USER_INITIATED_ABT);
-						ph->param_length = htons(SCTP_BUF_LEN(op_err));
-					}
+					op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 					stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ+SCTP_LOC_4;
 					sctp_send_abort_tcb(stcb, op_err, SCTP_SO_LOCKED);
 					SCTP_STAT_INCR_COUNTER32(sctps_aborted);
@@ -1494,17 +1493,7 @@
 			    (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) {
 				struct mbuf *op_err;
 			abort_anyway:
-				op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-							       0, M_NOWAIT, 1, MT_DATA);
-				if (op_err) {
-					/* Fill in the user initiated abort */
-					struct sctp_paramhdr *ph;
-
-					SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-					ph = mtod(op_err, struct sctp_paramhdr *);
-					ph->param_type = htons( SCTP_CAUSE_USER_INITIATED_ABT);
-					ph->param_length = htons(SCTP_BUF_LEN(op_err));
-				}
+				op_err = sctp_generate_cause(SCTP_CAUSE_USER_INITIATED_ABT, "");
 				stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_USRREQ+SCTP_LOC_6;
 				sctp_abort_an_association(stcb->sctp_ep, stcb,
 							  op_err, SCTP_SO_LOCKED);
@@ -3434,7 +3423,7 @@
 
 		if (stcb) {
 			/* simply copy out the sockaddr_storage... */
-			int len;
+			size_t len;
 
 			len = *optsize;
 #ifdef HAVE_SA_LEN
@@ -7792,7 +7781,7 @@
 
 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
 struct pr_usrreqs sctp_usrreqs = {
-#if __FreeBSD_version >= 600000
+#if defined(__FreeBSD__)
 	.pru_abort = sctp_abort,
 	.pru_accept = sctp_accept,
 	.pru_attach = sctp_attach,
@@ -7816,45 +7805,51 @@
 	.pru_sockaddr = sctp_ingetaddr,
 	.pru_sosend = sctp_sosend,
 	.pru_soreceive = sctp_soreceive
-#else
+#elif defined(__APPLE__)
+	.pru_abort = sctp_abort,
+	.pru_accept = sctp_accept,
+	.pru_attach = sctp_attach,
+	.pru_bind = sctp_bind,
+	.pru_connect = sctp_connect,
+	.pru_connect2 = pru_connect2_notsupp,
+	.pru_control = in_control,
+	.pru_detach = sctp_detach,
+	.pru_disconnect = sctp_disconnect,
+	.pru_listen = sctp_listen,
+	.pru_peeraddr = sctp_peeraddr,
+	.pru_rcvd = NULL,
+	.pru_rcvoob = pru_rcvoob_notsupp,
+	.pru_send = sctp_sendm,
+	.pru_sense = pru_sense_null,
+	.pru_shutdown = sctp_shutdown,
+	.pru_sockaddr = sctp_ingetaddr,
+	.pru_sosend = sctp_sosend,
+	.pru_soreceive = sctp_soreceive,
+	.pru_sopoll = sopoll
+#elif defined(__Windows__)
 	sctp_abort,
 	sctp_accept,
 	sctp_attach,
 	sctp_bind,
 	sctp_connect,
 	pru_connect2_notsupp,
-#if defined(__Windows__)
 	NULL,
 	NULL,
-#else
-	in_control,
-	sctp_detach,
-#endif
 	sctp_disconnect,
 	sctp_listen,
 	sctp_peeraddr,
 	NULL,
 	pru_rcvoob_notsupp,
-#if defined(__Windows__)
 	NULL,
-#else
-	sctp_sendm,
-#endif
 	pru_sense_null,
 	sctp_shutdown,
-#if defined(__Windows__)
 	sctp_flush,
-#endif
 	sctp_ingetaddr,
 	sctp_sosend,
 	sctp_soreceive,
-#if defined(__Windows__)
 	sopoll_generic,
 	NULL,
 	sctp_close
-#else
-	sopoll
-#endif
 #endif
 };
 #elif !defined(__Panda__) && !defined(__Userspace__)
diff --git a/netinet/sctp_var.h b/netinet/sctp_var.h
index af9edeb..f2a0316 100755
--- a/netinet/sctp_var.h
+++ b/netinet/sctp_var.h
@@ -436,13 +436,13 @@
 void sctp_init(uint16_t,
                int (*)(void *addr, void *buffer, size_t length, uint8_t tos, uint8_t set_df),
                void (*)(const char *, ...));
-#else
-#if defined(__FreeBSD__) && __FreeBSD_version < 902000
+#elif defined(__FreeBSD__) && __FreeBSD_version < 902000
 void sctp_init __P((void));
+#elif defined(__APPLE__) && (!defined(APPLE_LEOPARD) && !defined(APPLE_SNOWLEOPARD) &&!defined(APPLE_LION) && !defined(APPLE_MOUNTAINLION))
+void sctp_init(struct protosw *pp, struct domain *dp);
 #else
 void sctp_init(void);
 #endif
-#endif
 void sctp_finish(void);
 #if defined(__FreeBSD__) || defined(__Windows__) || defined(__Userspace__)
 int sctp_flush(struct socket *, int);
diff --git a/netinet/sctputil.c b/netinet/sctputil.c
index 93f3e4b..56a2257 100755
--- a/netinet/sctputil.c
+++ b/netinet/sctputil.c
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 257800 2013-11-07 16:37:12Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -4216,6 +4216,7 @@
 sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
                  struct sockaddr *src, struct sockaddr *dst,
                  struct sctphdr *sh, struct sctp_inpcb *inp,
+                 struct mbuf *cause,
 #if defined(__FreeBSD__)
                  uint8_t use_mflowid, uint32_t mflowid,
 #endif
@@ -4284,7 +4285,7 @@
 	if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
 	    ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
 	     (contains_init_chunk == 0))) {
-		sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
+		sctp_send_abort(m, iphlen, src, dst, sh, 0, cause,
 #if defined(__FreeBSD__)
 		                use_mflowid, mflowid,
 #endif
@@ -5083,19 +5084,24 @@
  */
 
 struct mbuf *
-sctp_generate_invmanparam(int err)
+sctp_generate_cause(uint16_t code, char *info)
 {
-	/* Return a MBUF with a invalid mandatory parameter */
 	struct mbuf *m;
+	struct sctp_gen_error_cause *cause;
+	size_t info_len, len;
 
-	m = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr), 0, M_NOWAIT, 1, MT_DATA);
-	if (m) {
-		struct sctp_paramhdr *ph;
-
-		SCTP_BUF_LEN(m) = sizeof(struct sctp_paramhdr);
-		ph = mtod(m, struct sctp_paramhdr *);
-		ph->param_length = htons(sizeof(struct sctp_paramhdr));
-		ph->param_type = htons(err);
+	if ((code == 0) || (info == NULL)) {
+		return (NULL);
+	}
+	info_len = strlen(info);
+	len = sizeof(struct sctp_paramhdr) + info_len;
+	m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
+	if (m != NULL) {
+		SCTP_BUF_LEN(m) = len;
+		cause = mtod(m, struct sctp_gen_error_cause *);
+		cause->code = htons(code);
+		cause->length = htons((uint16_t)len);
+		memcpy(cause->info, info, info_len);
 	}
 	return (m);
 }
@@ -6477,8 +6483,8 @@
 #else
 		if ((uio->uio_resid == 0) ||
 #endif
-		    ((in_eeor_mode) && (copied_so_far >= max(so->so_rcv.sb_lowat, 1)))
-			) {
+		    ((in_eeor_mode) &&
+		     (copied_so_far >= (uint32_t)max(so->so_rcv.sb_lowat, 1)))) {
 			goto release;
 		}
 		/*
@@ -6527,13 +6533,13 @@
 			SOCKBUF_LOCK(&so->so_rcv);
 			hold_sblock = 1;
 		}
-#if defined(__APPLE__)
-		sbunlock(&so->so_rcv, 1);
-#endif
 		if ((copied_so_far) && (control->length == 0) &&
 		    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
 			goto release;
 		}
+#if defined(__APPLE__)
+		sbunlock(&so->so_rcv, 1);
+#endif
 		if (so->so_rcv.sb_cc <= control->held_length) {
 			error = sbwait(&so->so_rcv);
 			if (error) {
diff --git a/netinet/sctputil.h b/netinet/sctputil.h
index e602251..9815a4c 100755
--- a/netinet/sctputil.h
+++ b/netinet/sctputil.h
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 243186 2012-11-17 20:04:04Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.h 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #ifndef _NETINET_SCTP_UTIL_H_
@@ -202,6 +202,7 @@
 void sctp_handle_ootb(struct mbuf *, int, int,
                       struct sockaddr *, struct sockaddr *,
                       struct sctphdr *, struct sctp_inpcb *,
+                      struct mbuf *,
 #if defined(__FreeBSD__)
                       uint8_t, uint32_t,
 #endif
@@ -269,7 +270,7 @@
 #endif
 );
 
-struct mbuf *sctp_generate_invmanparam(int);
+struct mbuf *sctp_generate_cause(uint16_t, char *);
 
 void sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
 			    struct sockaddr *sa, sctp_assoc_t assoc_id,
diff --git a/netinet6/sctp6_usrreq.c b/netinet6/sctp6_usrreq.c
index e3e2707..45a3196 100644
--- a/netinet6/sctp6_usrreq.c
+++ b/netinet6/sctp6_usrreq.c
@@ -463,8 +463,10 @@
 	    (icmph->icmp6_code == ICMP_UNREACH_ISOLATED) ||
 	    (icmph->icmp6_code == ICMP_UNREACH_NET_PROHIB) ||
 	    (icmph->icmp6_code == ICMP_UNREACH_HOST_PROHIB) ||
-#ifdef __Panda__
+#if defined(__Panda__)
             (icmph->icmp6_code == ICMP_UNREACH_ADMIN)) {
+#elif defined(__Userspace_os_NetBSD)
+            (icmph->icmp6_code == ICMP_UNREACH_ADMIN_PROHIBIT)) {
 #else
             (icmph->icmp6_code == ICMP_UNREACH_FILTER_PROHIB)) {
 #endif
@@ -1683,7 +1685,7 @@
 
 #if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__)
 struct pr_usrreqs sctp6_usrreqs = {
-#if __FreeBSD_version >= 600000
+#if defined(__FreeBSD__)
 	.pru_abort = sctp6_abort,
 	.pru_accept = sctp_accept,
 	.pru_attach = sctp6_attach,
@@ -1707,46 +1709,52 @@
 	.pru_sockaddr = sctp6_in6getaddr,
 	.pru_sosend = sctp_sosend,
 	.pru_soreceive = sctp_soreceive
-#else
+#elif defined(__APPLE__)
+	.pru_abort = sctp6_abort,
+	.pru_accept = sctp_accept,
+	.pru_attach = sctp6_attach,
+	.pru_bind = sctp6_bind,
+	.pru_connect = sctp6_connect,
+	.pru_connect2 = pru_connect2_notsupp,
+	.pru_control = in6_control,
+	.pru_detach = sctp6_detach,
+	.pru_disconnect = sctp6_disconnect,
+	.pru_listen = sctp_listen,
+	.pru_peeraddr = sctp6_getpeeraddr,
+	.pru_rcvd = NULL,
+	.pru_rcvoob = pru_rcvoob_notsupp,
+	.pru_send = sctp6_send,
+	.pru_sense = pru_sense_null,
+	.pru_shutdown = sctp_shutdown,
+	.pru_sockaddr = sctp6_in6getaddr,
+	.pru_sosend = sctp_sosend,
+	.pru_soreceive = sctp_soreceive,
+ 	.pru_sopoll = sopoll
+#elif defined(__Windows__)
 	sctp6_abort,
 	sctp_accept,
 	sctp6_attach,
 	sctp6_bind,
 	sctp6_connect,
 	pru_connect2_notsupp,
-#if defined(__Windows__)
 	NULL,
 	NULL,
-#else
-	in6_control,
-	sctp6_detach,
-#endif
 	sctp6_disconnect,
 	sctp_listen,
 	sctp6_getpeeraddr,
 	NULL,
 	pru_rcvoob_notsupp,
-#if defined(__Windows__)
 	NULL,
-#else
-	sctp6_send,
-#endif
 	pru_sense_null,
 	sctp_shutdown,
-#if defined(__Windows__)
 	sctp_flush,
-#endif
 	sctp6_in6getaddr,
 	sctp_sosend,
 	sctp_soreceive,
-#if !defined(__Windows__)
- 	sopoll
-#else
 	sopoll_generic,
 	NULL,
 	sctp6_close
 #endif
-#endif
 };
 
 #elif !defined(__Panda__) && !defined(__Userspace__)
diff --git a/user_environment.c b/user_environment.c
index c540b61..6830a23 100755
--- a/user_environment.c
+++ b/user_environment.c
@@ -87,7 +87,7 @@
 	/* Fill buf[] with random(9) output */
 	for (i = 0; i < count; i+= (int)sizeof(uint32_t)) {
 		randval = random();
-		size = MIN(count - i, sizeof(uint32_t));
+		size = MIN(count - i, (int)sizeof(uint32_t));
 		memcpy(&((char *)buf)[i], &randval, (size_t)size);
 	}
 
diff --git a/user_ip6_var.h b/user_ip6_var.h
index 9c57d72..f5e4a60 100755
--- a/user_ip6_var.h
+++ b/user_ip6_var.h
@@ -95,7 +95,7 @@
 #endif
 #endif
 
-#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD)
+#if !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_OpenBSD) && !defined(__Userspace_os_DragonFly)
 struct route_in6 {
 	struct	rtentry *ro_rt;
 	struct	llentry *ro_lle;
diff --git a/user_mbuf.h b/user_mbuf.h
index e5e286d..f371740 100755
--- a/user_mbuf.h
+++ b/user_mbuf.h
@@ -163,9 +163,9 @@
  * externally and attach it to the mbuf in a way similar to that of mbuf
  * clusters.
  */
-#define	MLEN		(MSIZE - sizeof(struct m_hdr))	/* normal data len */
-#define	MHLEN		(MLEN - sizeof(struct pkthdr))	/* data len w/pkthdr */
-#define	MINCLSIZE	(MHLEN + 1)	/* smallest amount to put in cluster */
+#define	MLEN		((int)(MSIZE - sizeof(struct m_hdr)))	/* normal data len */
+#define	MHLEN		((int)(MLEN - sizeof(struct pkthdr)))	/* data len w/pkthdr */
+#define	MINCLSIZE	((int)(MHLEN + 1))	/* smallest amount to put in cluster */
 #define	M_MAXCOMPRESS	(MHLEN / 2)	/* max amount to copy for compression */
 
 
diff --git a/user_recv_thread.c b/user_recv_thread.c
index 6a67850..7b2ff58 100755
--- a/user_recv_thread.c
+++ b/user_recv_thread.c
@@ -35,7 +35,7 @@
 #include <netinet/in.h>
 #include <unistd.h>
 #include <pthread.h>
-#if !defined(__Userspace_os_FreeBSD)
+#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD)
 #include <sys/uio.h>
 #else
 #include <user_ip6_var.h>
@@ -56,7 +56,7 @@
 #endif
 #endif
 #endif
-#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
 #include <net/route.h>
 #endif
 /* local macros and datatypes used to get IP addresses system independently */
@@ -67,12 +67,12 @@
 void recv_thread_destroy(void);
 #define MAXLEN_MBUF_CHAIN 32 /* What should this value be? */
 #define ROUNDUP(a, size) (((a) & ((size)-1)) ? (1 + ((a) | ((size)-1))) : (a))
-#if defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_Darwin)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
 #define NEXT_SA(ap) ap = (struct sockaddr *) \
 	((caddr_t) ap + (ap->sa_len ? ROUNDUP(ap->sa_len, sizeof (uint32_t)) : sizeof(uint32_t)))
 #endif
 
-#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
 static void
 sctp_get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
 {
@@ -1086,7 +1086,7 @@
 #else
 	unsigned int timeout = SOCKET_TIMEOUT; /* Timeout in milliseconds */
 #endif
-#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
 	if (SCTP_BASE_VAR(userspace_route) == -1) {
 		if ((SCTP_BASE_VAR(userspace_route) = socket(AF_ROUTE, SOCK_RAW, 0)) < 0) {
 			SCTPDBG(SCTP_DEBUG_USR, "Can't create routing socket (errno = %d).\n", errno);
@@ -1387,7 +1387,7 @@
 	}
 #endif
 #if !defined(__Userspace_os_Windows)
-#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
 #if defined(INET) || defined(INET6)
 	if (SCTP_BASE_VAR(userspace_route) != -1) {
 		int rc;
@@ -1479,7 +1479,7 @@
 void
 recv_thread_destroy(void)
 {
-#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_FreeBSD)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD)
 #if defined(INET) || defined(INET6)
 	if (SCTP_BASE_VAR(userspace_route) != -1) {
 		close(SCTP_BASE_VAR(userspace_route));
diff --git a/user_socket.c b/user_socket.c
index abbccee..e4e886f 100755
--- a/user_socket.c
+++ b/user_socket.c
@@ -48,14 +48,11 @@
 #if !defined (__Userspace_os_Windows)
 #include <netinet/udp.h>
 #include <arpa/inet.h>
-/* Statically initializing accept_mtx and accept_cond since there is no call for ACCEPT_LOCK_INIT() */
-userland_mutex_t accept_mtx = PTHREAD_MUTEX_INITIALIZER;
-userland_cond_t accept_cond = PTHREAD_COND_INITIALIZER;
 #else
 #include <user_socketvar.h>
+#endif
 userland_mutex_t accept_mtx;
 userland_cond_t accept_cond;
-#endif
 #ifdef _WIN32
 #include <time.h>
 #include <sys/timeb.h>
@@ -725,7 +722,7 @@
 		return (-1);
 	}
 	if ((tolen > 0) &&
-	    ((to == NULL) || (tolen < sizeof(struct sockaddr)))) {
+	    ((to == NULL) || (tolen < (socklen_t)sizeof(struct sockaddr)))) {
 		errno = EINVAL;
 		return (-1);
 	}
@@ -895,7 +892,7 @@
         error = (ENAMETOOLONG);
         goto sendmsg_return;
     }
-    if (tolen < offsetof(struct sockaddr, sa_data)){
+    if (tolen < (socklen_t)offsetof(struct sockaddr, sa_data)){
         error = (EINVAL);
         goto sendmsg_return;
     }
@@ -977,10 +974,15 @@
 		    (struct sctp_sndrcvinfo *)sinfo, 1);
 
 	if (error) {
-		if (auio.uio_resid != (int)ulen && (error == ERESTART ||
-		    error == EINTR || error == EWOULDBLOCK))
+		if (auio.uio_resid != (int)ulen &&
+		    (error == EINTR ||
+#if !defined(__Userspace_os_NetBSD)
+		     error == ERESTART ||
+#endif
+		     error == EWOULDBLOCK)) {
 			error = 0;
 		}
+	}
 	if ((fromlenp != NULL) && (fromlen > 0) && (from != NULL)) {
 		switch (from->sa_family) {
 #if defined(INET)
@@ -1066,7 +1068,11 @@
 		    (struct sctp_sndrcvinfo *)&seinfo, 1);
 	if (errno) {
 		if (auio.uio_resid != (int)ulen &&
-		    (errno == ERESTART || errno == EINTR || errno == EWOULDBLOCK)) {
+		    (errno == EINTR ||
+#if !defined(__Userspace_os_NetBSD)
+		     errno == ERESTART ||
+#endif
+		     errno == EWOULDBLOCK)) {
 			errno = 0;
 		}
 	}
@@ -1076,7 +1082,7 @@
 		inp = (struct sctp_inpcb *)so->so_pcb;
 		if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVNXTINFO) &&
 		    sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
-		    *infolen >= sizeof(struct sctp_recvv_rn) &&
+		    *infolen >= (socklen_t)sizeof(struct sctp_recvv_rn) &&
 		    seinfo.sreinfo_next_flags & SCTP_NEXT_MSG_AVAIL) {
 			rn = (struct sctp_recvv_rn *)info;
 			rn->recvv_rcvinfo.rcv_sid = seinfo.sinfo_stream;
@@ -1104,7 +1110,7 @@
 			*infolen = (socklen_t)sizeof(struct sctp_recvv_rn);
 			*infotype = SCTP_RECVV_RN;
 		} else if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_RECVRCVINFO) &&
-		           *infolen >= sizeof(struct sctp_rcvinfo)) {
+		           *infolen >= (socklen_t)sizeof(struct sctp_rcvinfo)) {
 			rcv = (struct sctp_rcvinfo *)info;
 			rcv->rcv_sid = seinfo.sinfo_stream;
 			rcv->rcv_ssn = seinfo.sinfo_ssn;
@@ -1747,8 +1753,33 @@
 	if (name) {
 #ifdef HAVE_SA_LEN
 		/* check sa_len before it is destroyed */
-		if (*namelen > sa->sa_len)
+		if (*namelen > sa->sa_len) {
 			*namelen = sa->sa_len;
+		}
+#else
+		socklen_t sa_len;
+
+		switch (sa->sa_family) {
+#ifdef INET
+		case AF_INET:
+			sa_len = sizeof(struct sockaddr_in);
+			break;
+#endif
+#ifdef INET6
+		case AF_INET6:
+			sa_len = sizeof(struct sockaddr_in6);
+			break;
+#endif
+		case AF_CONN:
+			sa_len = sizeof(struct sockaddr_conn);
+			break;
+		default:
+			sa_len = 0;
+			break;
+		}
+		if (*namelen > sa_len) {
+			*namelen = sa_len;
+		}
 #endif
 		*name = sa;
 		sa = NULL;
@@ -1989,8 +2020,13 @@
 		error = pthread_cond_wait(SOCK_COND(so), SOCK_MTX(so));
 #endif
 		if (error) {
-			if (error == EINTR || error == ERESTART)
+#if defined(__Userspace_os_NetBSD)
+			if (error == EINTR) {
+#else
+			if (error == EINTR || error == ERESTART) {
+#endif
 				interrupted = 1;
+			}
 			break;
 		}
 	}
@@ -2001,10 +2037,14 @@
 	SOCK_UNLOCK(so);
 
 bad:
-	if (!interrupted)
+	if (!interrupted) {
 		so->so_state &= ~SS_ISCONNECTING;
-	if (error == ERESTART)
+	}
+#if !defined(__Userspace_os_NetBSD)
+	if (error == ERESTART) {
 		error = EINTR;
+	}
+#endif
 done1:
 	return (error);
 }
@@ -2306,13 +2346,17 @@
 {
 	struct sctp_getaddresses *gaddrs;
 	struct sockaddr *sa;
+#ifdef INET
 	struct sockaddr_in *sin;
+#endif
 #ifdef INET6
 	struct sockaddr_in6 *sin6;
 #endif
 	int i;
 	size_t argsz;
+#if defined(INET) || defined(INET6)
 	uint16_t sport = 0;
+#endif
 
 	/* validate the flags */
 	if ((flags != SCTP_BINDX_ADD_ADDR) &&
@@ -2352,7 +2396,7 @@
 				}
 			}
 #ifndef HAVE_SA_LEN
-		sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
+			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in));
 #endif
 			break;
 #endif
@@ -2379,27 +2423,19 @@
 				}
 			}
 #ifndef HAVE_SA_LEN
-		sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
+			sa = (struct sockaddr *)((caddr_t)sa + sizeof(struct sockaddr_in6));
 #endif
 			break;
 #endif
 		default:
 			/* Invalid address family specified. */
-			errno = EINVAL;
+			errno = EAFNOSUPPORT;
 			return (-1);
 		}
 #ifdef HAVE_SA_LEN
 		sa = (struct sockaddr *)((caddr_t)sa + sa->sa_len);
 #endif
 	}
-	/*
-	 * Now if there was a port mentioned, assure that the first address
-	 * has that port to make sure it fails or succeeds correctly.
-	 */
-	if (sport) {
-		sin = (struct sockaddr_in *)sa;
-		sin->sin_port = sport;
-	}
 	argsz = sizeof(struct sctp_getaddresses) +
 	        sizeof(struct sockaddr_storage);
 	if ((gaddrs = (struct sctp_getaddresses *)malloc(argsz)) == NULL) {
@@ -2437,6 +2473,29 @@
 			break;
 		}
 		memcpy(gaddrs->addr, sa, sa_len);
+		/*
+		 * Now, if there was a port mentioned, assure that the
+		 * first address has that port to make sure it fails or
+		 * succeeds correctly.
+		 */
+#if defined(INET) || defined(INET6)
+		if ((i == 0) && (sport != 0)) {
+			switch (gaddrs->addr->sa_family) {
+#ifdef INET
+			case AF_INET:
+				sin = (struct sockaddr_in *)gaddrs->addr;
+				sin->sin_port = sport;
+				break;
+#endif
+#ifdef INET6
+			case AF_INET6:
+				sin6 = (struct sockaddr_in6 *)gaddrs->addr;
+				sin6->sin6_port = sport;
+				break;
+#endif
+			}
+		}
+#endif
 		if (usrsctp_setsockopt(so, IPPROTO_SCTP, flags, gaddrs, (socklen_t)argsz) != 0) {
 			free(gaddrs);
 			return (-1);
@@ -2750,6 +2809,8 @@
 			ip = mtod(m, struct ip *);
 		}
 		udp = (struct udphdr *)(ip + 1);
+	} else {
+		udp = NULL;
 	}
 
 	if (!use_udp_tunneling) {
@@ -2906,6 +2967,8 @@
 			ip6 = mtod(m, struct ip6_hdr *);
 		}
 		udp = (struct udphdr *)(ip6 + 1);
+	} else {
+		udp = NULL;
 	}
 
 	if (!use_udp_tunneling) {
@@ -3238,6 +3301,7 @@
 USRSCTP_SYSCTL_SET_DEF(sctp_enable_sack_immediately)
 USRSCTP_SYSCTL_SET_DEF(sctp_vtag_time_wait)
 USRSCTP_SYSCTL_SET_DEF(sctp_blackhole)
+USRSCTP_SYSCTL_SET_DEF(sctp_diag_info_code)
 USRSCTP_SYSCTL_SET_DEF(sctp_fr_max_burst_default)
 USRSCTP_SYSCTL_SET_DEF(sctp_path_pf_threshold)
 USRSCTP_SYSCTL_SET_DEF(sctp_default_ss_module)
@@ -3316,6 +3380,7 @@
 USRSCTP_SYSCTL_GET_DEF(sctp_enable_sack_immediately)
 USRSCTP_SYSCTL_GET_DEF(sctp_vtag_time_wait)
 USRSCTP_SYSCTL_GET_DEF(sctp_blackhole)
+USRSCTP_SYSCTL_GET_DEF(sctp_diag_info_code)
 USRSCTP_SYSCTL_GET_DEF(sctp_fr_max_burst_default)
 USRSCTP_SYSCTL_GET_DEF(sctp_path_pf_threshold)
 USRSCTP_SYSCTL_GET_DEF(sctp_default_ss_module)
diff --git a/user_socketvar.h b/user_socketvar.h
index 6a7c818..dd4ff10 100755
--- a/user_socketvar.h
+++ b/user_socketvar.h
@@ -42,7 +42,7 @@
 /* #include <sys/_lock.h>  was 0 byte file */
 /* #include <sys/_mutex.h> was 0 byte file */
 /* #include <sys/_sx.h> */ /*__Userspace__ alternative?*/
-#if !defined(__Userspace_os_Windows) && !defined(__Userspace_os_FreeBSD)
+#if !defined(__Userspace_os_DragonFly) && !defined(__Userspace_os_FreeBSD) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_Windows) 
 #include <sys/uio.h>
 #endif
 #define SOCK_MAXADDRLEN 255
@@ -54,16 +54,16 @@
 #define SS_CANTRCVMORE 0x020
 #define SS_CANTSENDMORE 0x010
 
-#if defined (__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined(__Userspace_os_Darwin) || defined (__Userspace_os_Windows)
+#if defined(__Userspace_os_Darwin) || defined(__Userspace_os_DragonFly) || defined(__Userspace_os_FreeBSD) || defined(__Userspace_os_OpenBSD) || defined (__Userspace_os_Windows)
 #define UIO_MAXIOV 1024
 #define ERESTART (-1)
 #endif
 
-#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_OpenBSD)
+#if !defined(__Userspace_os_Darwin) && !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD)
 enum	uio_rw { UIO_READ, UIO_WRITE };
 #endif
 
-#if !defined(__Userspace_os_OpenBSD)
+#if !defined(__Userspace_os_NetBSD) && !defined(__Userspace_os_OpenBSD)
 /* Segment flag values. */
 enum uio_seg {
 	UIO_USERSPACE,		/* from user data space */
@@ -737,7 +737,7 @@
 
 /* can we read something from so? */
 #define	soreadable(so) \
-    ((so)->so_rcv.sb_cc >= (so)->so_rcv.sb_lowat || \
+    ((int)((so)->so_rcv.sb_cc) >= (so)->so_rcv.sb_lowat || \
 	((so)->so_rcv.sb_state & SBS_CANTRCVMORE) || \
 	!TAILQ_EMPTY(&(so)->so_comp) || (so)->so_error)
 
diff --git a/usrsctp.h b/usrsctp.h
index 86bac66..052c076 100644
--- a/usrsctp.h
+++ b/usrsctp.h
@@ -1046,6 +1046,7 @@
 USRSCTP_SYSCTL_DECL(sctp_enable_sack_immediately)
 USRSCTP_SYSCTL_DECL(sctp_vtag_time_wait)
 USRSCTP_SYSCTL_DECL(sctp_blackhole)
+USRSCTP_SYSCTL_DECL(sctp_diag_info_code)
 USRSCTP_SYSCTL_DECL(sctp_fr_max_burst_default)
 USRSCTP_SYSCTL_DECL(sctp_path_pf_threshold)
 USRSCTP_SYSCTL_DECL(sctp_default_ss_module)