Deleted Added
full compact
sctp6_usrreq.c (228653) sctp6_usrreq.c (228907)
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *

--- 18 unchanged lines hidden (view full) ---

27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32/* $KAME: sctp6_usrreq.c,v 1.38 2005/08/24 08:08:56 suz Exp $ */
33
34#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
3 * Copyright (c) 2008-2011, by Randall Stewart. All rights reserved.
4 * Copyright (c) 2008-2011, by Michael Tuexen. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *

--- 18 unchanged lines hidden (view full) ---

27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
31 */
32/* $KAME: sctp6_usrreq.c,v 1.38 2005/08/24 08:08:56 suz Exp $ */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 228653 2011-12-17 19:21:40Z tuexen $");
35__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 228907 2011-12-27 10:16:24Z tuexen $");
36
37#include <netinet/sctp_os.h>
38#include <sys/proc.h>
39#include <netinet/sctp_pcb.h>
40#include <netinet/sctp_header.h>
41#include <netinet/sctp_var.h>
42#if defined(INET6)
43#include <netinet6/sctp6_var.h>

--- 61 unchanged lines hidden (view full) ---

105 sctp_packet_log(m, pkt_len);
106#endif
107 ip6 = mtod(m, struct ip6_hdr *);
108 /* Ensure that (sctphdr + sctp_chunkhdr) in a row. */
109 IP6_EXTHDR_GET(sh, struct sctphdr *, m, off,
110 (int)(sizeof(*sh) + sizeof(*ch)));
111 if (sh == NULL) {
112 SCTP_STAT_INCR(sctps_hdrops);
36
37#include <netinet/sctp_os.h>
38#include <sys/proc.h>
39#include <netinet/sctp_pcb.h>
40#include <netinet/sctp_header.h>
41#include <netinet/sctp_var.h>
42#if defined(INET6)
43#include <netinet6/sctp6_var.h>

--- 61 unchanged lines hidden (view full) ---

105 sctp_packet_log(m, pkt_len);
106#endif
107 ip6 = mtod(m, struct ip6_hdr *);
108 /* Ensure that (sctphdr + sctp_chunkhdr) in a row. */
109 IP6_EXTHDR_GET(sh, struct sctphdr *, m, off,
110 (int)(sizeof(*sh) + sizeof(*ch)));
111 if (sh == NULL) {
112 SCTP_STAT_INCR(sctps_hdrops);
113 return IPPROTO_DONE;
113 return (IPPROTO_DONE);
114 }
115 ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
116 iphlen = off;
117 offset = iphlen + sizeof(*sh) + sizeof(*ch);
118 SCTPDBG(SCTP_DEBUG_INPUT1,
119 "sctp6_input() length:%d iphlen:%d\n", pkt_len, iphlen);
120
121

--- 149 unchanged lines hidden (view full) ---

271 if (m)
272 sctp_m_freem(m);
273 if ((in6p) && refcount_up) {
274 /* reduce ref-count */
275 SCTP_INP_WLOCK(in6p);
276 SCTP_INP_DECR_REF(in6p);
277 SCTP_INP_WUNLOCK(in6p);
278 }
114 }
115 ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr));
116 iphlen = off;
117 offset = iphlen + sizeof(*sh) + sizeof(*ch);
118 SCTPDBG(SCTP_DEBUG_INPUT1,
119 "sctp6_input() length:%d iphlen:%d\n", pkt_len, iphlen);
120
121

--- 149 unchanged lines hidden (view full) ---

