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 --- |