summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/netinet/sctp_asconf.c95
-rw-r--r--sys/netinet/sctp_asconf.h4
-rw-r--r--sys/netinet/sctp_indata.c6
-rw-r--r--sys/netinet/sctp_indata.h4
-rw-r--r--sys/netinet/sctp_input.c234
-rw-r--r--sys/netinet/sctp_input.h1
-rw-r--r--sys/netinet/sctp_os_bsd.h13
-rw-r--r--sys/netinet/sctp_output.c269
-rw-r--r--sys/netinet/sctp_output.h15
-rw-r--r--sys/netinet/sctp_pcb.c219
-rw-r--r--sys/netinet/sctp_pcb.h7
-rw-r--r--sys/netinet/sctp_usrreq.c8
-rw-r--r--sys/netinet/sctputil.c72
-rw-r--r--sys/netinet/sctputil.h9
-rw-r--r--sys/netinet6/sctp6_usrreq.c46
15 files changed, 329 insertions, 673 deletions
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index e37c522..1a1aa96 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -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 @@ send_reply:
* 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 */
diff --git a/sys/netinet/sctp_asconf.h b/sys/netinet/sctp_asconf.h
index 1535f1f..183c99b 100644
--- a/sys/netinet/sctp_asconf.h
+++ b/sys/netinet/sctp_asconf.h
@@ -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 *,
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 581422e..449c825 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -2516,6 +2516,7 @@ doit_again:
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);
diff --git a/sys/netinet/sctp_indata.h b/sys/netinet/sctp_indata.h
index 9cb4d8a..5eaa1f4 100644
--- a/sys/netinet/sctp_indata.h
+++ b/sys/netinet/sctp_indata.h
@@ -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,
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 3e6f312..e321fa8 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -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 @@ process_control_chunks:
/* 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 @@ process_control_chunks:
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 @@ process_control_chunks:
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 @@ process_control_chunks:
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 @@ process_control_chunks:
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 @@ process_control_chunks:
__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_skip_csum:
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_skip_csum:
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_skip_csum:
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_skip_csum:
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);
diff --git a/sys/netinet/sctp_input.h b/sys/netinet/sctp_input.h
index aff39de..0f0f8d5 100644
--- a/sys/netinet/sctp_input.h
+++ b/sys/netinet/sctp_input.h
@@ -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,
diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h
index 861c76e..9cb77b6 100644
--- a/sys/netinet/sctp_os_bsd.h
+++ b/sys/netinet/sctp_os_bsd.h
@@ -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)));
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 5d3a4a3..e8a8cfc 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -5189,7 +5189,7 @@ invalid_size:
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 @@ do_a_abort:
#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 @@ do_a_abort:
/* 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 @@ do_a_abort:
}
#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 @@ do_a_abort:
* 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 @@ do_a_abort:
*/
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 @@ do_a_abort:
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 @@ do_a_abort:
}
}
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 @@ skip_stuff:
}
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;
diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h
index b191260..b91d476 100644
--- a/sys/netinet/sctp_output.h
+++ b/sys/netinet/sctp_output.h
@@ -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);
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 22bdb66..e9d99ed 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -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)) {
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index 68b87ab..e416658 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -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 *,
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index 9929424..dc01f2d 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -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)) {
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 23a1c3a..c89eb82 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -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);
}
@@ -4248,62 +4250,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,
struct sctp_tcb *stcb,
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index 8c4d0a6..3ced6c5 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -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 *,
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 82b3faf..f48b75af 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -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 @@ sctp_skip_csum:
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 @@ sctp_skip_csum:
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 @@ sctp_skip_csum:
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 @@ sctp_skip_csum:
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)) {
OpenPOWER on IntegriCloud