Pass the src and dst address of a received packet explicitly around.
MFC after: 3 days
This commit is contained in:
parent
db0cb5be21
commit
b1754ad17b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=237715
@ -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 */
|
||||
|
@ -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 *,
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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, ¬ification,
|
||||
*stcb = sctp_process_cookie_new(m, iphlen, offset, src, dst, sh,
|
||||
cookie, cookie_len, *inp_p,
|
||||
netp, to, ¬ification,
|
||||
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,
|
||||
¬ification, 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);
|
||||
|
@ -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,
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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 *,
|
||||
|
@ -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)) {
|
||||
|
@ -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,
|
||||
|
@ -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 *,
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user