271 if (m)
272 sctp_m_freem(m);
273 if ((in6p) && refcount_up) {
274 /* reduce ref-count */
275 SCTP_INP_WLOCK(in6p);
276 SCTP_INP_DECR_REF(in6p);
277 SCTP_INP_WUNLOCK(in6p);
278 }
279 return IPPROTO_DONE;
279 return (IPPROTO_DONE);
280
281bad:
282 if (stcb) {
283 SCTP_TCB_UNLOCK(stcb);
284 }
285 if ((in6p) && refcount_up) {
286 /* reduce ref-count */
287 SCTP_INP_WLOCK(in6p);
288 SCTP_INP_DECR_REF(in6p);
289 SCTP_INP_WUNLOCK(in6p);
290 }
291 if (m)
292 sctp_m_freem(m);
280
281bad:
282 if (stcb) {
283 SCTP_TCB_UNLOCK(stcb);
284 }
285 if ((in6p) && refcount_up) {
286 /* reduce ref-count */
287 SCTP_INP_WLOCK(in6p);
288 SCTP_INP_DECR_REF(in6p);
289 SCTP_INP_WUNLOCK(in6p);
290 }
291 if (m)
292 sctp_m_freem(m);
293 return IPPROTO_DONE;
293 return (IPPROTO_DONE);
294}
295
296
297static void
298sctp6_notify_mbuf(struct sctp_inpcb *inp, struct icmp6_hdr *icmp6,
299 struct sctphdr *sh, struct sctp_tcb *stcb, struct sctp_nets *net)
300{
301 uint32_t nxtsz;

--- 366 unchanged lines hidden (view full) ---

668 struct in6pcb *inp6;
669 int error;
670 struct sctp_inpcb *inp;
671 uint32_t vrf_id = SCTP_DEFAULT_VRFID;
672
673 inp = (struct sctp_inpcb *)so->so_pcb;
674 if (inp != NULL) {
675 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
294}
295
296
297static void
298sctp6_notify_mbuf(struct sctp_inpcb *inp, struct icmp6_hdr *icmp6,
299 struct sctphdr *sh, struct sctp_tcb *stcb, struct sctp_nets *net)
300{
301 uint32_t nxtsz;

--- 366 unchanged lines hidden (view full) ---

668 struct in6pcb *inp6;
669 int error;
670 struct sctp_inpcb *inp;
671 uint32_t vrf_id = SCTP_DEFAULT_VRFID;
672
673 inp = (struct sctp_inpcb *)so->so_pcb;
674 if (inp != NULL) {
675 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
676 return EINVAL;
676 return (EINVAL);
677 }
678 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
679 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
680 if (error)
677 }
678 if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
679 error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace));
680 if (error)
681 return error;
681 return (error);
682 }
683 error = sctp_inpcb_alloc(so, vrf_id);
684 if (error)
682 }
683 error = sctp_inpcb_alloc(so, vrf_id);
684 if (error)
685 return error;
685 return (error);
686 inp = (struct sctp_inpcb *)so->so_pcb;
687 SCTP_INP_WLOCK(inp);
688 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */
689 inp6 = (struct in6pcb *)inp;
690
691 inp6->inp_vflag |= INP_IPV6;
692 inp6->in6p_hops = -1; /* use kernel default */
693 inp6->in6p_cksum = -1; /* just to be sure */

--- 5 unchanged lines hidden (view full) ---

699 */
700 inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
701#endif
702 /*
703 * Hmm what about the IPSEC stuff that is missing here but in
704 * sctp_attach()?
705 */
706 SCTP_INP_WUNLOCK(inp);
686 inp = (struct sctp_inpcb *)so->so_pcb;
687 SCTP_INP_WLOCK(inp);
688 inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */
689 inp6 = (struct in6pcb *)inp;
690
691 inp6->inp_vflag |= INP_IPV6;
692 inp6->in6p_hops = -1; /* use kernel default */
693 inp6->in6p_cksum = -1; /* just to be sure */

--- 5 unchanged lines hidden (view full) ---

