Pass the src and dst address of a received packet explicitly around.

MFC after: 3 days
This commit is contained in:
Michael Tuexen 2012-06-28 16:01:08 +00:00
parent db0cb5be21
commit b1754ad17b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237715
15 changed files with 329 additions and 673 deletions

View file

@ -50,59 +50,8 @@ __FBSDID("$FreeBSD$");
*/
static void
sctp_asconf_get_source_ip(struct mbuf *m, struct sockaddr *sa)
{
struct ip *iph;
#ifdef INET
struct sockaddr_in *sin;
#endif
#ifdef INET6
struct sockaddr_in6 *sin6;
#endif
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
{
/* IPv4 source */
sin = (struct sockaddr_in *)sa;
bzero(sin, sizeof(*sin));
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_port = 0;
sin->sin_addr.s_addr = iph->ip_src.s_addr;
break;
}
#endif
#ifdef INET6
case (IPV6_VERSION >> 4):
{
/* IPv6 source */
struct ip6_hdr *ip6;
sin6 = (struct sockaddr_in6 *)sa;
bzero(sin6, sizeof(*sin6));
sin6->sin6_family = AF_INET6;
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_port = 0;
ip6 = mtod(m, struct ip6_hdr *);
sin6->sin6_addr = ip6->ip6_src;
break;
}
#endif /* INET6 */
default:
break;
}
return;
}
/*
* draft-ietf-tsvwg-addip-sctp
* RFC 5061
*
* An ASCONF parameter queue exists per asoc which holds the pending address
* operations. Lists are updated upon receipt of ASCONF-ACK.
@ -194,12 +143,12 @@ sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
}
static struct mbuf *
sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *aph,
struct sctp_tcb *stcb, int send_hb, int response_required)
{
struct sctp_nets *net;
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_source, sa_store;
struct sockaddr_storage sa_store;
struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
@ -279,11 +228,10 @@ sctp_process_asconf_add_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
/* if 0.0.0.0/::0, add the source address instead */
if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
sa = (struct sockaddr *)&sa_source;
sctp_asconf_get_source_ip(m, sa);
sa = src;
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_asconf_add_ip: using source addr ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
}
/* add the address */
if (bad_address) {
@ -343,11 +291,12 @@ sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
}
static struct mbuf *
sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
sctp_process_asconf_delete_ip(struct sockaddr *src,
struct sctp_asconf_paramhdr *aph,
struct sctp_tcb *stcb, int response_required)
{
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_source, sa_store;
struct sockaddr_storage sa_store;
struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
@ -365,9 +314,6 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
#endif
/* get the source IP address for src and 0.0.0.0/::0 delete checks */
sctp_asconf_get_source_ip(m, (struct sockaddr *)&sa_source);
aparam_length = ntohs(aph->ph.param_length);
ph = (struct sctp_paramhdr *)(aph + 1);
param_type = ntohs(ph->param_type);
@ -424,7 +370,7 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
}
/* make sure the source address is not being deleted */
if (sctp_cmpaddr(sa, (struct sockaddr *)&sa_source)) {
if (sctp_cmpaddr(sa, src)) {
/* trying to delete the source address! */
SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
m_reply = sctp_asconf_error_response(aph->correlation_id,
@ -434,8 +380,7 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
}
/* if deleting 0.0.0.0/::0, delete all addresses except src addr */
if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
result = sctp_asconf_del_remote_addrs_except(stcb,
(struct sockaddr *)&sa_source);
result = sctp_asconf_del_remote_addrs_except(stcb, src);
if (result) {
/* src address did not exist? */
@ -475,12 +420,12 @@ sctp_process_asconf_delete_ip(struct mbuf *m, struct sctp_asconf_paramhdr *aph,
}
static struct mbuf *
sctp_process_asconf_set_primary(struct mbuf *m,
sctp_process_asconf_set_primary(struct sockaddr *src,
struct sctp_asconf_paramhdr *aph,
struct sctp_tcb *stcb, int response_required)
{
struct mbuf *m_reply = NULL;
struct sockaddr_storage sa_source, sa_store;
struct sockaddr_storage sa_store;
struct sctp_paramhdr *ph;
uint16_t param_type, param_length, aparam_length;
struct sockaddr *sa;
@ -550,11 +495,10 @@ sctp_process_asconf_set_primary(struct mbuf *m,
/* if 0.0.0.0/::0, use the source address instead */
if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
sa = (struct sockaddr *)&sa_source;
sctp_asconf_get_source_ip(m, sa);
sa = src;
SCTPDBG(SCTP_DEBUG_ASCONF1,
"process_asconf_set_primary: using source addr ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
}
/* set the primary address */
if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
@ -626,6 +570,7 @@ sctp_process_asconf_set_primary(struct mbuf *m,
*/
void
sctp_handle_asconf(struct mbuf *m, unsigned int offset,
struct sockaddr *src,
struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
int first)
{
@ -762,13 +707,13 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
switch (param_type) {
case SCTP_ADD_IP_ADDRESS:
asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_add_ip(m, aph, stcb,
m_result = sctp_process_asconf_add_ip(src, aph, stcb,
(cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
cnt++;
break;
case SCTP_DEL_IP_ADDRESS:
asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_delete_ip(m, aph, stcb,
m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
error);
break;
case SCTP_ERROR_CAUSE_IND:
@ -776,7 +721,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
break;
case SCTP_SET_PRIM_ADDR:
asoc->peer_supports_asconf = 1;
m_result = sctp_process_asconf_set_primary(m, aph,
m_result = sctp_process_asconf_set_primary(src, aph,
stcb, error);
break;
case SCTP_NAT_VTAGS:
@ -856,11 +801,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
* this could happen if the source address was just newly
* added
*/
struct sockaddr_storage addr;
struct sockaddr *src = (struct sockaddr *)&addr;
SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
sctp_asconf_get_source_ip(m, src);
SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
/* look up the from address */

View file

@ -46,8 +46,8 @@ extern void sctp_asconf_cleanup(struct sctp_tcb *, struct sctp_nets *);
extern struct mbuf *sctp_compose_asconf(struct sctp_tcb *, int *, int);
extern void
sctp_handle_asconf(struct mbuf *, unsigned int, struct sctp_asconf_chunk *,
struct sctp_tcb *, int i);
sctp_handle_asconf(struct mbuf *, unsigned int, struct sockaddr *,
struct sctp_asconf_chunk *, struct sctp_tcb *, int);
extern void
sctp_handle_asconf_ack(struct mbuf *, int, struct sctp_asconf_ack_chunk *,

View file

@ -2516,6 +2516,7 @@ sctp_service_queues(struct sctp_tcb *stcb, struct sctp_association *asoc)
int
sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_inpcb *inp,
struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t * high_tsn,
uint8_t use_mflowid, uint32_t mflowid,
@ -2626,8 +2627,8 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
}
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
sctp_abort_association(inp, stcb, m, iphlen, sh,
op_err,
sctp_abort_association(inp, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
return (2);
@ -2695,6 +2696,7 @@ sctp_process_data(struct mbuf **mm, int iphlen, int *offset, int length,
op_err = sctp_generate_invmanparam(SCTP_CAUSE_PROTOCOL_VIOLATION);
sctp_abort_association(inp, stcb,
m, iphlen,
src, dst,
sh, op_err,
use_mflowid, mflowid,
vrf_id, port);

View file

@ -111,7 +111,9 @@ void
sctp_update_acked(struct sctp_tcb *, struct sctp_shutdown_chunk *, int *);
int
sctp_process_data(struct mbuf **, int, int *, int, struct sctphdr *,
sctp_process_data(struct mbuf **, int, int *, int,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *,
struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint32_t *,
uint8_t, uint32_t,

View file

@ -80,7 +80,8 @@ sctp_stop_all_cookie_timers(struct sctp_tcb *stcb)
/* INIT handler */
static void
sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
sctp_handle_init(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
struct sctp_init_chunk *cp, struct sctp_inpcb *inp,
struct sctp_tcb *stcb, int *abort_no_unlock,
uint8_t use_mflowid, uint32_t mflowid,
@ -97,7 +98,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
/* validate length */
if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@ -109,7 +110,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (init->initiate_tag == 0) {
/* protocol error... send abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@ -119,7 +120,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
/* invalid parameter... send abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@ -129,7 +130,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (init->num_inbound_streams == 0) {
/* protocol error... send abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@ -139,7 +140,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (init->num_outbound_streams == 0) {
/* protocol error... send abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(inp, stcb, m, iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@ -149,7 +150,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
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, sh, NULL,
sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, NULL,
use_mflowid, mflowid,
vrf_id, port);
if (stcb)
@ -178,7 +179,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
* state :-)
*/
if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
sctp_send_abort(m, iphlen, sh, 0, NULL,
sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
use_mflowid, mflowid,
vrf_id, port);
}
@ -191,7 +192,8 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_CONTROL_PROC, SCTP_SO_NOT_LOCKED);
} else {
SCTPDBG(SCTP_DEBUG_INPUT3, "sctp_handle_init: sending INIT-ACK\n");
sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, sh, cp,
sctp_send_initiate_ack(inp, stcb, m, iphlen, offset, src, dst,
sh, cp,
use_mflowid, mflowid,
vrf_id, port,
((stcb == NULL) ? SCTP_HOLDS_LOCK : SCTP_NOT_LOCKED));
@ -419,7 +421,8 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
* INIT-ACK message processing/consumption returns value < 0 on error
*/
static int
sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
struct sctp_nets *net, int *abort_no_unlock,
uint8_t use_mflowid, uint32_t mflowid,
@ -454,13 +457,14 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh
initack_limit = offset + ntohs(cp->ch.chunk_length);
/* load all addresses */
if ((retval = sctp_load_addresses_from_init(stcb, m,
(offset + sizeof(struct sctp_init_chunk)), initack_limit, sh,
NULL))) {
(offset + sizeof(struct sctp_init_chunk)), initack_limit,
src, dst, NULL))) {
/* Huh, we should abort */
SCTPDBG(SCTP_DEBUG_INPUT1,
"Load addresses from INIT causes an abort %d\n",
retval);
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh, NULL,
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
src, dst, sh, NULL,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -536,7 +540,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh
mp->resv = 0;
}
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
sh, op_err,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -1278,7 +1282,8 @@ sctp_handle_error(struct sctp_chunkhdr *ch,
}
static int
sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh,
struct sctp_init_ack_chunk *cp, struct sctp_tcb *stcb,
struct sctp_nets *net, int *abort_no_unlock,
uint8_t use_mflowid, uint32_t mflowid,
@ -1298,8 +1303,8 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
/* Invalid length */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
op_err,
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -1310,8 +1315,8 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (init_ack->initiate_tag == 0) {
/* protocol error... send an abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
op_err,
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -1320,8 +1325,8 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
/* protocol error... send an abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
op_err,
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -1330,8 +1335,8 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (init_ack->num_inbound_streams == 0) {
/* protocol error... send an abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
op_err,
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -1340,8 +1345,8 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if (init_ack->num_outbound_streams == 0) {
/* protocol error... send an abort */
op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen, sh,
op_err,
sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
*abort_no_unlock = 1;
@ -1365,7 +1370,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_CONFIRMED,
stcb, 0, (void *)stcb->asoc.primary_destination, SCTP_SO_NOT_LOCKED);
}
if (sctp_process_init_ack(m, iphlen, offset, sh, cp, stcb,
if (sctp_process_init_ack(m, iphlen, offset, src, dst, sh, cp, stcb,
net, abort_no_unlock,
use_mflowid, mflowid,
vrf_id) < 0) {
@ -1419,6 +1424,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
static struct sctp_tcb *
sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
struct sctp_inpcb *inp, struct sctp_nets **netp,
struct sockaddr *init_src, int *notification,
@ -1435,6 +1441,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
*/
static struct sctp_tcb *
sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets **netp,
struct sockaddr *init_src, int *notification,
@ -1477,7 +1484,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
sctp_send_operr_to(m, sh, cookie->peers_vtag, op_err,
sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
use_mflowid, mflowid,
vrf_id, net->port);
if (how_indx < sizeof(asoc->cookie_how))
@ -1642,7 +1649,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
*/
if (sctp_load_addresses_from_init(stcb, m,
init_offset + sizeof(struct sctp_init_chunk),
initack_offset, sh, init_src)) {
initack_offset, src, dst, init_src)) {
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 4;
return (NULL);
@ -1703,7 +1710,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
ph = mtod(op_err, struct sctp_paramhdr *);
ph->param_type = htons(SCTP_CAUSE_NAT_COLLIDING_STATE);
ph->param_length = htons(sizeof(struct sctp_paramhdr));
sctp_send_abort(m, iphlen, sh, 0, op_err,
sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
use_mflowid, mflowid,
vrf_id, port);
return (NULL);
@ -1786,7 +1793,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
}
if (sctp_load_addresses_from_init(stcb, m,
init_offset + sizeof(struct sctp_init_chunk),
initack_offset, sh, init_src)) {
initack_offset, src, dst, init_src)) {
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 10;
return (NULL);
@ -1867,7 +1874,8 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
* cookie_new code since we are allowing a duplicate
* association. I hope this works...
*/
return (sctp_process_cookie_new(m, iphlen, offset, sh, cookie, cookie_len,
return (sctp_process_cookie_new(m, iphlen, offset, src, dst,
sh, cookie, cookie_len,
inp, netp, init_src, notification,
auth_skipped, auth_offset, auth_len,
use_mflowid, mflowid,
@ -1972,7 +1980,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
if (sctp_load_addresses_from_init(stcb, m,
init_offset + sizeof(struct sctp_init_chunk),
initack_offset, sh, init_src)) {
initack_offset, src, dst, init_src)) {
if (how_indx < sizeof(asoc->cookie_how))
asoc->cookie_how[how_indx] = 14;
@ -2003,6 +2011,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
*/
static struct sctp_tcb *
sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_state_cookie *cookie, int cookie_len,
struct sctp_inpcb *inp, struct sctp_nets **netp,
struct sockaddr *init_src, int *notification,
@ -2102,7 +2111,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
sh, op_err,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
return (NULL);
@ -2130,7 +2139,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
atomic_add_int(&stcb->asoc.refcnt, 1);
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
sh, op_err,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@ -2179,8 +2188,8 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
}
/* load all addresses */
if (sctp_load_addresses_from_init(stcb, m,
init_offset + sizeof(struct sctp_init_chunk), initack_offset, sh,
init_src)) {
init_offset + sizeof(struct sctp_init_chunk), initack_offset,
src, dst, init_src)) {
atomic_add_int(&stcb->asoc.refcnt, 1);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
SCTP_TCB_UNLOCK(stcb);
@ -2376,6 +2385,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
*/
static struct mbuf *
sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_cookie_echo_chunk *cp,
struct sctp_inpcb **inp_p, struct sctp_tcb **stcb, struct sctp_nets **netp,
int auth_skipped, uint32_t auth_offset, uint32_t auth_len,
@ -2396,9 +2406,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
unsigned int cookie_len;
struct timeval now;
struct timeval time_expires;
struct sockaddr_storage dest_store;
struct sockaddr *localep_sa = (struct sockaddr *)&dest_store;
struct ip *iph;
int notification = 0;
struct sctp_nets *netl;
int had_a_existing_tcb = 0;
@ -2419,45 +2426,6 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
if (inp_p == NULL) {
return (NULL);
}
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
{
/* its IPv4 */
struct sockaddr_in *lsin;
lsin = (struct sockaddr_in *)(localep_sa);
memset(lsin, 0, sizeof(*lsin));
lsin->sin_family = AF_INET;
lsin->sin_len = sizeof(*lsin);
lsin->sin_port = sh->dest_port;
lsin->sin_addr.s_addr = iph->ip_dst.s_addr;
break;
}
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
/* its IPv6 */
struct ip6_hdr *ip6;
struct sockaddr_in6 *lsin6;
lsin6 = (struct sockaddr_in6 *)(localep_sa);
memset(lsin6, 0, sizeof(*lsin6));
lsin6->sin6_family = AF_INET6;
lsin6->sin6_len = sizeof(struct sockaddr_in6);
ip6 = mtod(m, struct ip6_hdr *);
lsin6->sin6_port = sh->dest_port;
lsin6->sin6_addr = ip6->ip6_dst;
break;
}
#endif
default:
return (NULL);
}
cookie = &cp->cookie;
cookie_offset = offset + sizeof(struct sctp_chunkhdr);
cookie_len = ntohs(cp->ch.chunk_length);
@ -2608,7 +2576,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
if (tim == 0)
tim = now.tv_usec - cookie->time_entered.tv_usec;
scm->time_usec = htonl(tim);
sctp_send_operr_to(m, sh, cookie->peers_vtag, op_err,
sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
use_mflowid, mflowid,
vrf_id, port);
return (NULL);
@ -2652,7 +2620,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
}
if ((*stcb == NULL) && to) {
/* Yep, lets check */
*stcb = sctp_findassociation_ep_addr(inp_p, to, netp, localep_sa, NULL);
*stcb = sctp_findassociation_ep_addr(inp_p, to, netp, dst, NULL);
if (*stcb == NULL) {
/*
* We should have only got back the same inp. If we
@ -2695,15 +2663,17 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
cookie_len -= SCTP_SIGNATURE_SIZE;
if (*stcb == NULL) {
/* this is the "normal" case... get a new TCB */
*stcb = sctp_process_cookie_new(m, iphlen, offset, sh, cookie,
cookie_len, *inp_p, netp, to, &notification,
*stcb = sctp_process_cookie_new(m, iphlen, offset, src, dst, sh,
cookie, cookie_len, *inp_p,
netp, to, &notification,
auth_skipped, auth_offset, auth_len,
use_mflowid, mflowid,
vrf_id, port);
} else {
/* this is abnormal... cookie-echo on existing TCB */
had_a_existing_tcb = 1;
*stcb = sctp_process_cookie_existing(m, iphlen, offset, sh,
*stcb = sctp_process_cookie_existing(m, iphlen, offset,
src, dst, sh,
cookie, cookie_len, *inp_p, *stcb, netp, to,
&notification, auth_skipped, auth_offset, auth_len,
use_mflowid, mflowid,
@ -2788,7 +2758,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(*inp_p, NULL, m, iphlen,
sh, op_err,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING)
@ -4404,6 +4374,7 @@ __attribute__((noinline))
#endif
static struct sctp_tcb *
sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_chunkhdr *ch, struct sctp_inpcb *inp,
struct sctp_tcb *stcb, struct sctp_nets **netp, int *fwd_tsn_seen,
uint8_t use_mflowid, uint32_t mflowid,
@ -4520,7 +4491,9 @@ __attribute__((noinline))
if (asconf_len < sizeof(struct sctp_asconf_paramhdr))
break;
stcb = sctp_findassociation_ep_asconf(m,
*offset, sh, &inp, netp, vrf_id);
*offset,
dst,
sh, &inp, netp, vrf_id);
if (stcb != NULL)
break;
asconf_offset += SCTP_SIZE32(asconf_len);
@ -4562,7 +4535,7 @@ __attribute__((noinline))
}
if (stcb == NULL) {
/* no association, so it's out of the blue... */
sctp_handle_ootb(m, iphlen, *offset, sh, inp,
sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp,
use_mflowid, mflowid,
vrf_id, port);
*offset = length;
@ -4600,7 +4573,8 @@ __attribute__((noinline))
if (locked_tcb) {
SCTP_TCB_UNLOCK(locked_tcb);
}
sctp_handle_ootb(m, iphlen, *offset, sh, inp,
sctp_handle_ootb(m, iphlen, *offset, src, dst,
sh, inp,
use_mflowid, mflowid,
vrf_id, port);
return (NULL);
@ -4742,8 +4716,8 @@ __attribute__((noinline))
/* The INIT chunk must be the only chunk. */
if ((num_chunks > 1) ||
(length - *offset > (int)SCTP_SIZE32(chk_length))) {
sctp_abort_association(inp, stcb, m,
iphlen, sh, NULL,
sctp_abort_association(inp, stcb, m, iphlen,
src, dst, sh, NULL,
use_mflowid, mflowid,
vrf_id, port);
*offset = length;
@ -4754,14 +4728,14 @@ __attribute__((noinline))
struct mbuf *op_err;
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(inp, stcb, m,
iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
*offset = length;
return (NULL);
}
sctp_handle_init(m, iphlen, *offset, sh,
sctp_handle_init(m, iphlen, *offset, src, dst, sh,
(struct sctp_init_chunk *)ch, inp,
stcb, &abort_no_unlock,
use_mflowid, mflowid,
@ -4813,7 +4787,8 @@ __attribute__((noinline))
return (NULL);
}
if ((netp) && (*netp)) {
ret = sctp_handle_init_ack(m, iphlen, *offset, sh,
ret = sctp_handle_init_ack(m, iphlen, *offset,
src, dst, sh,
(struct sctp_init_ack_chunk *)ch,
stcb, *netp,
&abort_no_unlock,
@ -5123,8 +5098,8 @@ __attribute__((noinline))
struct mbuf *op_err;
op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
sctp_abort_association(inp, stcb, m,
iphlen, sh, op_err,
sctp_abort_association(inp, stcb, m, iphlen,
src, dst, sh, op_err,
use_mflowid, mflowid,
vrf_id, port);
}
@ -5151,7 +5126,9 @@ __attribute__((noinline))
if (netp) {
ret_buf =
sctp_handle_cookie_echo(m, iphlen,
*offset, sh,
*offset,
src, dst,
sh,
(struct sctp_cookie_echo_chunk *)ch,
&inp, &stcb, netp,
auth_skipped,
@ -5314,7 +5291,7 @@ __attribute__((noinline))
__LINE__);
}
stcb->asoc.overall_error_count = 0;
sctp_handle_asconf(m, *offset,
sctp_handle_asconf(m, *offset, src,
(struct sctp_asconf_chunk *)ch, stcb, asconf_cnt == 0);
asconf_cnt++;
}
@ -5610,8 +5587,9 @@ __attribute__((noinline))
* common input chunk processing (v4 and v6)
*/
void
sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
int length, struct sctphdr *sh, struct sctp_chunkhdr *ch,
sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int length,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_chunkhdr *ch,
struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_nets *net, uint8_t ecn_bits,
uint8_t use_mflowid, uint32_t mflowid,
@ -5650,7 +5628,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
* NOT respond to any packet.. its OOTB.
*/
SCTP_TCB_UNLOCK(stcb);
sctp_handle_ootb(m, iphlen, offset, sh, inp,
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
use_mflowid, mflowid,
vrf_id, port);
goto out_now;
@ -5659,7 +5637,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
if (IS_SCTP_CONTROL(ch)) {
/* process the control portion of the SCTP packet */
/* sa_ignore NO_NULL_CHK */
stcb = sctp_process_control(m, iphlen, &offset, length, sh, ch,
stcb = sctp_process_control(m, iphlen, &offset, length,
src, dst, sh, ch,
inp, stcb, &net, &fwd_tsn_seen,
use_mflowid, mflowid,
vrf_id, port);
@ -5697,7 +5676,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
}
if (stcb == NULL) {
/* out of the blue DATA chunk */
sctp_handle_ootb(m, iphlen, offset, sh, inp,
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
use_mflowid, mflowid,
vrf_id, port);
goto out_now;
@ -5767,7 +5746,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
/*
* We consider OOTB any data sent during asoc setup.
*/
sctp_handle_ootb(m, iphlen, offset, sh, inp,
sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
use_mflowid, mflowid,
vrf_id, port);
SCTP_TCB_UNLOCK(stcb);
@ -5788,7 +5767,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset,
break;
}
/* plow through the data chunks while length > offset */
retval = sctp_process_data(mm, iphlen, &offset, length, sh,
retval = sctp_process_data(mm, iphlen, &offset, length,
src, dst, sh,
inp, stcb, net, &high_tsn,
use_mflowid, mflowid,
vrf_id, port);
@ -5883,6 +5863,7 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
int iphlen;
uint32_t vrf_id = 0;
uint8_t ecn_bits;
struct sockaddr_in src, dst;
struct ip *ip;
struct sctphdr *sh;
struct sctp_chunkhdr *ch;
@ -5932,18 +5913,27 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
SCTP_STAT_INCR(sctps_recvpackets);
SCTP_STAT_INCR_COUNTER64(sctps_inpackets);
/* Get IP, SCTP, and first chunk header together in the first mbuf. */
ip = mtod(m, struct ip *);
offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
if (SCTP_BUF_LEN(m) < offset) {
if ((m = m_pullup(m, offset)) == 0) {
if ((m = m_pullup(m, offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
return;
}
ip = mtod(m, struct ip *);
}
ip = mtod(m, struct ip *);
sh = (struct sctphdr *)((caddr_t)ip + iphlen);
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset -= sizeof(struct sctp_chunkhdr);
memset(&src, 0, sizeof(struct sockaddr_in));
src.sin_family = AF_INET;
src.sin_len = sizeof(struct sockaddr_in);
src.sin_port = sh->src_port;
src.sin_addr = ip->ip_src;
memset(&dst, 0, sizeof(struct sockaddr_in));
dst.sin_family = AF_INET;
dst.sin_len = sizeof(struct sockaddr_in);
dst.sin_port = sh->dest_port;
dst.sin_addr = ip->ip_dst;
length = ip->ip_len + iphlen;
/* Validate mbuf chain length with IP payload length. */
if (SCTP_HEADER_LEN(i_pak) != length) {
@ -5953,10 +5943,10 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
goto bad;
}
/* SCTP does not allow broadcasts or multicasts */
if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) {
goto bad;
}
if (SCTP_IS_IT_BROADCAST(ip->ip_dst, m)) {
if (SCTP_IS_IT_BROADCAST(dst.sin_addr, m)) {
goto bad;
}
SCTPDBG(SCTP_DEBUG_INPUT1,
@ -5982,6 +5972,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
calc_check, check, m, length, iphlen);
stcb = sctp_findassociation_addr(m, offset,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch, &inp, &net, vrf_id);
if ((net) && (port)) {
if (net->port == 0) {
@ -6013,6 +6005,8 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
goto bad;
}
stcb = sctp_findassociation_addr(m, offset,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch, &inp, &net, vrf_id);
if ((net) && (port)) {
if (net->port == 0) {
@ -6031,7 +6025,9 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0)
goto bad;
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
sctp_send_shutdown_complete2(m, sh,
sctp_send_shutdown_complete2((struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh,
use_mflowid, mflowid,
vrf_id, port);
goto bad;
@ -6043,7 +6039,10 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
(ch->chunk_type != SCTP_INIT))) {
sctp_send_abort(m, iphlen, sh, 0, NULL,
sctp_send_abort(m, iphlen,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, 0, NULL,
use_mflowid, mflowid,
vrf_id, port);
}
@ -6066,8 +6065,10 @@ sctp_input_with_port(struct mbuf *i_pak, int off, uint16_t port)
ecn_bits = ip->ip_tos;
/* sa_ignore NO_NULL_CHK */
sctp_common_input_processing(&m, iphlen, offset, length, sh, ch,
inp, stcb, net, ecn_bits,
sctp_common_input_processing(&m, iphlen, offset, length,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch, inp, stcb, net, ecn_bits,
use_mflowid, mflowid,
vrf_id, port);
if (m) {
@ -6119,15 +6120,14 @@ sctp_input(struct mbuf *m, int off)
* No flow id built by lower layers fix it so we
* create one.
*/
ip = mtod(m, struct ip *);
offset = off + sizeof(*sh);
offset = off + sizeof(struct sctphdr);
if (SCTP_BUF_LEN(m) < offset) {
if ((m = m_pullup(m, offset)) == 0) {
if ((m = m_pullup(m, offset)) == NULL) {
SCTP_STAT_INCR(sctps_hdrops);
return;
}
ip = mtod(m, struct ip *);
}
ip = mtod(m, struct ip *);
sh = (struct sctphdr *)((caddr_t)ip + off);
tag = htonl(sh->v_tag);
flowid = tag ^ ntohs(sh->dest_port) ^ ntohs(sh->src_port);

View file

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#if defined(_KERNEL) || defined(__Userspace__)
void
sctp_common_input_processing(struct mbuf **, int, int, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_chunkhdr *,
struct sctp_inpcb *, struct sctp_tcb *,
struct sctp_nets *, uint8_t,

View file

@ -177,18 +177,9 @@ MALLOC_DECLARE(SCTP_M_MCORE);
} \
} while (0); \
}
#define SCTPDBG_PKT(level, iph, sh) \
{ \
do { \
if (SCTP_BASE_SYSCTL(sctp_debug_on) & level) { \
sctp_print_address_pkt(iph, sh); \
} \
} while (0); \
}
#else
#define SCTPDBG(level, params...)
#define SCTPDBG_ADDR(level, addr)
#define SCTPDBG_PKT(level, iph, sh)
#endif
#ifdef SCTP_LTRACE_CHUNKS
@ -394,10 +385,6 @@ typedef struct callout sctp_os_timer_t;
* its a NOP.
*/
/* Macro's for getting length from V6/V4 header */
#define SCTP_GET_IPV4_LENGTH(iph) (iph->ip_len)
#define SCTP_GET_IPV6_LENGTH(ip6) (ntohs(ip6->ip6_plen))
/* get the v6 hop limit */
#define SCTP_GET_HLIM(inp, ro) in6_selecthlim((struct in6pcb *)&inp->ip_inp.inp, (ro ? (ro->ro_rt ? (ro->ro_rt->rt_ifp) : (NULL)) : (NULL)));

View file

@ -5189,7 +5189,7 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt,
static int
sctp_are_there_new_addresses(struct sctp_association *asoc,
struct mbuf *in_initpkt, int offset)
struct mbuf *in_initpkt, int offset, struct sockaddr *src)
{
/*
* Given a INIT packet, look through the packet to verify that there
@ -5204,7 +5204,6 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
uint16_t ptype, plen;
uint8_t fnd;
struct sctp_nets *net;
struct ip *iph;
#ifdef INET
struct sockaddr_in sin4, *sa4;
@ -5212,7 +5211,6 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
#endif
#ifdef INET6
struct sockaddr_in6 sin6, *sa6;
struct ip6_hdr *ip6h;
#endif
@ -5226,37 +5224,18 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(sin6);
#endif
sa_touse = NULL;
/* First what about the src address of the pkt ? */
iph = mtod(in_initpkt, struct ip *);
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
/* source addr is IPv4 */
sin4.sin_addr = iph->ip_src;
sa_touse = (struct sockaddr *)&sin4;
break;
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
/* source addr is IPv6 */
ip6h = mtod(in_initpkt, struct ip6_hdr *);
sin6.sin6_addr = ip6h->ip6_src;
sa_touse = (struct sockaddr *)&sin6;
break;
#endif
default:
return (1);
}
fnd = 0;
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
sa = (struct sockaddr *)&net->ro._l_addr;
if (sa->sa_family == sa_touse->sa_family) {
if (sa->sa_family == src->sa_family) {
#ifdef INET
if (sa->sa_family == AF_INET) {
struct sockaddr_in *src4;
sa4 = (struct sockaddr_in *)sa;
if (sa4->sin_addr.s_addr == sin4.sin_addr.s_addr) {
src4 = (struct sockaddr_in *)src;
if (sa4->sin_addr.s_addr == src4->sin_addr.s_addr) {
fnd = 1;
break;
}
@ -5264,8 +5243,11 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
#endif
#ifdef INET6
if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *src6;
sa6 = (struct sockaddr_in6 *)sa;
if (SCTP6_ARE_ADDR_EQUAL(sa6, &sin6)) {
src6 = (struct sockaddr_in6 *)src;
if (SCTP6_ARE_ADDR_EQUAL(sa6, src6)) {
fnd = 1;
break;
}
@ -5373,6 +5355,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
void
sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct mbuf *init_pkt, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_init_chunk *init_chk,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port, int hold_inp_lock)
@ -5384,20 +5367,18 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct sctp_ecn_supported_param *ecn;
struct sctp_prsctp_supported_param *prsctp;
struct sctp_supported_chunk_types_param *pr_supported;
union sctp_sockstore store, store1, *over_addr;
union sctp_sockstore *over_addr;
#ifdef INET
struct sockaddr_in *sin, *to_sin;
struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
struct sockaddr_in *src4 = (struct sockaddr_in *)src;
struct sockaddr_in *sin;
#endif
#ifdef INET6
struct sockaddr_in6 *sin6, *to_sin6;
#endif
struct ip *iph;
#ifdef INET6
struct ip6_hdr *ip6;
struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)src;
struct sockaddr_in6 *sin6;
#endif
struct sockaddr *to;
@ -5412,21 +5393,22 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
int nat_friendly = 0;
struct socket *so;
if (stcb)
if (stcb) {
asoc = &stcb->asoc;
else
} else {
asoc = NULL;
}
mp_last = NULL;
if ((asoc != NULL) &&
(SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) &&
(sctp_are_there_new_addresses(asoc, init_pkt, offset))) {
(sctp_are_there_new_addresses(asoc, init_pkt, offset, src))) {
/* new addresses, out of here in non-cookie-wait states */
/*
* Send a ABORT, we don't add the new address error clause
* 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, sh, 0, NULL,
sctp_send_abort(init_pkt, iphlen, src, dst, sh, 0, NULL,
use_mflowid, mflowid,
vrf_id, port);
return;
@ -5437,7 +5419,7 @@ 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:
sctp_send_abort(init_pkt, iphlen, sh,
sctp_send_abort(init_pkt, iphlen, src, dst, sh,
init_chk->init.initiate_tag, op_err,
use_mflowid, mflowid,
vrf_id, port);
@ -5502,61 +5484,20 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#else
stc.ipv4_scope = 0;
#endif
/* now for scope setup */
memset((caddr_t)&store, 0, sizeof(store));
memset((caddr_t)&store1, 0, sizeof(store1));
#ifdef INET
sin = &store.sin;
to_sin = &store1.sin;
#endif
#ifdef INET6
sin6 = &store.sin6;
to_sin6 = &store1.sin6;
#endif
iph = mtod(init_pkt, struct ip *);
/* establish the to_addr's */
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
to_sin->sin_port = sh->dest_port;
to_sin->sin_family = AF_INET;
to_sin->sin_len = sizeof(struct sockaddr_in);
to_sin->sin_addr = iph->ip_dst;
break;
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
ip6 = mtod(init_pkt, struct ip6_hdr *);
to_sin6->sin6_addr = ip6->ip6_dst;
to_sin6->sin6_scope_id = 0;
to_sin6->sin6_port = sh->dest_port;
to_sin6->sin6_family = AF_INET6;
to_sin6->sin6_len = sizeof(struct sockaddr_in6);
break;
#endif
default:
goto do_a_abort;
break;
}
if (net == NULL) {
to = (struct sockaddr *)&store;
switch (iph->ip_v) {
to = src;
switch (dst->sa_family) {
#ifdef INET
case IPVERSION:
case AF_INET:
{
sin->sin_family = AF_INET;
sin->sin_len = sizeof(struct sockaddr_in);
sin->sin_port = sh->src_port;
sin->sin_addr = iph->ip_src;
/* lookup address */
stc.address[0] = sin->sin_addr.s_addr;
stc.address[0] = src4->sin_addr.s_addr;
stc.address[1] = 0;
stc.address[2] = 0;
stc.address[3] = 0;
stc.addr_type = SCTP_IPV4_ADDRESS;
/* local from address */
stc.laddress[0] = to_sin->sin_addr.s_addr;
stc.laddress[0] = dst4->sin_addr.s_addr;
stc.laddress[1] = 0;
stc.laddress[2] = 0;
stc.laddress[3] = 0;
@ -5564,14 +5505,14 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
/* scope_id is only for v6 */
stc.scope_id = 0;
#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE
if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
if (IN4_ISPRIVATE_ADDRESS(&src4->sin_addr)) {
stc.ipv4_scope = 1;
}
#else
stc.ipv4_scope = 1;
#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
/* Must use the address in this case */
if (sctp_is_address_on_local_host((struct sockaddr *)sin, vrf_id)) {
if (sctp_is_address_on_local_host(src, vrf_id)) {
stc.loopback_scope = 1;
stc.ipv4_scope = 1;
stc.site_scope = 1;
@ -5581,32 +5522,16 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
case AF_INET6:
{
ip6 = mtod(init_pkt, struct ip6_hdr *);
sin6->sin6_family = AF_INET6;
sin6->sin6_len = sizeof(struct sockaddr_in6);
sin6->sin6_port = sh->src_port;
sin6->sin6_addr = ip6->ip6_src;
/* lookup address */
memcpy(&stc.address, &sin6->sin6_addr,
sizeof(struct in6_addr));
sin6->sin6_scope_id = 0;
stc.addr_type = SCTP_IPV6_ADDRESS;
stc.scope_id = 0;
if (sctp_is_address_on_local_host((struct sockaddr *)sin6, vrf_id)) {
/*
* FIX ME: does this have scope from
* rcvif?
*/
(void)sa6_recoverscope(sin6);
stc.scope_id = sin6->sin6_scope_id;
sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
stc.scope_id = in6_getscope(&src6->sin6_addr);
if (sctp_is_address_on_local_host(src, vrf_id)) {
stc.loopback_scope = 1;
stc.local_scope = 0;
stc.site_scope = 1;
stc.ipv4_scope = 1;
} else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
} else if (IN6_IS_ADDR_LINKLOCAL(&src6->sin6_addr)) {
/*
* If the new destination is a
* LINK_LOCAL we must have common
@ -5631,14 +5556,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* pull out the scope_id from
* incoming pkt
*/
/*
* FIX ME: does this have scope from
* rcvif?
*/
(void)sa6_recoverscope(sin6);
stc.scope_id = sin6->sin6_scope_id;
sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
} else if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
} else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr)) {
/*
* If the new destination is
* SITE_LOCAL then we must have site
@ -5646,7 +5564,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
*/
stc.site_scope = 1;
}
memcpy(&stc.laddress, &to_sin6->sin6_addr, sizeof(struct in6_addr));
memcpy(&stc.laddress, &dst6->sin6_addr, sizeof(struct in6_addr));
stc.laddr_type = SCTP_IPV6_ADDRESS;
break;
}
@ -5726,7 +5644,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
if (net->src_addr_selected == 0) {
/*
* strange case here, the INIT should have
* did the selection.
* done the selection.
*/
net->ro._s_addr = sctp_source_address_selection(inp,
stcb, (sctp_route_t *) & net->ro,
@ -6034,7 +5952,7 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
}
if (stc.loopback_scope) {
over_addr = &store1;
over_addr = (union sctp_sockstore *)dst;
} else {
over_addr = NULL;
}
@ -10879,7 +10797,8 @@ sctp_send_shutdown_complete(struct sctp_tcb *stcb,
}
static void
sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, uint32_t vtag,
uint8_t type, struct mbuf *cause,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
@ -10888,17 +10807,18 @@ sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
struct mbuf *mout;
struct sctphdr *shout;
struct sctp_chunkhdr *ch;
struct ip *iph;
struct udphdr *udp;
int len, cause_len, padding_len, ret;
#ifdef INET
sctp_route_t ro;
struct ip *iph_out;
struct sockaddr_in *src_sin, *dst_sin;
struct ip *ip;
#endif
#ifdef INET6
struct ip6_hdr *ip6, *ip6_out;
struct sockaddr_in6 *src_sin6, *dst_sin6;
struct ip6_hdr *ip6;
#endif
@ -10927,15 +10847,14 @@ sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
}
/* Get an mbuf for the header. */
len = sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr);
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
switch (dst->sa_family) {
#ifdef INET
case IPVERSION:
case AF_INET:
len += sizeof(struct ip);
break;
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
case AF_INET6:
len += sizeof(struct ip6_hdr);
break;
#endif
@ -10960,51 +10879,54 @@ sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
mout->m_flags |= M_FLOWID;
}
#ifdef INET
iph_out = NULL;
ip = NULL;
#endif
#ifdef INET6
ip6_out = NULL;
ip6 = NULL;
#endif
switch (iph->ip_v) {
switch (dst->sa_family) {
#ifdef INET
case IPVERSION:
iph_out = mtod(mout, struct ip *);
iph_out->ip_v = IPVERSION;
iph_out->ip_hl = (sizeof(struct ip) >> 2);
iph_out->ip_tos = 0;
iph_out->ip_id = ip_newid();
iph_out->ip_off = 0;
iph_out->ip_ttl = MODULE_GLOBAL(ip_defttl);
case AF_INET:
src_sin = (struct sockaddr_in *)src;
dst_sin = (struct sockaddr_in *)dst;
ip = mtod(mout, struct ip *);
ip->ip_v = IPVERSION;
ip->ip_hl = (sizeof(struct ip) >> 2);
ip->ip_tos = 0;
ip->ip_id = ip_newid();
ip->ip_off = 0;
ip->ip_ttl = MODULE_GLOBAL(ip_defttl);
if (port) {
iph_out->ip_p = IPPROTO_UDP;
ip->ip_p = IPPROTO_UDP;
} else {
iph_out->ip_p = IPPROTO_SCTP;
ip->ip_p = IPPROTO_SCTP;
}
iph_out->ip_src.s_addr = iph->ip_dst.s_addr;
iph_out->ip_dst.s_addr = iph->ip_src.s_addr;
iph_out->ip_sum = 0;
ip->ip_src.s_addr = dst_sin->sin_addr.s_addr;
ip->ip_dst.s_addr = src_sin->sin_addr.s_addr;
ip->ip_sum = 0;
len = sizeof(struct ip);
shout = (struct sctphdr *)((caddr_t)iph_out + len);
shout = (struct sctphdr *)((caddr_t)ip + len);
break;
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
ip6 = (struct ip6_hdr *)iph;
ip6_out = mtod(mout, struct ip6_hdr *);
ip6_out->ip6_flow = htonl(0x60000000);
case AF_INET6:
src_sin6 = (struct sockaddr_in6 *)src;
dst_sin6 = (struct sockaddr_in6 *)dst;
ip6 = mtod(mout, struct ip6_hdr *);
ip6->ip6_flow = htonl(0x60000000);
if (V_ip6_auto_flowlabel) {
ip6_out->ip6_flow |= (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
ip6->ip6_flow |= (htonl(ip6_randomflowlabel()) & IPV6_FLOWLABEL_MASK);
}
ip6_out->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
ip6->ip6_hlim = MODULE_GLOBAL(ip6_defhlim);
if (port) {
ip6_out->ip6_nxt = IPPROTO_UDP;
ip6->ip6_nxt = IPPROTO_UDP;
} else {
ip6_out->ip6_nxt = IPPROTO_SCTP;
ip6->ip6_nxt = IPPROTO_SCTP;
}
ip6_out->ip6_src = ip6->ip6_dst;
ip6_out->ip6_dst = ip6->ip6_src;
ip6->ip6_src = dst_sin6->sin6_addr;
ip6->ip6_dst = src_sin6->sin6_addr;
len = sizeof(struct ip6_hdr);
shout = (struct sctphdr *)((caddr_t)ip6_out + len);
shout = (struct sctphdr *)((caddr_t)ip6 + len);
break;
#endif
default:
@ -11056,17 +10978,17 @@ sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
}
SCTP_ATTACH_CHAIN(o_pak, mout, len);
#ifdef INET
if (iph_out != NULL) {
if (ip != NULL) {
/* zap the stack pointer to the route */
bzero(&ro, sizeof(sctp_route_t));
if (port) {
if (V_udp_cksum) {
udp->uh_sum = in_pseudo(iph_out->ip_src.s_addr, iph_out->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
udp->uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, udp->uh_ulen + htons(IPPROTO_UDP));
} else {
udp->uh_sum = 0;
}
}
iph_out->ip_len = len;
ip->ip_len = len;
if (port) {
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_sendnocrc);
@ -11099,8 +11021,8 @@ sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
}
#endif
#ifdef INET6
if (ip6_out != NULL) {
ip6_out->ip6_plen = len - sizeof(struct ip6_hdr);
if (ip6 != NULL) {
ip6->ip6_plen = len - sizeof(struct ip6_hdr);
if (port) {
#if defined(SCTP_WITH_NO_CSUM)
SCTP_STAT_INCR(sctps_sendnocrc);
@ -11135,11 +11057,12 @@ sctp_send_resp_msg(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
}
void
sctp_send_shutdown_complete2(struct mbuf *m, struct sctphdr *sh,
sctp_send_shutdown_complete2(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
sctp_send_resp_msg(m, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL,
sctp_send_resp_msg(src, dst, sh, 0, SCTP_SHUTDOWN_COMPLETE, NULL,
use_mflowid, mflowid,
vrf_id, port);
}
@ -11319,7 +11242,6 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
struct sctp_tmit_chunk *chk;
uint8_t *datap;
int was_trunc = 0;
struct ip *iph;
int fullsz = 0;
long spc;
int offset;
@ -11345,11 +11267,6 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
return;
}
chk->copy_by_ref = 0;
iph = mtod(m, struct ip *);
if (iph == NULL) {
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
return;
}
len -= iphlen;
chk->send_size = len;
/* Validate that we do not have an ABORT in here. */
@ -11951,8 +11868,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
}
void
sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
struct mbuf *cause,
sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, uint32_t vtag, struct mbuf *cause,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
@ -11962,19 +11879,19 @@ sctp_send_abort(struct mbuf *m, int iphlen, struct sctphdr *sh, uint32_t vtag,
sctp_m_freem(cause);
return;
}
sctp_send_resp_msg(m, sh, vtag, SCTP_ABORT_ASSOCIATION, cause,
sctp_send_resp_msg(src, dst, sh, vtag, SCTP_ABORT_ASSOCIATION, cause,
use_mflowid, mflowid,
vrf_id, port);
return;
}
void
sctp_send_operr_to(struct mbuf *m, struct sctphdr *sh, uint32_t vtag,
struct mbuf *cause,
sctp_send_operr_to(struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, uint32_t vtag, struct mbuf *cause,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
sctp_send_resp_msg(m, sh, vtag, SCTP_OPERATION_ERROR, cause,
sctp_send_resp_msg(src, dst, sh, vtag, SCTP_OPERATION_ERROR, cause,
use_mflowid, mflowid,
vrf_id, port);
return;

View file

@ -84,7 +84,9 @@ sctp_send_initiate(struct sctp_inpcb *, struct sctp_tcb *, int
void
sctp_send_initiate_ack(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *,
int, int, struct sctphdr *, struct sctp_init_chunk *,
int, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_init_chunk *,
uint8_t, uint32_t,
uint32_t, uint16_t, int);
@ -116,7 +118,8 @@ void sctp_send_shutdown_ack(struct sctp_tcb *, struct sctp_nets *);
void sctp_send_shutdown_complete(struct sctp_tcb *, struct sctp_nets *, int);
void
sctp_send_shutdown_complete2(struct mbuf *, struct sctphdr *,
sctp_send_shutdown_complete2(struct sockaddr *, struct sockaddr *,
struct sctphdr *,
uint8_t, uint32_t,
uint32_t, uint16_t);
@ -203,14 +206,14 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
uint16_t adding_i, uint8_t from_peer);
void
sctp_send_abort(struct mbuf *, int, struct sctphdr *, uint32_t,
struct mbuf *,
sctp_send_abort(struct mbuf *, int, struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
uint8_t, uint32_t,
uint32_t, uint16_t);
void
sctp_send_operr_to(struct mbuf *, struct sctphdr *, uint32_t,
struct mbuf *,
sctp_send_operr_to(struct sockaddr *, struct sockaddr *,
struct sctphdr *, uint32_t, struct mbuf *,
uint8_t, uint32_t,
uint32_t, uint16_t);

View file

@ -1891,7 +1891,7 @@ sctp_pcb_findep(struct sockaddr *nam, int find_tcp_pool, int have_lock,
* need to change the *to to some other struct like a mbuf...
*/
struct sctp_tcb *
sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
sctp_findassociation_addr_sa(struct sockaddr *from, struct sockaddr *to,
struct sctp_inpcb **inp_p, struct sctp_nets **netp, int find_tcp_pool,
uint32_t vrf_id)
{
@ -1946,7 +1946,7 @@ sctp_findassociation_addr_sa(struct sockaddr *to, struct sockaddr *from,
static struct sctp_tcb *
sctp_findassociation_special_addr(struct mbuf *m, int offset,
struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp,
struct sockaddr *dest)
struct sockaddr *dst)
{
struct sctp_paramhdr *phdr, parm_buf;
struct sctp_tcb *retval;
@ -2000,7 +2000,7 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
memcpy(&sin4.sin_addr, &p4->addr, sizeof(p4->addr));
/* look it up */
retval = sctp_findassociation_ep_addr(inp_p,
(struct sockaddr *)&sin4, netp, dest, NULL);
(struct sockaddr *)&sin4, netp, dst, NULL);
if (retval != NULL) {
return (retval);
}
@ -2021,7 +2021,7 @@ sctp_findassociation_special_addr(struct mbuf *m, int offset,
memcpy(&sin6.sin6_addr, &p6->addr, sizeof(p6->addr));
/* look it up */
retval = sctp_findassociation_ep_addr(inp_p,
(struct sockaddr *)&sin6, netp, dest, NULL);
(struct sockaddr *)&sin6, netp, dst, NULL);
if (retval != NULL) {
return (retval);
}
@ -2144,101 +2144,17 @@ sctp_findassoc_by_vtag(struct sockaddr *from, struct sockaddr *to, uint32_t vtag
*/
struct sctp_tcb *
sctp_findassociation_addr(struct mbuf *m, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_chunkhdr *ch,
struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
{
int find_tcp_pool;
struct ip *iph;
struct sctp_tcb *retval;
struct sockaddr_storage to_store, from_store;
struct sockaddr *to = (struct sockaddr *)&to_store;
struct sockaddr *from = (struct sockaddr *)&from_store;
struct sctp_inpcb *inp;
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
{
/* its IPv4 */
struct sockaddr_in *from4;
from4 = (struct sockaddr_in *)&from_store;
bzero(from4, sizeof(*from4));
from4->sin_family = AF_INET;
from4->sin_len = sizeof(struct sockaddr_in);
from4->sin_addr.s_addr = iph->ip_src.s_addr;
from4->sin_port = sh->src_port;
break;
}
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
/* its IPv6 */
struct ip6_hdr *ip6;
struct sockaddr_in6 *from6;
ip6 = mtod(m, struct ip6_hdr *);
from6 = (struct sockaddr_in6 *)&from_store;
bzero(from6, sizeof(*from6));
from6->sin6_family = AF_INET6;
from6->sin6_len = sizeof(struct sockaddr_in6);
from6->sin6_addr = ip6->ip6_src;
from6->sin6_port = sh->src_port;
/* Get the scopes in properly to the sin6 addr's */
sa6_embedscope(from6, MODULE_GLOBAL(ip6_use_defzone));
break;
}
#endif
default:
/* Currently not supported. */
return (NULL);
}
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
{
/* its IPv4 */
struct sockaddr_in *to4;
to4 = (struct sockaddr_in *)&to_store;
bzero(to4, sizeof(*to4));
to4->sin_family = AF_INET;
to4->sin_len = sizeof(struct sockaddr_in);
to4->sin_addr.s_addr = iph->ip_dst.s_addr;
to4->sin_port = sh->dest_port;
break;
}
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
/* its IPv6 */
struct ip6_hdr *ip6;
struct sockaddr_in6 *to6;
ip6 = mtod(m, struct ip6_hdr *);
to6 = (struct sockaddr_in6 *)&to_store;
bzero(to6, sizeof(*to6));
to6->sin6_family = AF_INET6;
to6->sin6_len = sizeof(struct sockaddr_in6);
to6->sin6_addr = ip6->ip6_dst;
to6->sin6_port = sh->dest_port;
/* Get the scopes in properly to the sin6 addr's */
sa6_embedscope(to6, MODULE_GLOBAL(ip6_use_defzone));
break;
}
#endif
default:
/* TSNH */
break;
}
if (sh->v_tag) {
/* we only go down this path if vtag is non-zero */
retval = sctp_findassoc_by_vtag(from, to, ntohl(sh->v_tag),
retval = sctp_findassoc_by_vtag(src, dst, ntohl(sh->v_tag),
inp_p, netp, sh->src_port, sh->dest_port, 0, vrf_id, 0);
if (retval) {
return (retval);
@ -2253,11 +2169,11 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
find_tcp_pool = 1;
}
if (inp_p) {
retval = sctp_findassociation_addr_sa(to, from, inp_p, netp,
retval = sctp_findassociation_addr_sa(src, dst, inp_p, netp,
find_tcp_pool, vrf_id);
inp = *inp_p;
} else {
retval = sctp_findassociation_addr_sa(to, from, &inp, netp,
retval = sctp_findassociation_addr_sa(src, dst, &inp, netp,
find_tcp_pool, vrf_id);
}
SCTPDBG(SCTP_DEBUG_PCB1, "retval:%p inp:%p\n", retval, inp);
@ -2280,7 +2196,7 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
return (NULL);
}
retval = sctp_findassociation_special_addr(m,
offset, sh, &inp, netp, to);
offset, sh, &inp, netp, dst);
if (inp_p != NULL) {
*inp_p = inp;
}
@ -2296,12 +2212,11 @@ sctp_findassociation_addr(struct mbuf *m, int offset,
*/
struct sctp_tcb *
sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
struct sctphdr *sh, struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
struct sockaddr *dst, struct sctphdr *sh,
struct sctp_inpcb **inp_p, struct sctp_nets **netp, uint32_t vrf_id)
{
struct sctp_tcb *stcb;
struct sockaddr_storage local_store, remote_store;
struct sockaddr *to;
struct ip *iph;
struct sockaddr_storage remote_store;
struct sctp_paramhdr parm_buf, *phdr;
int ptype;
int zero_address = 0;
@ -2311,42 +2226,11 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
#endif
#ifdef INET6
struct ip6_hdr *ip6;
struct sockaddr_in6 *sin6;
#endif
memset(&local_store, 0, sizeof(local_store));
memset(&remote_store, 0, sizeof(remote_store));
to = (struct sockaddr *)&local_store;
/* First get the destination address setup too. */
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
/* its IPv4 */
sin = (struct sockaddr_in *)&local_store;
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
sin->sin_port = sh->dest_port;
sin->sin_addr.s_addr = iph->ip_dst.s_addr;
break;
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
/* its IPv6 */
ip6 = mtod(m, struct ip6_hdr *);
sin6 = (struct sockaddr_in6 *)&local_store;
sin6->sin6_family = AF_INET6;
sin6->sin6_len = sizeof(*sin6);
sin6->sin6_port = sh->dest_port;
sin6->sin6_addr = ip6->ip6_dst;
break;
#endif
default:
return NULL;
}
phdr = sctp_get_next_param(m, offset + sizeof(struct sctp_asconf_chunk),
&parm_buf, sizeof(struct sctp_paramhdr));
if (phdr == NULL) {
@ -2417,7 +2301,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
}
if (zero_address) {
stcb = sctp_findassoc_by_vtag(NULL, to, ntohl(sh->v_tag), inp_p,
stcb = sctp_findassoc_by_vtag(NULL, dst, ntohl(sh->v_tag), inp_p,
netp, sh->src_port, sh->dest_port, 1, vrf_id, 0);
/*
* SCTP_PRINTF("findassociation_ep_asconf: zero lookup
@ -2426,7 +2310,7 @@ sctp_findassociation_ep_asconf(struct mbuf *m, int offset,
} else {
stcb = sctp_findassociation_ep_addr(inp_p,
(struct sockaddr *)&remote_store, netp,
to, NULL);
dst, NULL);
}
return (stcb);
}
@ -6079,7 +5963,8 @@ sctp_pcb_finish(void)
int
sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
int offset, int limit, struct sctphdr *sh,
int offset, int limit,
struct sockaddr *src, struct sockaddr *dst,
struct sockaddr *altsa)
{
/*
@ -6091,13 +5976,10 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
*/
struct sctp_inpcb *inp;
struct sctp_nets *net, *nnet, *net_tmp;
struct ip *iph;
struct sctp_paramhdr *phdr, parm_buf;
struct sctp_tcb *stcb_tmp;
uint16_t ptype, plen;
struct sockaddr *sa;
struct sockaddr_storage dest_store;
struct sockaddr *local_sa = (struct sockaddr *)&dest_store;
uint8_t random_store[SCTP_PARAM_BUFFER_SIZE];
struct sctp_auth_random *p_random = NULL;
uint16_t random_len = 0;
@ -6136,65 +6018,10 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_port = stcb->rport;
#endif
iph = mtod(m, struct ip *);
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
{
/* its IPv4 */
struct sockaddr_in *sin_2;
sin_2 = (struct sockaddr_in *)(local_sa);
memset(sin_2, 0, sizeof(sin));
sin_2->sin_family = AF_INET;
sin_2->sin_len = sizeof(sin);
sin_2->sin_port = sh->dest_port;
sin_2->sin_addr.s_addr = iph->ip_dst.s_addr;
if (altsa) {
/*
* For cookies we use the src address NOT
* from the packet but from the original
* INIT.
*/
sa = altsa;
} else {
sin.sin_addr = iph->ip_src;
sa = (struct sockaddr *)&sin;
}
break;
}
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
/* its IPv6 */
struct ip6_hdr *ip6;
struct sockaddr_in6 *sin6_2;
ip6 = mtod(m, struct ip6_hdr *);
sin6_2 = (struct sockaddr_in6 *)(local_sa);
memset(sin6_2, 0, sizeof(sin6));
sin6_2->sin6_family = AF_INET6;
sin6_2->sin6_len = sizeof(struct sockaddr_in6);
sin6_2->sin6_port = sh->dest_port;
sin6_2->sin6_addr = ip6->ip6_dst;
if (altsa) {
/*
* For cookies we use the src address NOT
* from the packet but from the original
* INIT.
*/
sa = altsa;
} else {
sin6.sin6_addr = ip6->ip6_src;
sa = (struct sockaddr *)&sin6;
}
break;
}
#endif
default:
return (-1);
break;
if (altsa) {
sa = altsa;
} else {
sa = src;
}
/* Turn off ECN until we get through all params */
ecn_allowed = 0;
@ -6205,7 +6032,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
/* does the source address already exist? if so skip it */
inp = stcb->sctp_ep;
atomic_add_int(&stcb->asoc.refcnt, 1);
stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, local_sa, stcb);
stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net_tmp, dst, stcb);
atomic_add_int(&stcb->asoc.refcnt, -1);
if ((stcb_tmp == NULL && inp == stcb->sctp_ep) || inp == NULL) {
@ -6295,7 +6122,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
inp = stcb->sctp_ep;
atomic_add_int(&stcb->asoc.refcnt, 1);
stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
local_sa, stcb);
dst, stcb);
atomic_add_int(&stcb->asoc.refcnt, -1);
if ((stcb_tmp == NULL && inp == stcb->sctp_ep) ||
@ -6385,7 +6212,7 @@ sctp_load_addresses_from_init(struct sctp_tcb *stcb, struct mbuf *m,
inp = stcb->sctp_ep;
atomic_add_int(&stcb->asoc.refcnt, 1);
stcb_tmp = sctp_findassociation_ep_addr(&inp, sa, &net,
local_sa, stcb);
dst, stcb);
atomic_add_int(&stcb->asoc.refcnt, -1);
if (stcb_tmp == NULL &&
(inp == stcb->sctp_ep || inp == NULL)) {

View file

@ -528,6 +528,7 @@ sctp_inpcb_bind(struct socket *, struct sockaddr *,
struct sctp_tcb *
sctp_findassociation_addr(struct mbuf *, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_chunkhdr *, struct sctp_inpcb **,
struct sctp_nets **, uint32_t vrf_id);
@ -558,7 +559,7 @@ sctp_findassociation_ep_asocid(struct sctp_inpcb *,
sctp_assoc_t, int);
struct sctp_tcb *
sctp_findassociation_ep_asconf(struct mbuf *, int,
sctp_findassociation_ep_asconf(struct mbuf *, int, struct sockaddr *,
struct sctphdr *, struct sctp_inpcb **, struct sctp_nets **, uint32_t vrf_id);
int sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id);
@ -603,8 +604,8 @@ void sctp_add_local_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
void sctp_del_local_addr_restricted(struct sctp_tcb *, struct sctp_ifa *);
int
sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int,
int, struct sctphdr *, struct sockaddr *);
sctp_load_addresses_from_init(struct sctp_tcb *, struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *, struct sockaddr *);
int
sctp_set_primary_addr(struct sctp_tcb *, struct sockaddr *,

View file

@ -345,8 +345,8 @@ sctp_ctlinput(cmd, sa, vip)
* 'from' holds our local endpoint address. Thus we reverse
* the to and the from in the lookup.
*/
stcb = sctp_findassociation_addr_sa((struct sockaddr *)&from,
(struct sockaddr *)&to,
stcb = sctp_findassociation_addr_sa((struct sockaddr *)&to,
(struct sockaddr *)&from,
&inp, &net, 1, vrf_id);
if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
if (cmd != PRC_MSGSIZE) {
@ -397,8 +397,8 @@ sctp_getcred(SYSCTL_HANDLER_ARGS)
if (error)
return (error);
stcb = sctp_findassociation_addr_sa(sintosa(&addrs[0]),
sintosa(&addrs[1]),
stcb = sctp_findassociation_addr_sa(sintosa(&addrs[1]),
sintosa(&addrs[0]),
&inp, &net, 1, vrf_id);
if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
if ((inp != NULL) && (stcb == NULL)) {

View file

@ -3823,8 +3823,9 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error
void
sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
struct mbuf *m, int iphlen, struct sctphdr *sh,
struct mbuf *op_err,
struct mbuf *m, int iphlen,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct mbuf *op_err,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
@ -3844,7 +3845,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
vrf_id = stcb->asoc.vrf_id;
stcb->asoc.state |= SCTP_STATE_WAS_ABORTED;
}
sctp_send_abort(m, iphlen, sh, vtag, op_err,
sctp_send_abort(m, iphlen, src, dst, sh, vtag, op_err,
use_mflowid, mflowid,
vrf_id, port);
if (stcb != NULL) {
@ -3995,8 +3996,9 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
}
void
sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
struct sctp_inpcb *inp,
sctp_handle_ootb(struct mbuf *m, int iphlen, int offset,
struct sockaddr *src, struct sockaddr *dst,
struct sctphdr *sh, struct sctp_inpcb *inp,
uint8_t use_mflowid, uint32_t mflowid,
uint32_t vrf_id, uint16_t port)
{
@ -4041,7 +4043,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
*/
return;
case SCTP_SHUTDOWN_ACK:
sctp_send_shutdown_complete2(m, sh,
sctp_send_shutdown_complete2(src, dst, sh,
use_mflowid, mflowid,
vrf_id, port);
return;
@ -4055,7 +4057,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
(contains_init_chunk == 0))) {
sctp_send_abort(m, iphlen, sh, 0, NULL,
sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
use_mflowid, mflowid,
vrf_id, port);
}
@ -4247,62 +4249,6 @@ sctp_print_address(struct sockaddr *sa)
}
}
void
sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
{
switch (iph->ip_v) {
#ifdef INET
case IPVERSION:
{
struct sockaddr_in lsa, fsa;
bzero(&lsa, sizeof(lsa));
lsa.sin_len = sizeof(lsa);
lsa.sin_family = AF_INET;
lsa.sin_addr = iph->ip_src;
lsa.sin_port = sh->src_port;
bzero(&fsa, sizeof(fsa));
fsa.sin_len = sizeof(fsa);
fsa.sin_family = AF_INET;
fsa.sin_addr = iph->ip_dst;
fsa.sin_port = sh->dest_port;
SCTP_PRINTF("src: ");
sctp_print_address((struct sockaddr *)&lsa);
SCTP_PRINTF("dest: ");
sctp_print_address((struct sockaddr *)&fsa);
break;
}
#endif
#ifdef INET6
case IPV6_VERSION >> 4:
{
struct ip6_hdr *ip6;
struct sockaddr_in6 lsa6, fsa6;
ip6 = (struct ip6_hdr *)iph;
bzero(&lsa6, sizeof(lsa6));
lsa6.sin6_len = sizeof(lsa6);
lsa6.sin6_family = AF_INET6;
lsa6.sin6_addr = ip6->ip6_src;
lsa6.sin6_port = sh->src_port;
bzero(&fsa6, sizeof(fsa6));
fsa6.sin6_len = sizeof(fsa6);
fsa6.sin6_family = AF_INET6;
fsa6.sin6_addr = ip6->ip6_dst;
fsa6.sin6_port = sh->dest_port;
SCTP_PRINTF("src: ");
sctp_print_address((struct sockaddr *)&lsa6);
SCTP_PRINTF("dest: ");
sctp_print_address((struct sockaddr *)&fsa6);
break;
}
#endif
default:
/* TSNH */
break;
}
}
void
sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
struct sctp_inpcb *new_inp,

View file

@ -186,7 +186,8 @@ sctp_abort_notification(struct sctp_tcb *, uint8_t, uint16_t,
/* We abort responding to an IP packet for some reason */
void
sctp_abort_association(struct sctp_inpcb *, struct sctp_tcb *, struct mbuf *,
int, struct sctphdr *, struct mbuf *,
int, struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct mbuf *,
uint8_t, uint32_t,
uint32_t, uint16_t);
@ -201,8 +202,9 @@ sctp_abort_an_association(struct sctp_inpcb *, struct sctp_tcb *,
);
void
sctp_handle_ootb(struct mbuf *, int, int, struct sctphdr *,
struct sctp_inpcb *,
sctp_handle_ootb(struct mbuf *, int, int,
struct sockaddr *, struct sockaddr *,
struct sctphdr *, struct sctp_inpcb *,
uint8_t, uint32_t,
uint32_t, uint16_t);
@ -241,7 +243,6 @@ struct sockaddr_in6 *
int sctp_cmpaddr(struct sockaddr *, struct sockaddr *);
void sctp_print_address(struct sockaddr *);
void sctp_print_address_pkt(struct ip *, struct sctphdr *);
int
sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,

View file

@ -71,6 +71,7 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
int iphlen;
uint32_t vrf_id = 0;
uint8_t ecn_bits;
struct sockaddr_in6 src, dst;
struct ip6_hdr *ip6;
struct sctphdr *sh;
struct sctp_chunkhdr *ch;
@ -131,7 +132,23 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
}
ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
offset -= sizeof(struct sctp_chunkhdr);
if (faithprefix_p != NULL && (*faithprefix_p) (&ip6->ip6_dst)) {
memset(&src, 0, sizeof(struct sockaddr_in6));
src.sin6_family = AF_INET6;
src.sin6_len = sizeof(struct sockaddr_in6);
src.sin6_port = sh->src_port;
src.sin6_addr = ip6->ip6_src;
if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
goto bad;
}
memset(&dst, 0, sizeof(struct sockaddr_in6));
dst.sin6_family = AF_INET6;
dst.sin6_len = sizeof(struct sockaddr_in6);
dst.sin6_port = sh->dest_port;
dst.sin6_addr = ip6->ip6_dst;
if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) {
goto bad;
}
if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) {
/* XXX send icmp6 host/port unreach? */
goto bad;
}
@ -169,6 +186,8 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
SCTPDBG(SCTP_DEBUG_INPUT1, "Bad CSUM on SCTP packet calc_check:%x check:%x m:%p mlen:%d iphlen:%d\n",
calc_check, check, m, length, iphlen);
stcb = sctp_findassociation_addr(m, offset,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch, &inp, &net, vrf_id);
if ((net) && (port)) {
if (net->port == 0) {
@ -200,6 +219,8 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
goto bad;
}
stcb = sctp_findassociation_addr(m, offset,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch, &inp, &net, vrf_id);
if ((net) && (port)) {
if (net->port == 0) {
@ -218,7 +239,9 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
if (badport_bandlim(BANDLIM_SCTP_OOTB) < 0)
goto bad;
if (ch->chunk_type == SCTP_SHUTDOWN_ACK) {
sctp_send_shutdown_complete2(m, sh,
sctp_send_shutdown_complete2((struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh,
use_mflowid, mflowid,
vrf_id, port);
goto bad;
@ -230,7 +253,10 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
(ch->chunk_type != SCTP_INIT))) {
sctp_send_abort(m, iphlen, sh, 0, NULL,
sctp_send_abort(m, iphlen,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, 0, NULL,
use_mflowid, mflowid,
vrf_id, port);
}
@ -253,8 +279,10 @@ sctp6_input(struct mbuf **i_pak, int *offp, int proto)
ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff);
/* sa_ignore NO_NULL_CHK */
sctp_common_input_processing(&m, iphlen, offset, length, sh, ch,
inp, stcb, net, ecn_bits,
sctp_common_input_processing(&m, iphlen, offset, length,
(struct sockaddr *)&src,
(struct sockaddr *)&dst,
sh, ch, inp, stcb, net, ecn_bits,
use_mflowid, mflowid,
vrf_id, port);
if (m) {
@ -497,8 +525,8 @@ sctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d)
final.sin6_family = AF_INET6;
final.sin6_addr = ((struct sockaddr_in6 *)pktdst)->sin6_addr;
final.sin6_port = sh.dest_port;
stcb = sctp_findassociation_addr_sa((struct sockaddr *)ip6cp->ip6c_src,
(struct sockaddr *)&final,
stcb = sctp_findassociation_addr_sa((struct sockaddr *)&final,
(struct sockaddr *)ip6cp->ip6c_src,
&inp, &net, 1, vrf_id);
/* inp's ref-count increased && stcb locked */
if (stcb != NULL && inp && (inp->sctp_socket != NULL)) {
@ -565,8 +593,8 @@ sctp6_getcred(SYSCTL_HANDLER_ARGS)
if (error)
return (error);
stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[0]),
sin6tosa(&addrs[1]),
stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[1]),
sin6tosa(&addrs[0]),
&inp, &net, 1, vrf_id);
if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) {
if ((inp != NULL) && (stcb == NULL)) {