#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>
}
/* 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,
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,
}
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,
}
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,
}
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,
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
* 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
/* 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)),
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
*/
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
}
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__)
/* 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__)
}
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__)
}
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__)
}
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__)
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;
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,
return (NULL);
}
- switch SCTP_GET_STATE(asoc) {
+ switch (SCTP_GET_STATE(asoc)) {
case SCTP_STATE_COOKIE_WAIT:
case SCTP_STATE_COOKIE_ECHOED:
/*
* 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,
/* 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__)
* 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__)
#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__)
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;
}
}
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
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
/* 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
}
/* 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__)
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__)
{
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;
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
*/
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
}
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
/*
* 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