summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/sctp.h6
-rw-r--r--sys/netinet/sctp_constants.h3
-rw-r--r--sys/netinet/sctp_indata.c644
-rw-r--r--sys/netinet/sctp_input.c122
-rw-r--r--sys/netinet/sctp_output.c11
-rw-r--r--sys/netinet/sctp_pcb.c39
-rw-r--r--sys/netinet/sctp_sysctl.c7
-rw-r--r--sys/netinet/sctp_sysctl.h6
-rw-r--r--sys/netinet/sctp_timer.c44
-rw-r--r--sys/netinet/sctp_usrreq.c27
-rw-r--r--sys/netinet/sctputil.c28
-rw-r--r--sys/netinet/sctputil.h3
12 files changed, 275 insertions, 665 deletions
diff --git a/sys/netinet/sctp.h b/sys/netinet/sctp.h
index 46d738f..2f7f49b 100644
--- a/sys/netinet/sctp.h
+++ b/sys/netinet/sctp.h
@@ -365,6 +365,12 @@ struct sctp_paramhdr {
/*
* 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/sys/netinet/sctp_constants.h b/sys/netinet/sctp_constants.h
index 7deff39..bb01eec 100644
--- a/sys/netinet/sctp_constants.h
+++ b/sys/netinet/sctp_constants.h
@@ -771,6 +771,9 @@ __FBSDID("$FreeBSD$");
*/
#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/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 7446170..2c2c4bd 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -561,7 +561,8 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
@@ -578,7 +579,7 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb, struct sctp_association *asoc,
(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:
/*
@@ -586,26 +587,12 @@ protocol_error:
* 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;
@@ -839,7 +826,9 @@ static void
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;
@@ -864,30 +853,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
* 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) {
@@ -897,28 +870,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
* 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) {
/*
@@ -931,30 +890,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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 &&
@@ -963,31 +907,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
}
@@ -1057,31 +985,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
@@ -1091,33 +1002,18 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
* 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;
}
@@ -1131,30 +1027,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
@@ -1164,31 +1045,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
@@ -1208,30 +1072,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
!= 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;
}
@@ -1247,31 +1095,14 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
@@ -1284,31 +1115,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
@@ -1322,30 +1137,15 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
}
@@ -1430,7 +1230,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
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;
@@ -1497,15 +1298,12 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
*/
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);
@@ -1633,27 +1431,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
/* 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);
}
@@ -1892,28 +1676,11 @@ failed_pdapi_express_del:
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 {
@@ -1925,31 +1692,11 @@ failed_pdapi_express_del:
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);
}
@@ -1971,30 +1718,11 @@ failed_pdapi_express_del:
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);
}
@@ -2601,26 +2329,11 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
* 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,
@@ -2688,7 +2401,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
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,
@@ -3837,7 +3550,8 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
}
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
@@ -3846,22 +3560,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
*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
}
@@ -4211,23 +3914,14 @@ again:
(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;
@@ -4420,7 +4114,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
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.
@@ -4435,22 +4130,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
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;
}
}
@@ -4939,23 +4623,14 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
(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;
@@ -5384,33 +5059,20 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
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/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 6ea85f5..2be2b87 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -97,7 +97,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
}
/* 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,
use_mflowid, mflowid,
vrf_id, port);
@@ -109,7 +109,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
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,
use_mflowid, mflowid,
vrf_id, port);
@@ -119,7 +119,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
vrf_id, port);
@@ -129,7 +129,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
vrf_id, port);
@@ -139,7 +139,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
vrf_id, port);
@@ -150,7 +150,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
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,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@@ -179,7 +181,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
* 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,
use_mflowid, mflowid,
vrf_id, port);
}
@@ -461,12 +465,13 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
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,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@@ -521,8 +526,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
*/
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
@@ -1305,7 +1309,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
@@ -1317,7 +1321,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
/* 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,
use_mflowid, mflowid,
@@ -1327,7 +1331,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
@@ -1337,7 +1341,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
@@ -1347,7 +1351,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
}
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,
use_mflowid, mflowid,
@@ -1457,7 +1461,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
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;
@@ -1476,17 +1479,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
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,
use_mflowid, mflowid,
vrf_id, net->port);
@@ -1693,25 +1686,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
* 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,
use_mflowid, mflowid,
vrf_id, port);
@@ -2124,8 +2099,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
/* 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,
use_mflowid, mflowid,
@@ -2153,7 +2127,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
* 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,
use_mflowid, mflowid,
@@ -2772,7 +2746,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
#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,
use_mflowid, mflowid,
@@ -4394,6 +4368,8 @@ __attribute__((noinline))
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;
@@ -4547,8 +4523,11 @@ __attribute__((noinline))
}
}
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,
use_mflowid, mflowid,
vrf_id, port);
*offset = length;
@@ -4588,8 +4567,11 @@ __attribute__((noinline))
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,
use_mflowid, mflowid,
vrf_id, port);
return (NULL);
@@ -4731,8 +4713,10 @@ process_control_chunks:
/* 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,
use_mflowid, mflowid,
vrf_id, port);
*offset = length;
@@ -4740,9 +4724,7 @@ process_control_chunks:
}
/* 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,
use_mflowid, mflowid,
@@ -5110,9 +5092,7 @@ process_control_chunks:
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,
use_mflowid, mflowid,
@@ -5597,7 +5577,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
{
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;
@@ -5683,8 +5664,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
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,
use_mflowid, mflowid,
vrf_id, port);
}
@@ -5742,7 +5725,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
*/
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,
use_mflowid, mflowid,
vrf_id, port);
goto out;
@@ -5789,7 +5775,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
}
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,
use_mflowid, mflowid,
vrf_id, port);
goto out;
@@ -5858,7 +5847,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
/*
* 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,
use_mflowid, mflowid,
vrf_id, port);
goto out;
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 5d3a32a..63d8d4a 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -5392,7 +5392,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* 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,
use_mflowid, mflowid,
vrf_id, port);
return;
@@ -5403,6 +5405,13 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
&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,
use_mflowid, mflowid,
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 88dd145..08a8577 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -3333,17 +3333,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
/* 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);
@@ -3414,20 +3404,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
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);
@@ -3491,17 +3468,7 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from)
((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);
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index 77e59bd..5836dcb 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -116,7 +116,7 @@ sctp_init_sysctls()
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)
memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log));
#endif
@@ -655,6 +655,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
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);
@@ -1113,6 +1114,10 @@ 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);
+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,
&SCTP_BASE_SYSCTL(sctp_debug_on), 0, sysctl_sctp_check, "IU",
diff --git a/sys/netinet/sctp_sysctl.h b/sys/netinet/sctp_sysctl.h
index 8090373..064f6bd 100644
--- a/sys/netinet/sctp_sysctl.h
+++ b/sys/netinet/sctp_sysctl.h
@@ -104,6 +104,7 @@ struct sctp_sysctl {
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)
struct sctp_log sctp_log;
#endif
@@ -529,6 +530,11 @@ struct sctp_sysctl {
#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/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c
index 188b086..2aef412 100644
--- a/sys/netinet/sctp_timer.c
+++ b/sys/netinet/sctp_timer.c
@@ -147,24 +147,12 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
if (stcb->asoc.overall_error_count > threshold) {
/* Abort notification sends a ULP notify */
- struct mbuf *oper;
-
- 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);
- }
+ struct mbuf *op_err;
+
+ 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);
@@ -1051,24 +1039,12 @@ sctp_cookie_timer(struct sctp_inpcb *inp,
if (cookie == NULL) {
if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_ECHOED) {
/* FOOBAR! */
- struct mbuf *oper;
-
- 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);
- }
+ struct mbuf *op_err;
+
+ 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/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 761ef28..83bb0ad 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -854,20 +854,7 @@ sctp_disconnect(struct socket *so)
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);
@@ -1063,17 +1050,7 @@ sctp_shutdown(struct socket *so)
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);
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 4ce988e..be21b11 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -4018,6 +4018,7 @@ void
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,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
@@ -4076,7 +4077,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
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,
use_mflowid, mflowid,
vrf_id, port);
}
@@ -4631,19 +4632,24 @@ get_out:
*/
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);
}
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index 411bfaf..73c7f10 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -205,6 +205,7 @@ void
sctp_handle_ootb(struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_inpcb *,
+ struct mbuf *,
uint8_t, uint32_t,
uint32_t, uint16_t);
@@ -252,7 +253,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
#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,
OpenPOWER on IntegriCloud