699 */
700 inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
701#endif
702 /*
703 * Hmm what about the IPSEC stuff that is missing here but in
704 * sctp_attach()?
705 */
706 SCTP_INP_WUNLOCK(inp);
707 return 0;
707 return (0);
708}
709
710static int
711sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
712{
713 struct sctp_inpcb *inp;
714 struct in6pcb *inp6;
715 int error;
716
717 inp = (struct sctp_inpcb *)so->so_pcb;
718 if (inp == 0) {
719 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
708}
709
710static int
711sctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p)
712{
713 struct sctp_inpcb *inp;
714 struct in6pcb *inp6;
715 int error;
716
717 inp = (struct sctp_inpcb *)so->so_pcb;
718 if (inp == 0) {
719 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
720 return EINVAL;
720 return (EINVAL);
721 }
722 if (addr) {
723 switch (addr->sa_family) {
724#ifdef INET
725 case AF_INET:
726 if (addr->sa_len != sizeof(struct sockaddr_in)) {
727 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
721 }
722 if (addr) {
723 switch (addr->sa_family) {
724#ifdef INET
725 case AF_INET:
726 if (addr->sa_len != sizeof(struct sockaddr_in)) {
727 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
728 return EINVAL;
728 return (EINVAL);
729 }
730 break;
731#endif
732#ifdef INET6
733 case AF_INET6:
734 if (addr->sa_len != sizeof(struct sockaddr_in6)) {
735 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
729 }
730 break;
731#endif
732#ifdef INET6
733 case AF_INET6:
734 if (addr->sa_len != sizeof(struct sockaddr_in6)) {
735 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
736 return EINVAL;
736 return (EINVAL);
737 }
738 break;
739#endif
740 default:
741 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
737 }
738 break;
739#endif
740 default:
741 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
742 return EINVAL;
742 return (EINVAL);
743 }
744 }
745 inp6 = (struct in6pcb *)inp;
746 inp6->inp_vflag &= ~INP_IPV4;
747 inp6->inp_vflag |= INP_IPV6;
748 if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp6) == 0)) {
749 switch (addr->sa_family) {
750#ifdef INET

--- 16 unchanged lines hidden (view full) ---

767#ifdef INET
768 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
769 struct sockaddr_in sin;
770
771 in6_sin6_2_sin(&sin, sin6_p);
772 inp6->inp_vflag |= INP_IPV4;
773 inp6->inp_vflag &= ~INP_IPV6;
774 error = sctp_inpcb_bind(so, (struct sockaddr *)&sin, NULL, p);
743 }
744 }
745 inp6 = (struct in6pcb *)inp;
746 inp6->inp_vflag &= ~INP_IPV4;
747 inp6->inp_vflag |= INP_IPV6;
748 if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp6) == 0)) {
749 switch (addr->sa_family) {
750#ifdef INET

--- 16 unchanged lines hidden (view full) ---

767#ifdef INET
768 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
769 struct sockaddr_in sin;
770
771 in6_sin6_2_sin(&sin, sin6_p);
772 inp6->inp_vflag |= INP_IPV4;
773 inp6->inp_vflag &= ~INP_IPV6;
774 error = sctp_inpcb_bind(so, (struct sockaddr *)&sin, NULL, p);
775 return error;
775 return (error);
776 }
777#endif
778 break;
779 }
780#endif
781 default:
782 break;
783 }
784 } else if (addr != NULL) {
785 struct sockaddr_in6 *sin6_p;
786
787 /* IPV6_V6ONLY socket */
788#ifdef INET
789 if (addr->sa_family == AF_INET) {
790 /* can't bind v4 addr to v6 only socket! */
791 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
776 }
777#endif
778 break;
779 }
780#endif
781 default:
782 break;
783 }
784 } else if (addr != NULL) {
785 struct sockaddr_in6 *sin6_p;
786
787 /* IPV6_V6ONLY socket */
788#ifdef INET
789 if (addr->sa_family == AF_INET) {
790 /* can't bind v4 addr to v6 only socket! */
791 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
792 return EINVAL;
792 return (EINVAL);
793 }
794#endif
795 sin6_p = (struct sockaddr_in6 *)addr;
796
797 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
798 /* can't bind v4-mapped addrs either! */
799 /* NOTE: we don't support SIIT */
800 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
793 }
794#endif
795 sin6_p = (struct sockaddr_in6 *)addr;
796
797 if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
798 /* can't bind v4-mapped addrs either! */
799 /* NOTE: we don't support SIIT */
800 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
801 return EINVAL;
801 return (EINVAL);
802 }
803 }
804 error = sctp_inpcb_bind(so, addr, NULL, p);
802 }
803 }
804 error = sctp_inpcb_bind(so, addr, NULL, p);
805 return error;
805 return (error);
806}
807
808
809static void
810sctp6_close(struct socket *so)
811{
812 sctp_close(so);
813}

--- 29 unchanged lines hidden (view full) ---

843 inp = (struct sctp_inpcb *)so->so_pcb;
844 if (inp == NULL) {
845 if (control) {
846 SCTP_RELEASE_PKT(control);
847 control = NULL;
848 }
849 SCTP_RELEASE_PKT(m);
850 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
806}
807
808
809static void
810sctp6_close(struct socket *so)
811{
812 sctp_close(so);
813}

--- 29 unchanged lines hidden (view full) ---

