diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c index e37c522c9695..1a1aa96dd3a5 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 @@ 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 */ diff --git a/sys/netinet/sctp_asconf.h b/sys/netinet/sctp_asconf.h index 1535f1fc0464..183c99b4b982 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 581422e02ffb..449c825cee6d 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -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); diff --git a/sys/netinet/sctp_indata.h b/sys/netinet/sctp_indata.h index 9cb4d8ad30ac..5eaa1f4ba412 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 3e6f312baa2b..e321fa81c7ae 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, ¬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); diff --git a/sys/netinet/sctp_input.h b/sys/netinet/sctp_input.h index aff39de57843..0f0f8d5e0c4b 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 861c76e91437..9cb77b688c25 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 5d3a4a31f5ed..e8a8cfc8b38b 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -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; diff --git a/sys/netinet/sctp_output.h b/sys/netinet/sctp_output.h index b191260e6aea..b91d476cc9f7 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 22bdb667dbf5..e9d99ed69d12 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 68b87ab92bd0..e41665818f9c 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 9929424ba3f0..dc01f2dbb466 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 23a1c3aa407b..c89eb82f022a 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); } @@ -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, diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h index 8c4d0a6b00db..3ced6c5c8f37 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 82b3faf17045..f48b75aff54b 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 @@ 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)) {