843 inp = (struct sctp_inpcb *)so->so_pcb;
844 if (inp == NULL) {
845 if (control) {
846 SCTP_RELEASE_PKT(control);
847 control = NULL;
848 }
849 SCTP_RELEASE_PKT(m);
850 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
851 return EINVAL;
851 return (EINVAL);
852 }
853 inp6 = (struct in6pcb *)inp;
854 /*
855 * For the TCP model we may get a NULL addr, if we are a connected
856 * socket thats ok.
857 */
858 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
859 (addr == NULL)) {

--- 12 unchanged lines hidden (view full) ---

872 sin6 = (struct sockaddr_in6 *)addr;
873 if (SCTP_IPV6_V6ONLY(inp6)) {
874 /*
875 * if IPV6_V6ONLY flag, we discard datagrams destined to a
876 * v4 addr or v4-mapped addr
877 */
878 if (addr->sa_family == AF_INET) {
879 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
852 }
853 inp6 = (struct in6pcb *)inp;
854 /*
855 * For the TCP model we may get a NULL addr, if we are a connected
856 * socket thats ok.
857 */
858 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) &&
859 (addr == NULL)) {

--- 12 unchanged lines hidden (view full) ---

872 sin6 = (struct sockaddr_in6 *)addr;
873 if (SCTP_IPV6_V6ONLY(inp6)) {
874 /*
875 * if IPV6_V6ONLY flag, we discard datagrams destined to a
876 * v4 addr or v4-mapped addr
877 */
878 if (addr->sa_family == AF_INET) {
879 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
880 return EINVAL;
880 return (EINVAL);
881 }
882 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
883 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
881 }
882 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
883 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
884 return EINVAL;
884 return (EINVAL);
885 }
886 }
887 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
888 if (!MODULE_GLOBAL(ip6_v6only)) {
889 struct sockaddr_in sin;
890
891 /* convert v4-mapped into v4 addr and send */
892 in6_sin6_2_sin(&sin, sin6);
885 }
886 }
887 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
888 if (!MODULE_GLOBAL(ip6_v6only)) {
889 struct sockaddr_in sin;
890
891 /* convert v4-mapped into v4 addr and send */
892 in6_sin6_2_sin(&sin, sin6);
893 return sctp_sendm(so, flags, m, (struct sockaddr *)&sin,
894 control, p);
893 return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin,
894 control, p));
895 } else {
896 /* mapped addresses aren't enabled */
897 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
895 } else {
896 /* mapped addresses aren't enabled */
897 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
898 return EINVAL;
898 return (EINVAL);
899 }
900 }
901#endif /* INET */
902connected_type:
903 /* now what about control */
904 if (control) {
905 if (inp->control) {
906 SCTP_PRINTF("huh? control set?\n");

--- 108 unchanged lines hidden (view full) ---

1015 /*
1016 * if IPV6_V6ONLY flag, ignore connections destined to a v4
1017 * addr or v4-mapped addr
1018 */
1019 if (addr->sa_family == AF_INET) {
1020 SCTP_INP_RUNLOCK(inp);
1021 SCTP_ASOC_CREATE_UNLOCK(inp);
1022 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
899 }
900 }
901#endif /* INET */
902connected_type:
903 /* now what about control */
904 if (control) {
905 if (inp->control) {
906 SCTP_PRINTF("huh? control set?\n");

--- 108 unchanged lines hidden (view full) ---

1015 /*
1016 * if IPV6_V6ONLY flag, ignore connections destined to a v4
1017 * addr or v4-mapped addr
1018 */
1019 if (addr->sa_family == AF_INET) {
1020 SCTP_INP_RUNLOCK(inp);
1021 SCTP_ASOC_CREATE_UNLOCK(inp);
1022 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1023 return EINVAL;
1023 return (EINVAL);
1024 }
1025 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1026 SCTP_INP_RUNLOCK(inp);
1027 SCTP_ASOC_CREATE_UNLOCK(inp);
1028 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1024 }
1025 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1026 SCTP_INP_RUNLOCK(inp);
1027 SCTP_ASOC_CREATE_UNLOCK(inp);
1028 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1029 return EINVAL;
1029 return (EINVAL);
1030 }
1031 }
1032 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1033 if (!MODULE_GLOBAL(ip6_v6only)) {
1034 /* convert v4-mapped into v4 addr */
1035 in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
1036 addr = (struct sockaddr *)&ss;
1037 } else {
1038 /* mapped addresses aren't enabled */
1039 SCTP_INP_RUNLOCK(inp);
1040 SCTP_ASOC_CREATE_UNLOCK(inp);
1041 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1030 }
1031 }
1032 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
1033 if (!MODULE_GLOBAL(ip6_v6only)) {
1034 /* convert v4-mapped into v4 addr */
1035 in6_sin6_2_sin((struct sockaddr_in *)&ss, sin6);
1036 addr = (struct sockaddr *)&ss;
1037 } else {
1038 /* mapped addresses aren't enabled */
1039 SCTP_INP_RUNLOCK(inp);
1040 SCTP_ASOC_CREATE_UNLOCK(inp);
1041 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1042 return EINVAL;
1042 return (EINVAL);
1043 }
1044 }
1045#endif /* INET */
1046 /* Now do we connect? */
1047 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1048 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1049 if (stcb) {
1050 SCTP_TCB_UNLOCK(stcb);

--- 34 unchanged lines hidden (view full) ---

1085 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
1086 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1087
1088 /* initialize authentication parameters for the assoc */
1089 sctp_initialize_auth_params(inp, stcb);
1090
1091 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
1092 SCTP_TCB_UNLOCK(stcb);
1043 }
1044 }
1045#endif /* INET */
1046 /* Now do we connect? */
1047 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1048 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1049 if (stcb) {
1050 SCTP_TCB_UNLOCK(stcb);

--- 34 unchanged lines hidden (view full) ---

1085 stcb->asoc.state = SCTP_STATE_COOKIE_WAIT;
1086 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
1087
1088 /* initialize authentication parameters for the assoc */
1089 sctp_initialize_auth_params(inp, stcb);
1090
1091 sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
1092 SCTP_TCB_UNLOCK(stcb);
1093 return error;
1093 return (error);
1094}
1095
1096static int
1097sctp6_getaddr(struct socket *so, struct sockaddr **addr)
1098{
1099 struct sockaddr_in6 *sin6;
1100 struct sctp_inpcb *inp;
1101 uint32_t vrf_id;
1102 struct sctp_ifa *sctp_ifa;
1103
1104 int error;
1105
1106 /*
1107 * Do the malloc first in case it blocks.
1108 */
1109 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6));
1110 if (sin6 == NULL)
1094}
1095
1096static int
1097sctp6_getaddr(struct socket *so, struct sockaddr **addr)
1098{
1099 struct sockaddr_in6 *sin6;
1100 struct sctp_inpcb *inp;
1101 uint32_t vrf_id;
1102 struct sctp_ifa *sctp_ifa;
1103
1104 int error;
1105
1106 /*
1107 * Do the malloc first in case it blocks.
1108 */
1109 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6));
1110 if (sin6 == NULL)
1111 return ENOMEM;
1111 return (ENOMEM);
1112 sin6->sin6_family = AF_INET6;
1113 sin6->sin6_len = sizeof(*sin6);
1114
1115 inp = (struct sctp_inpcb *)so->so_pcb;
1116 if (inp == NULL) {
1117 SCTP_FREE_SONAME(sin6);
1118 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
1112 sin6->sin6_family = AF_INET6;
1113 sin6->sin6_len = sizeof(*sin6);
1114
1115 inp = (struct sctp_inpcb *)so->so_pcb;
1116 if (inp == NULL) {
1117 SCTP_FREE_SONAME(sin6);
1118 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
1119 return ECONNRESET;
1119 return (ECONNRESET);
1120 }
1121 SCTP_INP_RLOCK(inp);
1122 sin6->sin6_port = inp->sctp_lport;
1123 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1124 /* For the bound all case you get back 0 */
1125 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1126 struct sctp_tcb *stcb;
1127 struct sockaddr_in6 *sin_a6;

--- 45 unchanged lines hidden (view full) ---

1173 fnd = 1;
1174 break;
1175 }
1176 }
1177 if (!fnd) {
1178 SCTP_FREE_SONAME(sin6);
1179 SCTP_INP_RUNLOCK(inp);
1180 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
1120 }
1121 SCTP_INP_RLOCK(inp);
1122 sin6->sin6_port = inp->sctp_lport;
1123 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
1124 /* For the bound all case you get back 0 */
1125 if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {
1126 struct sctp_tcb *stcb;
1127 struct sockaddr_in6 *sin_a6;

--- 45 unchanged lines hidden (view full) ---

1173 fnd = 1;
1174 break;
1175 }
1176 }
1177 if (!fnd) {
1178 SCTP_FREE_SONAME(sin6);
1179 SCTP_INP_RUNLOCK(inp);
1180 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
1181 return ENOENT;
1181 return (ENOENT);
1182 }
1183 }
1184 SCTP_INP_RUNLOCK(inp);
1185 /* Scoping things for v6 */
1186 if ((error = sa6_recoverscope(sin6)) != 0) {
1187 SCTP_FREE_SONAME(sin6);
1188 return (error);
1189 }

--- 5 unchanged lines hidden (view full) ---

1195sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
1196{
1197 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)*addr;
1198 int fnd;
1199 struct sockaddr_in6 *sin_a6;
1200 struct sctp_inpcb *inp;
1201 struct sctp_tcb *stcb;
1202 struct sctp_nets *net;
1182 }
1183 }
1184 SCTP_INP_RUNLOCK(inp);
1185 /* Scoping things for v6 */
1186 if ((error = sa6_recoverscope(sin6)) != 0) {
1187 SCTP_FREE_SONAME(sin6);
1188 return (error);
1189 }

--- 5 unchanged lines hidden (view full) ---

1195sctp6_peeraddr(struct socket *so, struct sockaddr **addr)
1196{
1197 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)*addr;
1198 int fnd;
1199 struct sockaddr_in6 *sin_a6;
1200 struct sctp_inpcb *inp;
1201 struct sctp_tcb *stcb;
1202 struct sctp_nets *net;
1203
1204 int error;
1205
1203 int error;
1204
1206 /*
1207 * Do the malloc first in case it blocks.
1208 */
1209 inp = (struct sctp_inpcb *)so->so_pcb;
1210 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) {
1211 /* UDP type and listeners will drop out here */
1212 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOTCONN);
1213 return (ENOTCONN);
1214 }
1205 /* Do the malloc first in case it blocks. */
1215 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
1216 if (sin6 == NULL)
1217 return (ENOMEM);
1218 sin6->sin6_family = AF_INET6;
1219 sin6->sin6_len = sizeof(*sin6);
1220
1206 SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6);
1207 if (sin6 == NULL)
1208 return (ENOMEM);
1209 sin6->sin6_family = AF_INET6;
1210 sin6->sin6_len = sizeof(*sin6);
1211
1221 /* We must recapture incase we blocked */
1222 inp = (struct sctp_inpcb *)so->so_pcb;
1212 inp = (struct sctp_inpcb *)so->so_pcb;
1223 if (inp == NULL) {
1213 if ((inp == NULL) ||
1214 ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) {
1215 /* UDP type and listeners will drop out here */
1224 SCTP_FREE_SONAME(sin6);
1216 SCTP_FREE_SONAME(sin6);
1225 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
1226 return ECONNRESET;
1217 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOTCONN);
1218 return (ENOTCONN);
1227 }
1228 SCTP_INP_RLOCK(inp);
1229 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1230 if (stcb) {
1231 SCTP_TCB_LOCK(stcb);
1232 }
1233 SCTP_INP_RUNLOCK(inp);
1234 if (stcb == NULL) {
1235 SCTP_FREE_SONAME(sin6);
1236 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
1219 }
1220 SCTP_INP_RLOCK(inp);
1221 stcb = LIST_FIRST(&inp->sctp_asoc_list);
1222 if (stcb) {
1223 SCTP_TCB_LOCK(stcb);
1224 }
1225 SCTP_INP_RUNLOCK(inp);
1226 if (stcb == NULL) {
1227 SCTP_FREE_SONAME(sin6);
1228 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET);
1237 return ECONNRESET;
1229 return (ECONNRESET);
1238 }
1239 fnd = 0;
1240 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1241 sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1242 if (sin_a6->sin6_family == AF_INET6) {
1243 fnd = 1;
1244 sin6->sin6_port = stcb->rport;
1245 sin6->sin6_addr = sin_a6->sin6_addr;
1246 break;
1247 }
1248 }
1249 SCTP_TCB_UNLOCK(stcb);
1250 if (!fnd) {
1251 /* No IPv4 address */
1252 SCTP_FREE_SONAME(sin6);
1253 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
1230 }
1231 fnd = 0;
1232 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
1233 sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr;
1234 if (sin_a6->sin6_family == AF_INET6) {
1235 fnd = 1;
1236 sin6->sin6_port = stcb->rport;
1237 sin6->sin6_addr = sin_a6->sin6_addr;
1238 break;
1239 }
1240 }
1241 SCTP_TCB_UNLOCK(stcb);
1242 if (!fnd) {
1243 /* No IPv4 address */
1244 SCTP_FREE_SONAME(sin6);
1245 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT);
1254 return ENOENT;
1246 return (ENOENT);
1255 }
1256 if ((error = sa6_recoverscope(sin6)) != 0)
1257 return (error);
1258 *addr = (struct sockaddr *)sin6;
1259 return (0);
1260}
1261
1262static int
1263sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
1264{
1265#ifdef INET
1266 struct sockaddr *addr;
1267
1268#endif
1269 struct in6pcb *inp6 = sotoin6pcb(so);
1270 int error;
1271
1272 if (inp6 == NULL) {
1273 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1247 }
1248 if ((error = sa6_recoverscope(sin6)) != 0)
1249 return (error);
1250 *addr = (struct sockaddr *)sin6;
1251 return (0);
1252}
1253
1254static int
1255sctp6_in6getaddr(struct socket *so, struct sockaddr **nam)
1256{
1257#ifdef INET
1258 struct sockaddr *addr;
1259
1260#endif
1261 struct in6pcb *inp6 = sotoin6pcb(so);
1262 int error;
1263
1264 if (inp6 == NULL) {
1265 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1274 return EINVAL;
1266 return (EINVAL);
1275 }
1276 /* allow v6 addresses precedence */
1277 error = sctp6_getaddr(so, nam);
1278#ifdef INET
1279 if (error) {
1280 /* try v4 next if v6 failed */
1281 error = sctp_ingetaddr(so, nam);
1282 if (error) {

--- 20 unchanged lines hidden (view full) ---

1303 struct sockaddr *addr;
1304
1305#endif
1306 struct in6pcb *inp6 = sotoin6pcb(so);
1307 int error;
1308
1309 if (inp6 == NULL) {
1310 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1267 }
1268 /* allow v6 addresses precedence */
1269 error = sctp6_getaddr(so, nam);
1270#ifdef INET
1271 if (error) {
1272 /* try v4 next if v6 failed */
1273 error = sctp_ingetaddr(so, nam);
1274 if (error) {

--- 20 unchanged lines hidden (view full) ---

1295 struct sockaddr *addr;
1296
1297#endif
1298 struct in6pcb *inp6 = sotoin6pcb(so);
1299 int error;
1300
1301 if (inp6 == NULL) {
1302 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL);
1311 return EINVAL;
1303 return (EINVAL);
1312 }
1313 /* allow v6 addresses precedence */
1314 error = sctp6_peeraddr(so, nam);
1315#ifdef INET
1316 if (error) {
1317 /* try v4 next if v6 failed */
1318 error = sctp_peeraddr(so, nam);
1319 if (error) {

--- 4 unchanged lines hidden (view full) ---

1324 if (SCTP_IPV6_V6ONLY(inp6)) {
1325 struct sockaddr_in6 sin6;
1326
1327 in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
1328 memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
1329 }
1330 }
1331#endif
1304 }
1305 /* allow v6 addresses precedence */
1306 error = sctp6_peeraddr(so, nam);
1307#ifdef INET
1308 if (error) {
1309 /* try v4 next if v6 failed */
1310 error = sctp_peeraddr(so, nam);
1311 if (error) {

--- 4 unchanged lines hidden (view full) ---

1316 if (SCTP_IPV6_V6ONLY(inp6)) {
1317 struct sockaddr_in6 sin6;
1318
1319 in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6);
1320 memcpy(addr, &sin6, sizeof(struct sockaddr_in6));
1321 }
1322 }
1323#endif
1332 return error;
1324 return (error);
1333}
1334
1335struct pr_usrreqs sctp6_usrreqs = {
1336 .pru_abort = sctp6_abort,
1337 .pru_accept = sctp_accept,
1338 .pru_attach = sctp6_attach,
1339 .pru_bind = sctp6_bind,
1340 .pru_connect = sctp6_connect,

--- 14 unchanged lines hidden ---
1325}
1326
1327struct pr_usrreqs sctp6_usrreqs = {
1328 .pru_abort = sctp6_abort,
1329 .pru_accept = sctp_accept,
1330 .pru_attach = sctp6_attach,
1331 .pru_bind = sctp6_bind,
1332 .pru_connect = sctp6_connect,

--- 14 unchanged lines hidden ---