129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen/*- 229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved. 3ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved. 4ecc6b8c25a7e8d9d2b78889e88224354a1cc3160tuexen * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved. 529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * 629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * Redistribution and use in source and binary forms, with or without 729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * modification, are permitted provided that the following conditions are met: 829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * 929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * a) Redistributions of source code must retain the above copyright notice, 1029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * this list of conditions and the following disclaimer. 1129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * 1229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * b) Redistributions in binary form must reproduce the above copyright 1329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * notice, this list of conditions and the following disclaimer in 1429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * the documentation and/or other materials provided with the distribution. 1529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * 1629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * c) Neither the name of Cisco Systems, Inc. nor the names of its 1729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * contributors may be used to endorse or promote products derived 1829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * from this software without specific prior written permission. 1929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * 2029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 2229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 3029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * THE POSSIBILITY OF SUCH DAMAGE. 3129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 3229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 3329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef __FreeBSD__ 3429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <sys/cdefs.h> 35bfb1bf7e665a02b48026482bf33d05c83dfad73bt__FBSDID("$FreeBSD: head/sys/netinet6/sctp6_usrreq.c 271221 2014-09-07 09:06:26Z tuexen $"); 3629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 3729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 3829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_os.h> 39c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen#ifdef INET6 4029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef __FreeBSD__ 4129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <sys/proc.h> 4229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 4329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_pcb.h> 4429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_header.h> 4529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_var.h> 46e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET6 4729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet6/sctp6_var.h> 4829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 4929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_sysctl.h> 5029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_output.h> 5129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_uio.h> 5229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_asconf.h> 5329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctputil.h> 5429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_indata.h> 5529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_timer.h> 5629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_auth.h> 5729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_input.h> 5829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_output.h> 5929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_bsd_addr.h> 6029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/sctp_crc32.h> 6159caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#if !defined(__Userspace_os_Windows) 6229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netinet/udp.h> 6359caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#endif 6429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 6529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__APPLE__) 6629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#define APPLE_FILE_NO 9 6729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 6829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef IPSEC 6929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netipsec/ipsec.h> 70e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET6 7129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#include <netipsec/ipsec6.h> 7229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* INET6 */ 7329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* IPSEC */ 7429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 750612043f643c9b26245564c05defca64d472060etuexen#if !defined(__Userspace__) 7629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenextern struct protosw inetsw[]; 7729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 780612043f643c9b26245564c05defca64d472060etuexen#if defined(__Panda__) || defined(__Userspace__) 7929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint ip6_v6only=0; 8029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 810cfdc9964570b9773086305f77ec1dc609daec56tuexen#if defined(__Userspace__) 8229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenvoid 8329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenin6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6) 8429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 8559caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#if defined(__Userspace_os_Windows) 8659caa502fe5258530a6f6eab10155a6dac5d8d5atuexen uint32_t temp; 8759caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#endif 8829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen bzero(sin, sizeof(*sin)); 897b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN_LEN 9029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin->sin_len = sizeof(struct sockaddr_in); 9129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 9229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin->sin_family = AF_INET; 9329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin->sin_port = sin6->sin6_port; 9459caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#if defined(__Userspace_os_Windows) 9559caa502fe5258530a6f6eab10155a6dac5d8d5atuexen temp = sin6->sin6_addr.s6_addr16[7]; 9659caa502fe5258530a6f6eab10155a6dac5d8d5atuexen temp = temp << 16; 9759caa502fe5258530a6f6eab10155a6dac5d8d5atuexen temp = temp | sin6->sin6_addr.s6_addr16[6]; 9859caa502fe5258530a6f6eab10155a6dac5d8d5atuexen sin->sin_addr.s_addr = temp; 99000a5bac556b28e74e4e98c540f66b1743e9312dtuexen sctp_print_address((struct sockaddr*)sin); 10059caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#else 10129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin->sin_addr.s_addr = sin6->sin6_addr.s6_addr32[3]; 10259caa502fe5258530a6f6eab10155a6dac5d8d5atuexen#endif 10329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 10429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 10529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenvoid 10629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenin6_sin6_2_sin_in_sock(struct sockaddr *nam) 10729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 10829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in *sin_p; 10929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 sin6; 11029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 11129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* save original sockaddr_in6 addr and convert it to sockaddr_in */ 11229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6 = *(struct sockaddr_in6 *)nam; 11329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin_p = (struct sockaddr_in *)nam; 11429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_sin6_2_sin(sin_p, &sin6); 11529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 1160cfdc9964570b9773086305f77ec1dc609daec56tuexen#endif 11729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 118cbc99d79b7130a379a4d6c538b25deaa7321ac37t#if !defined(__Userspace__) 11929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 120b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if defined(__APPLE__) || defined(__FreeBSD__) 12129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_input_with_port(struct mbuf **i_pak, int *offp, uint16_t port) 12229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined( __Panda__) 12329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_input(pakhandle_type *i_pak) 12429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 12529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_input(struct mbuf **i_pak, int *offp, int proto) 12629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 12729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 12829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *m; 129923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen int iphlen; 13066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen uint32_t vrf_id; 131923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen uint8_t ecn_bits; 132e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen struct sockaddr_in6 src, dst; 13329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct ip6_hdr *ip6; 13429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctphdr *sh; 13529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_chunkhdr *ch; 136923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen int length, offset; 13766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if !defined(SCTP_WITH_NO_CSUM) 13866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen uint8_t compute_crc; 13966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif 1406a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 1416a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen uint32_t mflowid; 1426a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen uint8_t use_mflowid; 1436a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 144b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if !(defined(__APPLE__) || defined (__FreeBSD__)) 14529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint16_t port = 0; 14629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 147923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen 148923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#if defined(__Panda__) 149923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen /* This is Evil, but its the only way to make panda work right. */ 150923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen iphlen = sizeof(struct ip6_hdr); 151923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#else 152923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen iphlen = *offp; 15329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 154923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen if (SCTP_GET_PKT_VRFID(*i_pak, vrf_id)) { 15529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_RELEASE_PKT(*i_pak); 156923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen return (IPPROTO_DONE); 15729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 15829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen m = SCTP_HEADER_TO_CHAIN(*i_pak); 15929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef __Panda__ 16029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_DETACH_HEADER_FROM_CHAIN(*i_pak); 16129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (void)SCTP_RELEASE_HEADER(*i_pak); 16229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 163923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#ifdef SCTP_MBUF_LOGGING 164923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen /* Log in any input mbufs */ 165923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_MBUF_LOGGING_ENABLE) { 166923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen struct mbuf *mat; 16729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 168923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) { 169923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen if (SCTP_BUF_IS_EXTENDED(mat)) { 170923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen sctp_log_mb(mat, SCTP_MBUF_INPUT); 171923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen } 172923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen } 173923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen } 174923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#endif 1751b50943bdc80bbed39e89acdb49bd3b3f30c528ctuexen#ifdef SCTP_PACKET_LOGGING 1761b50943bdc80bbed39e89acdb49bd3b3f30c528ctuexen if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LAST_PACKET_TRACING) { 1771b50943bdc80bbed39e89acdb49bd3b3f30c528ctuexen sctp_packet_log(m); 1781b50943bdc80bbed39e89acdb49bd3b3f30c528ctuexen } 17929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 1806a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 18132ce34e90f7862d56c81f432a802a00110f7b427t#if __FreeBSD_version > 1000049 18232ce34e90f7862d56c81f432a802a00110f7b427t SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 18332ce34e90f7862d56c81f432a802a00110f7b427t "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%b.\n", 18432ce34e90f7862d56c81f432a802a00110f7b427t m->m_pkthdr.len, 18532ce34e90f7862d56c81f432a802a00110f7b427t if_name(m->m_pkthdr.rcvif), 18632ce34e90f7862d56c81f432a802a00110f7b427t (int)m->m_pkthdr.csum_flags, CSUM_BITS); 1878d509612af0dc2e1895434112897cf049b463063t#elif __FreeBSD_version >= 800000 18866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 18966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n", 19066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.len, 19166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen if_name(m->m_pkthdr.rcvif), 19266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.csum_flags); 19366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#else 19466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 19566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n", 19666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.len, 19766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.rcvif->if_xname, 19866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.csum_flags); 19966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif 20066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif 20166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__APPLE__) 20266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 20366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen "sctp6_input(): Packet of length %d received on %s%d with csum_flags 0x%x.\n", 20466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.len, 20566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.rcvif->if_name, 20666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.rcvif->if_unit, 20766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.csum_flags); 20866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif 20966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__Windows__) 21066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen SCTPDBG(SCTP_DEBUG_CRCOFFLOAD, 21166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen "sctp6_input(): Packet of length %d received on %s with csum_flags 0x%x.\n", 21266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.len, 21366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.rcvif->if_xname, 21466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen m->m_pkthdr.csum_flags); 21566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif 21666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if defined(__FreeBSD__) 2176a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen if (m->m_flags & M_FLOWID) { 2186a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen mflowid = m->m_pkthdr.flowid; 2196a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen use_mflowid = 1; 2206a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen } else { 2216a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen mflowid = 0; 2226a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen use_mflowid = 0; 2236a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen } 2246a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 225923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen SCTP_STAT_INCR(sctps_recvpackets); 226923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen SCTP_STAT_INCR_COUNTER64(sctps_inpackets); 227923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen /* Get IP, SCTP, and first chunk header together in the first mbuf. */ 228923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen offset = iphlen + sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr); 22966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen ip6 = mtod(m, struct ip6_hdr *); 230923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen IP6_EXTHDR_GET(sh, struct sctphdr *, m, iphlen, 231923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen (int)(sizeof(struct sctphdr) + sizeof(struct sctp_chunkhdr))); 23229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sh == NULL) { 23329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_STAT_INCR(sctps_hdrops); 234f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (IPPROTO_DONE); 23529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 23629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ch = (struct sctp_chunkhdr *)((caddr_t)sh + sizeof(struct sctphdr)); 237923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen offset -= sizeof(struct sctp_chunkhdr); 238e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen memset(&src, 0, sizeof(struct sockaddr_in6)); 239e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen src.sin6_family = AF_INET6; 2407b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 241e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen src.sin6_len = sizeof(struct sockaddr_in6); 242e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif 243e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen src.sin6_port = sh->src_port; 244e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen src.sin6_addr = ip6->ip6_src; 245e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#if defined(__FreeBSD__) 246e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#if defined(__APPLE__) 247e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen /* XXX: This code should also be used on Apple */ 248e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif 249e2828360ea9cf8951730d46f5c14626c9425cb30t if (in6_setscope(&src.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) { 25066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen goto out; 251e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen } 252e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif 253e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen memset(&dst, 0, sizeof(struct sockaddr_in6)); 254e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen dst.sin6_family = AF_INET6; 2557b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 256e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen dst.sin6_len = sizeof(struct sockaddr_in6); 257e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif 258e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen dst.sin6_port = sh->dest_port; 259e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen dst.sin6_addr = ip6->ip6_dst; 260e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#if defined(__FreeBSD__) 261e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#if defined(__APPLE__) 262e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen /* XXX: This code should also be used on Apple */ 263e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif 264e2828360ea9cf8951730d46f5c14626c9425cb30t if (in6_setscope(&dst.sin6_addr, m->m_pkthdr.rcvif, NULL) != 0) { 26566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen goto out; 266e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen } 267e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen#endif 26829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef __FreeBSD__ 269e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen if (faithprefix_p != NULL && (*faithprefix_p) (&dst.sin6_addr)) { 27029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* XXX send icmp6 host/port unreach? */ 27166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen goto out; 27229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 273923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#endif 274923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#if defined(__APPLE__) 275923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#if defined(NFAITH) && 0 < NFAITH 276e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen if (faithprefix(&dst.sin6_addr)) { 27766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen goto out; 278923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen } 27929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 280923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#endif 281923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen length = ntohs(ip6->ip6_plen) + iphlen; 282923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen /* Validate mbuf chain length with IP payload length. */ 28366bfb48e8d1df0adff2c330f249edcff464a5a25tuexen if (SCTP_HEADER_LEN(m) != length) { 284923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen SCTPDBG(SCTP_DEBUG_INPUT1, 28566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen "sctp6_input() length:%d reported length:%d\n", length, SCTP_HEADER_LEN(m)); 286923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen SCTP_STAT_INCR(sctps_hdrops); 28766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen goto out; 28829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 289923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { 29066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen goto out; 291923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen } 29266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen ecn_bits = ((ntohl(ip6->ip6_flow) >> 20) & 0x000000ff); 29329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(SCTP_WITH_NO_CSUM) 29429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_STAT_INCR(sctps_recvnocrc); 29529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 29629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 800000 29729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (m->m_pkthdr.csum_flags & CSUM_SCTP_VALID) { 29829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_STAT_INCR(sctps_recvhwcrc); 29966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen compute_crc = 0; 30066bfb48e8d1df0adff2c330f249edcff464a5a25tuexen } else { 30166bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#else 30266bfb48e8d1df0adff2c330f249edcff464a5a25tuexen if (SCTP_BASE_SYSCTL(sctp_no_csum_on_loopback) && 303e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen (IN6_ARE_ADDR_EQUAL(&src.sin6_addr, &dst.sin6_addr))) { 30429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_STAT_INCR(sctps_recvnocrc); 30566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen compute_crc = 0; 30666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen } else { 3076a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 30866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen SCTP_STAT_INCR(sctps_recvswcrc); 30966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen compute_crc = 1; 31029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 311923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen#endif 312e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen sctp_common_input_processing(&m, iphlen, offset, length, 313e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen (struct sockaddr *)&src, 31466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen (struct sockaddr *)&dst, 31566bfb48e8d1df0adff2c330f249edcff464a5a25tuexen sh, ch, 31666bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#if !defined(SCTP_WITH_NO_CSUM) 31766bfb48e8d1df0adff2c330f249edcff464a5a25tuexen compute_crc, 31866bfb48e8d1df0adff2c330f249edcff464a5a25tuexen#endif 31966bfb48e8d1df0adff2c330f249edcff464a5a25tuexen ecn_bits, 3206a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#if defined(__FreeBSD__) 3216a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen use_mflowid, mflowid, 3226a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen#endif 3236a646d8ad7f26691125adaa3a40cac21fbc1d81ftuexen vrf_id, port); 32466bfb48e8d1df0adff2c330f249edcff464a5a25tuexen out: 325923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen if (m) { 32629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_m_freem(m); 327923cf3e0f34bc13ed0c9510886aa189a5a5e7183tuexen } 328f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (IPPROTO_DONE); 32929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 33029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 33129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__APPLE__) 33229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 33329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_input(struct mbuf **i_pak, int *offp) 33429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 33529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (sctp6_input_with_port(i_pak, offp, 0)); 33629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 33729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 33829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 339b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#if defined(__FreeBSD__) 340b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72tint 341b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72tsctp6_input(struct mbuf **i_pak, int *offp, int proto SCTP_UNUSED) 342b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t{ 343b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t return (sctp6_input_with_port(i_pak, offp, 0)); 344b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t} 345b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t#endif 346b7a28211ba99e7b9116f93a0ec2e3f27acaa8f72t 34729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__Panda__) 34829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenvoid 34929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 35029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic void 35129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 35229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_notify_mbuf(struct sctp_inpcb *inp, struct icmp6_hdr *icmp6, 35329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctphdr *sh, struct sctp_tcb *stcb, struct sctp_nets *net) 35429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 35529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t nxtsz; 35629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 35729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 35829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmp6 == NULL) || (sh == NULL)) { 35929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto out; 36029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 36129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* First do we even look at it? */ 36229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) 36329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto out; 36429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 36529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (icmp6->icmp6_type != ICMP6_PACKET_TOO_BIG) { 36629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* not PACKET TO BIG */ 36729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto out; 36829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 36929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 37029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * ok we need to look closely. We could even get smarter and look at 37129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * anyone that we sent to in case we get a different ICMP that tells 37229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * us there is no way to reach a host, but for this impl, all we 37329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * care about is MTU discovery. 37429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 37529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen nxtsz = ntohl(icmp6->icmp6_mtu); 37629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Stop any PMTU timer */ 37729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_timer_stop(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL, SCTP_FROM_SCTP6_USRREQ+SCTP_LOC_1); 37829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 37929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Adjust destination size limit */ 38029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (net->mtu > nxtsz) { 38129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net->mtu = nxtsz; 38229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (net->port) { 38329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net->mtu -= sizeof(struct udphdr); 38429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 38529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 38629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* now what about the ep? */ 38729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb->asoc.smallest_mtu > nxtsz) { 38829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tmit_chunk *chk; 38929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 39029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Adjust that too */ 39129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb->asoc.smallest_mtu = nxtsz; 39229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* now off to subtract IP_DF flag if needed */ 39329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 39429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen TAILQ_FOREACH(chk, &stcb->asoc.send_queue, sctp_next) { 39529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) { 39629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 39729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 39829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 39929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) { 40029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((uint32_t) (chk->send_size + IP_HDR_SIZE) > nxtsz) { 40129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 40229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * For this guy we also mark for immediate 40329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * resend since we sent to big of chunk 40429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 40529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; 40629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (chk->sent != SCTP_DATAGRAM_RESEND) 40729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb->asoc.sent_queue_retran_cnt++; 40829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->sent = SCTP_DATAGRAM_RESEND; 40929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->rec.data.doing_fast_retransmit = 0; 41029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 41129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->sent = SCTP_DATAGRAM_RESEND; 41229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Clear any time so NO RTT is being done */ 41329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->sent_rcv_time.tv_sec = 0; 41429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen chk->sent_rcv_time.tv_usec = 0; 41529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb->asoc.total_flight -= chk->send_size; 41629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net->flight_size -= chk->send_size; 41729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 41829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 41929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 42029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, NULL); 42129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenout: 42229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb) { 42329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 42429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 42529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 42662652de4033658198a44c989a8396f0461be889btuexen#endif 42729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 4287ec5951ec04f35070419877f6b015541f6b9728dtuexen 42929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenvoid 43029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_notify(struct sctp_inpcb *inp, 43129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct icmp6_hdr *icmph, 43229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctphdr *sh, 43329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *to, 43429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tcb *stcb, 43529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_nets *net) 43629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 4370612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 43829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct socket *so; 43929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 44029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 44129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 44247674b651417d493ff4e0318113fd7beeef119dbtuexen /* protection */ 44329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((inp == NULL) || (stcb == NULL) || (net == NULL) || 44429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (sh == NULL) || (to == NULL)) { 44529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb) 44629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 44729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 44829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 44929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* First job is to verify the vtag matches what I would send */ 45029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (ntohl(sh->v_tag) != (stcb->asoc.peer_vtag)) { 45129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 45229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 45329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 45429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (icmph->icmp6_type != ICMP_UNREACH) { 45529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* We only care about unreachable */ 45629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 45729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 45829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 45929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((icmph->icmp6_code == ICMP_UNREACH_NET) || 46029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_HOST) || 46129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_NET_UNKNOWN) || 46229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_HOST_UNKNOWN) || 46329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_ISOLATED) || 46429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_NET_PROHIB) || 46529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_HOST_PROHIB) || 46622a33a1debfe70529be4aa018a2912bfe5dcd8dat#if defined(__Panda__) 46729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_ADMIN)) { 46822a33a1debfe70529be4aa018a2912bfe5dcd8dat#elif defined(__Userspace_os_NetBSD) 46922a33a1debfe70529be4aa018a2912bfe5dcd8dat (icmph->icmp6_code == ICMP_UNREACH_ADMIN_PROHIBIT)) { 47029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 47129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_FILTER_PROHIB)) { 47229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 47329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 47429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 47529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * Hmm reachablity problems we must examine closely. If its 47629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * not reachable, we may have lost a network. Or if there is 47729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * NO protocol at the other end named SCTP. well we consider 47829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * it a OOTB abort. 47929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 48029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (net->dest_state & SCTP_ADDR_REACHABLE) { 481000a5bac556b28e74e4e98c540f66b1743e9312dtuexen /* Ok that destination is NOT reachable */ 48229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net->dest_state &= ~SCTP_ADDR_REACHABLE; 48329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net->dest_state &= ~SCTP_ADDR_PF; 48429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN, 48547674b651417d493ff4e0318113fd7beeef119dbtuexen stcb, 0, (void *)net, SCTP_SO_NOT_LOCKED); 48629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 48729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 48829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else if ((icmph->icmp6_code == ICMP_UNREACH_PROTOCOL) || 48929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (icmph->icmp6_code == ICMP_UNREACH_PORT)) { 49029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 49129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * Here the peer is either playing tricks on us, 49229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * including an address that belongs to someone who 49329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * does not support SCTP OR was a userland 49429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * implementation that shutdown and now is dead. In 49529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * either case treat it like a OOTB abort with no 49629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * TCB 49729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 49847674b651417d493ff4e0318113fd7beeef119dbtuexen sctp_abort_notification(stcb, 1, 0, NULL, SCTP_SO_NOT_LOCKED); 4990612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 50029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen so = SCTP_INP_SO(inp); 50129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen atomic_add_int(&stcb->asoc.refcnt, 1); 50229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 50329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_SOCKET_LOCK(so, 1); 50429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_LOCK(stcb); 50529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen atomic_subtract_int(&stcb->asoc.refcnt, 1); 50629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 50729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ+SCTP_LOC_2); 5080612043f643c9b26245564c05defca64d472060etuexen#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) 50929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_SOCKET_UNLOCK(so, 1); 51029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* SCTP_TCB_UNLOCK(stcb); MT: I think this is not needed.*/ 51129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 51229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* no need to unlock here, since the TCB is gone */ 51329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 51429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 51529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 51629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 51729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 51829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 51929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 5200612043f643c9b26245564c05defca64d472060etuexen#if !defined(__Panda__) && !defined(__Userspace__) 52129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenvoid 52229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_ctlinput(int cmd, struct sockaddr *pktdst, void *d) 52329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 52429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctphdr sh; 52529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct ip6ctlparam *ip6cp = NULL; 52629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t vrf_id; 52729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 52829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 52929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen vrf_id = SCTP_DEFAULT_VRFID; 53029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 53129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 532f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 53329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (pktdst->sa_family != AF_INET6 || 53429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen pktdst->sa_len != sizeof(struct sockaddr_in6)) 53529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 53629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (pktdst->sa_family != AF_INET6) 53729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 53829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 53929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 54029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((unsigned)cmd >= PRC_NCMDS) 54129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 54229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (PRC_IS_REDIRECT(cmd)) { 54329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen d = NULL; 54429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else if (inet6ctlerrmap[cmd] == 0) { 54529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 54629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 54729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* if the parameter is from icmp6, decode it. */ 54829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (d != NULL) { 54929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ip6cp = (struct ip6ctlparam *)d; 55029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 55129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ip6cp = (struct ip6ctlparam *)NULL; 55229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 55329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 55429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (ip6cp) { 55529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 55629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * XXX: We assume that when IPV6 is non NULL, M and OFF are 55729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * valid. 55829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 55929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* check if we can safely examine src and dst ports */ 56029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp = NULL; 56129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tcb *stcb = NULL; 56229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_nets *net = NULL; 56329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 final; 56429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 56529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (ip6cp->ip6c_m == NULL) 56629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 56729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 56829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen bzero(&sh, sizeof(sh)); 56929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen bzero(&final, sizeof(final)); 57029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = NULL; 57129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net = NULL; 57229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen m_copydata(ip6cp->ip6c_m, ip6cp->ip6c_off, sizeof(sh), 57329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (caddr_t)&sh); 57429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ip6cp->ip6c_src->sin6_port = sh.src_port; 5757b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 57629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen final.sin6_len = sizeof(final); 57729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 57829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen final.sin6_family = AF_INET6; 57929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_cc_version < 440000 58029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen final.sin6_addr = *ip6cp->ip6c_finaldst; 58129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 58229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen final.sin6_addr = ((struct sockaddr_in6 *)pktdst)->sin6_addr; 58329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* __FreeBSD_cc_version */ 58429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen final.sin6_port = sh.dest_port; 585e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen stcb = sctp_findassociation_addr_sa((struct sockaddr *)&final, 586e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen (struct sockaddr *)ip6cp->ip6c_src, 58729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen &inp, &net, 1, vrf_id); 58829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* inp's ref-count increased && stcb locked */ 58929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb != NULL && inp && (inp->sctp_socket != NULL)) { 59029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (cmd == PRC_MSGSIZE) { 59129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_notify_mbuf(inp, 59229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ip6cp->ip6c_icmp6, 59329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen &sh, 59429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb, 59529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen net); 59629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* inp's ref-count reduced && stcb unlocked */ 59729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 59829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_notify(inp, ip6cp->ip6c_icmp6, &sh, 59929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (struct sockaddr *)&final, 60029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb, net); 60129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* inp's ref-count reduced && stcb unlocked */ 60229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 60329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 60429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if !defined(__Windows__) 60529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (PRC_IS_REDIRECT(cmd) && inp) { 60629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_rtchange((struct in6pcb *)inp, 60729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inet6ctlerrmap[cmd]); 60829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 60929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 61029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp) { 61129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* reduce inp's ref-count */ 61229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WLOCK(inp); 61329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_DECR_REF(inp); 61429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WUNLOCK(inp); 61529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 61629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb) 61729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 61829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 61929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 62029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 62129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 62229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 62329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen/* 62429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * this routine can probably be collasped into the one in sctp_userreq.c 62529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * since they do the same thing and now we lookup with a sockaddr 62629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 62729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef __FreeBSD__ 62829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 62929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getcred(SYSCTL_HANDLER_ARGS) 63029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 63129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct xucred xuc; 63229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 addrs[2]; 63329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 63429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_nets *net; 63529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tcb *stcb; 63629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 63729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t vrf_id; 63829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 63929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) 64029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen vrf_id = SCTP_DEFAULT_VRFID; 64129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 64229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen vrf_id = panda_get_vrf_from_call(); /* from connectx call? */ 64329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 64429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 64529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version > 602000 64629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = priv_check(req->td, PRIV_NETINET_GETCRED); 64729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__FreeBSD__) && __FreeBSD_version >= 500000 64829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = suser(req->td); 64929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 65029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = suser(req->p); 65129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 65229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) 65329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 65429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 65529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (req->newlen != sizeof(addrs)) { 65629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 65729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 65829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 65929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (req->oldlen != sizeof(struct ucred)) { 66029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 66129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 66229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 66329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = SYSCTL_IN(req, addrs, sizeof(addrs)); 66429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) 66529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 66629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 667e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen stcb = sctp_findassociation_addr_sa(sin6tosa(&addrs[1]), 668e056c2b95d882d42490e3cc86c7fbd6134c79b32tuexen sin6tosa(&addrs[0]), 66929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen &inp, &net, 1, vrf_id); 67029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb == NULL || inp == NULL || inp->sctp_socket == NULL) { 67129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((inp != NULL) && (stcb == NULL)) { 67229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* reduce ref-count */ 67329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WLOCK(inp); 67429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_DECR_REF(inp); 67529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto cred_can_cont; 67629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 67729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); 67829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = ENOENT; 67929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto out; 68029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 68129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 68229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* We use the write lock here, only 68329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * since in the error leg we need it. 68429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * If we used RLOCK, then we would have 68529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * to wlock/decr/unlock/rlock. Which 68629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * in theory could create a hole. Better 68729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * to use higher wlock. 68829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 68929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WLOCK(inp); 69029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen cred_can_cont: 69129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = cr_canseesocket(req->td->td_ucred, inp->sctp_socket); 69229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) { 69329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WUNLOCK(inp); 69429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto out; 69529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 69629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen cru2x(inp->sctp_socket->so_cred, &xuc); 69729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WUNLOCK(inp); 69829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = SYSCTL_OUT(req, &xuc, sizeof(struct xucred)); 69929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenout: 70029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 70129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 70229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 70329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenSYSCTL_PROC(_net_inet6_sctp6, OID_AUTO, getcred, CTLTYPE_OPAQUE | CTLFLAG_RW, 70429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 0, 0, 70529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_getcred, "S,ucred", "Get the ucred of a SCTP6 connection"); 70629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 70729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 70829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 70929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen/* This is the same as the sctp_abort() could be made common */ 71029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 690000) || defined(__Windows__) 71129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic void 71229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) || defined(__Userspace__) 71329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 71429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 71529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 71629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 71729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_abort(struct socket *so) 71829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 71929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 72029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t flags; 72129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 72229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 7232fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 72429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 72529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 690000) || defined(__Windows__) 72629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 72729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 728f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 72929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 73029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 73129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_must_try_again: 73229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen flags = inp->sctp_flags; 73329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_LOG_CLOSING 73429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_log_closing(inp, NULL, 17); 73529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 73629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) && 73729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) { 73829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_LOG_CLOSING 73929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_log_closing(inp, NULL, 16); 74029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 74129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT, 74229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_CALLED_AFTER_CMPSET_OFCLOSE); 74329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SOCK_LOCK(so); 74429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_SB_CLEAR(so->so_snd); 74529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* same for the rcv ones, they are only 74629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * here for the accounting/select. 74729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 74829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_SB_CLEAR(so->so_rcv); 74929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__APPLE__) 75029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen so->so_usecount--; 75129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 75229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Now null out the reference, we are completely detached. */ 75329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen so->so_pcb = NULL; 75429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 75529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SOCK_UNLOCK(so); 75629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 75729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen flags = inp->sctp_flags; 75829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) { 75929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto sctp_must_try_again; 76029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 76129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 76229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 690000) || defined(__Windows__) 76329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return; 76429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 76529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (0); 76629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 76729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 76829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 76929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 77029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 77129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUSED) 77229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) || defined(__Userspace__) 77329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 77429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_attach(struct socket *so, int proto SCTP_UNUSED, uint32_t vrf_id) 77529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Windows__) 77629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 77729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_attach(struct socket *so, int proto SCTP_UNUSED, PKTHREAD p SCTP_UNUSED) 77829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 77929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 78029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_attach(struct socket *so, int proto SCTP_UNUSED, struct proc *p SCTP_UNUSED) 78129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 78229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 78329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct in6pcb *inp6; 78429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 78529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 78629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if !defined(__Panda__) && !defined(__Userspace__) 78729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t vrf_id = SCTP_DEFAULT_VRFID; 78829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 78929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 79029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 79129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp != NULL) { 79229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 793f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 79429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 79529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 79629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { 79729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = SCTP_SORESERVE(so, SCTP_BASE_SYSCTL(sctp_sendspace), SCTP_BASE_SYSCTL(sctp_recvspace)); 79829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) 799f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (error); 80029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 80129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_inpcb_alloc(so, vrf_id); 80229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) 803f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (error); 80429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 80529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WLOCK(inp); 80629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->sctp_flags |= SCTP_PCB_FLAGS_BOUND_V6; /* I'm v6! */ 80729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6 = (struct in6pcb *)inp; 80829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 8090612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 81029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag |= INP_IPV6; 81129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 81229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag |= INP_IPV6; 81329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 81429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if !defined(__Panda__) 81529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->in6p_hops = -1; /* use kernel default */ 81629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->in6p_cksum = -1; /* just to be sure */ 81729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 81829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 81929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 82029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * XXX: ugly!! IPv4 TTL initialization is necessary for an IPv6 82129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * socket as well, because the socket may be bound to an IPv6 82229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * wildcard address, which may match an IPv4-mapped IPv6 address. 82329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 82429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); 82529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 82629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 82729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * Hmm what about the IPSEC stuff that is missing here but in 82829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * sctp_attach()? 82929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 83029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WUNLOCK(inp); 831f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (0); 83229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 83329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 83429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 83529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 83629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_bind(struct socket *so, struct sockaddr *addr, struct thread *p) 83729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 83829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__FreeBSD__) || defined(__APPLE__) 83929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 84029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_bind(struct socket *so, struct sockaddr *addr, struct proc *p) 84129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 84229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) || defined(__Userspace__) 84329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 84429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_bind(struct socket *so, struct sockaddr *addr, void * p) 84529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 84629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Windows__) 84729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 84829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_bind(struct socket *so, struct sockaddr *addr, PKTHREAD p) 84929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 85029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 85129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 85229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_bind(struct socket *so, struct mbuf *nam, struct proc *p) 85329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 85429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL; 85529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 85629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 85729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 85829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct in6pcb *inp6; 85929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 86029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 86129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 8622fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 86329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 864f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 86529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 86629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 86729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if !defined(__Windows__) 86829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr) { 86929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen switch (addr->sa_family) { 87029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 87129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case AF_INET: 872f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 87329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_len != sizeof(struct sockaddr_in)) { 87429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 875f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 87629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 87729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 87829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 87929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 88029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET6 88129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case AF_INET6: 882f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 88329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_len != sizeof(struct sockaddr_in6)) { 88429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 885f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 88629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 88729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 88829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 88929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 89029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen default: 89129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 892f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 89329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 89429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 89529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 89629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6 = (struct in6pcb *)inp; 8970612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 89829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag &= ~INP_IPV4; 89929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag |= INP_IPV6; 90029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 90129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag &= ~INP_IPV4; 90229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag |= INP_IPV6; 90329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 90429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((addr != NULL) && (SCTP_IPV6_V6ONLY(inp6) == 0)) { 90529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen switch (addr->sa_family) { 90629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 90729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case AF_INET: 90829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* binding v4 addr to v6 socket, so reset flags */ 9090612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 91029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag |= INP_IPV4; 91129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag &= ~INP_IPV6; 91229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 91329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag |= INP_IPV4; 91429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag &= ~INP_IPV6; 91529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 91629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 91729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 91829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET6 91929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case AF_INET6: 92029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen { 92129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6_p; 92229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 92329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6_p = (struct sockaddr_in6 *)addr; 92429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 92529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) { 9260612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 92729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag |= INP_IPV4; 92829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 92929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag |= INP_IPV4; 93029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 93129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 93229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 93329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) { 93429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in sin; 93529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 93629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_sin6_2_sin(&sin, sin6_p); 9370612043f643c9b26245564c05defca64d472060etuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) || defined(__Userspace__) 93829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag |= INP_IPV4; 93929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6->inp_vflag &= ~INP_IPV6; 94029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 94129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag |= INP_IPV4; 94229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->inp_vflag &= ~INP_IPV6; 94329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 94429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_inpcb_bind(so, (struct sockaddr *)&sin, NULL, p); 945f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (error); 94629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 94729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 94829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 94929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 95029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 95129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen default: 95229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 95329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 95429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else if (addr != NULL) { 95529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6_p; 95629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 95729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* IPV6_V6ONLY socket */ 95829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 95929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_family == AF_INET) { 96029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* can't bind v4 addr to v6 only socket! */ 96129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 962f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 96329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 96429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 96529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6_p = (struct sockaddr_in6 *)addr; 96629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 96729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) { 96829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* can't bind v4-mapped addrs either! */ 96929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* NOTE: we don't support SIIT */ 97029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 971f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 97229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 97329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 97429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_inpcb_bind(so, addr, NULL, p); 975f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (error); 97629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 97729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 9787ec5951ec04f35070419877f6b015541f6b9728dtuexen 9798a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#if (defined(__FreeBSD__) && __FreeBSD_version > 690000) || defined(__Windows__) || defined(__Userspace__) 9808a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#if !defined(__Userspace__) 9817ec5951ec04f35070419877f6b015541f6b9728dtuexenstatic void 9827ec5951ec04f35070419877f6b015541f6b9728dtuexen#else 9838a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexenvoid 9847ec5951ec04f35070419877f6b015541f6b9728dtuexen#endif 98529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_close(struct socket *so) 98629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 98729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_close(so); 98829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 98929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 99029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen/* This could be made common with sctp_detach() since they are identical */ 99129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 99229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 99329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if !defined(__Panda__) 99429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic 99529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 99629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 99729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_detach(struct socket *so) 99829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 9990612043f643c9b26245564c05defca64d472060etuexen#if defined(__Userspace__) 100029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_close(so); 100129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (0); 100229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 100329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (sctp_detach(so)); 100429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 100529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 100629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 100729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 100829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 10098a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#if !defined(__Panda__) && !defined(__Userspace__) 101029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic 101129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 101229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 101329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_disconnect(struct socket *so) 101429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 1015f57cf83923be449d11806a31f62bcc17e58832d6t return (sctp_disconnect(so)); 101629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 101729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 101829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 101929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 102029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 102129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 102229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *control, struct thread *p); 102329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 102429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 102529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp_sendm(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 102629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *control, struct proc *p); 102729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 102829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 102929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 10308a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#if !defined(__Panda__) && !defined(__Windows__) && !defined(__Userspace__) 103129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 103229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 103329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 103429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *control, struct thread *p) 103529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 103629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__FreeBSD__) || defined(__APPLE__) 103729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 103829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, 103929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *control, struct proc *p) 104029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 104129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 104229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 104329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *nam, 104429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *control, struct proc *p) 104529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 104629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = nam ? mtod(nam, struct sockaddr *): NULL; 104729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 104829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 104929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct in6pcb *inp6; 105029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 105129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 105229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6; 105329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* INET */ 105429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* No SPL needed since sctp_output does this */ 105529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 105629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 105729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp == NULL) { 105829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (control) { 105929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_RELEASE_PKT(control); 106029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen control = NULL; 106129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 106229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_RELEASE_PKT(m); 106329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1064f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 106529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 106629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6 = (struct in6pcb *)inp; 106729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 106829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * For the TCP model we may get a NULL addr, if we are a connected 106929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * socket thats ok. 107029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 107129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) && 107229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (addr == NULL)) { 107329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto connected_type; 107429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 107529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr == NULL) { 107629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_RELEASE_PKT(m); 107729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (control) { 107829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_RELEASE_PKT(control); 107929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen control = NULL; 108029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 108129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EDESTADDRREQ); 108229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EDESTADDRREQ); 108329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 108429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 108529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6 = (struct sockaddr_in6 *)addr; 108629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (SCTP_IPV6_V6ONLY(inp6)) { 108729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 108829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * if IPV6_V6ONLY flag, we discard datagrams destined to a 108929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * v4 addr or v4-mapped addr 109029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 109129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_family == AF_INET) { 109229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1093f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 109429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 109529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 109629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1097f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 109829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 109929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 110029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 1101202f563d266291cbdec3bacf7844172ebfabed95t struct sockaddr_in sin; 110229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 1103202f563d266291cbdec3bacf7844172ebfabed95t /* convert v4-mapped into v4 addr and send */ 1104202f563d266291cbdec3bacf7844172ebfabed95t in6_sin6_2_sin(&sin, sin6); 1105202f563d266291cbdec3bacf7844172ebfabed95t return (sctp_sendm(so, flags, m, (struct sockaddr *)&sin, control, p)); 110629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 110729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* INET */ 110829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenconnected_type: 110929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* now what about control */ 111029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (control) { 111129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp->control) { 111229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_PRINTF("huh? control set?\n"); 111329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_RELEASE_PKT(inp->control); 111429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->control = NULL; 111529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 111629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->control = control; 111729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 111829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Place the data */ 111929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp->pkt) { 112029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_BUF_NEXT(inp->pkt_last) = m; 112129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->pkt_last = m; 112229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 112329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->pkt_last = inp->pkt = m; 112429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 112529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ( 112629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) 112729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* FreeBSD and MacOSX uses a flag passed */ 112829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ((flags & PRUS_MORETOCOME) == 0) 112929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 113029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 1 /* Open BSD does not have any "more to come" 113129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * indication */ 113229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 113329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ) { 113429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 113529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * note with the current version this code will only be used 113629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * by OpenBSD, NetBSD and FreeBSD have methods for 113729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * re-defining sosend() to use sctp_sosend(). One can 113829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * optionaly switch back to this code (by changing back the 113929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * defininitions but this is not advisable. 114029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 114129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int ret; 114229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 114329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ret = sctp_output(inp, inp->pkt, addr, inp->control, p, flags); 114429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->pkt = NULL; 114529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp->control = NULL; 114629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (ret); 114729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 114829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (0); 114929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 115029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 115129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 115229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 115329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) && __FreeBSD_version >= 500000 115429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 115529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_connect(struct socket *so, struct sockaddr *addr, struct thread *p) 115629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 115729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__FreeBSD__) || defined(__APPLE__) 115829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 115929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_connect(struct socket *so, struct sockaddr *addr, struct proc *p) 116029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 116129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 116229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 116329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_connect(struct socket *so, struct sockaddr *addr, void *p) 116429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 116529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Windows__) 116629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 116729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_connect(struct socket *so, struct sockaddr *addr, PKTHREAD p) 116829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 11690612043f643c9b26245564c05defca64d472060etuexen#elif defined(__Userspace__) 117029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 117129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_connect(struct socket *so, struct sockaddr *addr) 117229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 117329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen void *p = NULL; 117429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 117529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 117629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_connect(struct socket *so, struct mbuf *nam, struct proc *p) 117729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 117829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 117929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 118029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t vrf_id; 118129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error = 0; 118229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 118329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tcb *stcb; 118429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 1185590ebded4dce1066b7845150a337c0bd8a00d843t struct in6pcb *inp6; 118629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6; 1187bfb1bf7e665a02b48026482bf33d05c83dfad73bt union sctp_sockstore store; 118829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 118929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 1190590ebded4dce1066b7845150a337c0bd8a00d843t#ifdef INET 119129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp6 = (struct in6pcb *)so->so_pcb; 1192590ebded4dce1066b7845150a337c0bd8a00d843t#endif 119329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 11942fbec84cda9df157171087bab7b4a564107161eatuexen if (inp == NULL) { 119529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET); 119629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (ECONNRESET); /* I made the same as TCP since we are 119729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * not setup? */ 119829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 119929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr == NULL) { 120029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 120129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 120229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 120329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if !defined(__Windows__) 120429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen switch (addr->sa_family) { 120529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 120629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case AF_INET: 1207f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 120829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_len != sizeof(struct sockaddr_in)) { 120929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 121029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 121129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 121229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 121329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 121429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 121529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET6 121629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case AF_INET6: 1217f48c9397d7b9d7cee2e31a28173480bbfe22e6c7t#ifdef HAVE_SA_LEN 121829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_len != sizeof(struct sockaddr_in6)) { 121929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 122029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 122129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 122229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 122329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 122429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 122529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen default: 122629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 122729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 122829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 122929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 123029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 123129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen vrf_id = inp->def_vrf_id; 123229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_LOCK(inp); 123329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RLOCK(inp); 123429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) == 123529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_PCB_FLAGS_UNBOUND) { 123629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Bind a ephemeral port */ 123729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 123829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_bind(so, NULL, p); 123929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) { 124029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 124129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 124229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 124329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 124429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RLOCK(inp); 124529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 124629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) && 124729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED)) { 124829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* We are already connected AND the TCP model */ 124929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 125029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 125129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EADDRINUSE); 125229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EADDRINUSE); 125329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 125429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 125529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6 = (struct sockaddr_in6 *)addr; 125629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (SCTP_IPV6_V6ONLY(inp6)) { 125729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 125829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * if IPV6_V6ONLY flag, ignore connections destined to a v4 125929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * addr or v4-mapped addr 126029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 126129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (addr->sa_family == AF_INET) { 126229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 126329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 126429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1265f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 126629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 126729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 126829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 126929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 127029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1271f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 127229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 127329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 127429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 1275202f563d266291cbdec3bacf7844172ebfabed95t /* convert v4-mapped into v4 addr */ 1276bfb1bf7e665a02b48026482bf33d05c83dfad73bt in6_sin6_2_sin(&store.sin, sin6); 1277bfb1bf7e665a02b48026482bf33d05c83dfad73bt addr = &store.sa; 127829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 127929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* INET */ 128029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Now do we connect? */ 128129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 128229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 128329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb) { 128429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 128529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 128629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 128729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 128829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 128929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WLOCK(inp); 129029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_INCR_REF(inp); 129129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WUNLOCK(inp); 129229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb = sctp_findassociation_ep_addr(&inp, addr, NULL, NULL, NULL); 129329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb == NULL) { 129429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WLOCK(inp); 129529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_DECR_REF(inp); 129629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_WUNLOCK(inp); 129729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 129829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 129929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 130029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb != NULL) { 130129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Already have or am bring up an association */ 130229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 130329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 130429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EALREADY); 130529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EALREADY); 130629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 130729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* We are GOOD to go */ 130829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p); 130929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_ASOC_CREATE_UNLOCK(inp); 131029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb == NULL) { 131129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Gak! no memory */ 131229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 131329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 131429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { 131529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; 131629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Set the connected flag so we can queue data */ 131729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen soisconnecting(so); 131829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 131929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb->asoc.state = SCTP_STATE_COOKIE_WAIT; 132029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered); 132129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 132229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* initialize authentication parameters for the assoc */ 132329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_initialize_auth_params(inp, stcb); 132429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 132529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED); 132629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 1327f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (error); 132829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 132929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 133029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 133129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 133229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getaddr(struct socket *so, struct sockaddr **addr) 133329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 133429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6; 133529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 133629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getaddr(struct socket *so, struct sockaddr *addr) 133729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 133829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; 133929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 134029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getaddr(struct socket *so, struct mbuf *nam) 134129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 134229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *); 134329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 134429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 134529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t vrf_id; 134629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_ifa *sctp_ifa; 134729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 134829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_KAME 134929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 135029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* SCTP_KAME */ 135129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 135229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 135329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * Do the malloc first in case it blocks. 135429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 135529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 135629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof(*sin6)); 135729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sin6 == NULL) 1358f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (ENOMEM); 135929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 136029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen bzero(sin6, sizeof(*sin6)); 136129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 136229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_BUF_LEN(nam) = sizeof(*sin6); 136329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen bzero(sin6, sizeof(*sin6)); 136429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 136529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_family = AF_INET6; 13667b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 136729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_len = sizeof(*sin6); 136829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 136929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 137029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 137129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp == NULL) { 137229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 137329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_FREE_SONAME(sin6); 137429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 137529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET); 1376f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (ECONNRESET); 137729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 137829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RLOCK(inp); 137929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_port = inp->sctp_lport; 138029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) { 138129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* For the bound all case you get back 0 */ 138229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) { 138329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tcb *stcb; 138429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin_a6; 138529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_nets *net; 138629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int fnd; 138729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 138829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb == NULL) { 138929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto notConn6; 139029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 139129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen fnd = 0; 139229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin_a6 = NULL; 139329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 139429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr; 139529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sin_a6 == NULL) 139629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* this will make coverity happy */ 139729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen continue; 139829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 139929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sin_a6->sin6_family == AF_INET6) { 140029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen fnd = 1; 140129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 140229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 140329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 140429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((!fnd) || (sin_a6 == NULL)) { 140529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* punt */ 140629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen goto notConn6; 140729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 140829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen vrf_id = inp->def_vrf_id; 140929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_ifa = sctp_source_address_selection(inp, stcb, (sctp_route_t *)&net->ro, net, 0, vrf_id); 141029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sctp_ifa) { 141129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_addr = sctp_ifa->address.sin6.sin6_addr; 141229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 141329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 141429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* For the bound all case you get back 0 */ 141529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen notConn6: 141629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr)); 141729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 141829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } else { 141929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Take the first IPv6 address in the list */ 142029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_laddr *laddr; 142129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int fnd = 0; 142229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 142329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) { 142429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (laddr->ifa->address.sa.sa_family == AF_INET6) { 142529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin_a; 142629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 1427bfb1bf7e665a02b48026482bf33d05c83dfad73bt sin_a = &laddr->ifa->address.sin6; 142829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_addr = sin_a->sin6_addr; 142929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen fnd = 1; 143029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 143129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 143229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 143329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (!fnd) { 143429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 143529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_FREE_SONAME(sin6); 143629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 143729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 143829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); 1439f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (ENOENT); 144029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 144129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 144229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 144329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Scoping things for v6 */ 144429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_EMBEDDED_V6_SCOPE 144529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_KAME 144629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((error = sa6_recoverscope(sin6)) != 0) { 144729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_FREE_SONAME(sin6); 144829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 144929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 145029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 145129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) 145229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* skip ifp check below */ 145329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_recoverscope(sin6, &sin6->sin6_addr, NULL); 145429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen else 145529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_scope_id = 0; /* XXX */ 145629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* SCTP_KAME */ 145729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 145829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 145929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (*addr) = (struct sockaddr *)sin6; 146029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 146129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (0); 146229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 146329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 146429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 146529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 146629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_peeraddr(struct socket *so, struct sockaddr **addr) 146729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 1468845436a72b5767f30403c3b77c457488703143a9tuexen struct sockaddr_in6 *sin6; 146929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 147029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_peeraddr(struct socket *so, struct sockaddr *addr) 147129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 147229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; 147329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 147429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_peeraddr(struct socket *so, struct mbuf *nam) 147529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 147629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin6 = mtod(nam, struct sockaddr_in6 *); 147729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 147829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int fnd; 147929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 *sin_a6; 148029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_inpcb *inp; 148129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_tcb *stcb; 148229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sctp_nets *net; 148329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_KAME 148429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 1485f840325bb9bca0f8732b3f8179ce54fa594160abtuexen#endif 148629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 1487f840325bb9bca0f8732b3f8179ce54fa594160abtuexen /* Do the malloc first in case it blocks. */ 148829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 148929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_MALLOC_SONAME(sin6, struct sockaddr_in6 *, sizeof *sin6); 149029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sin6 == NULL) 149129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (ENOMEM); 149229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 1493f840325bb9bca0f8732b3f8179ce54fa594160abtuexen memset(sin6, 0, sizeof(*sin6)); 149429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 149529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_BUF_LEN(nam) = sizeof(*sin6); 1496f840325bb9bca0f8732b3f8179ce54fa594160abtuexen memset(sin6, 0, sizeof(*sin6)); 149729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 149829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_family = AF_INET6; 14997b0ab5c1c85787647428afafeff9491e9b6a60c7t#ifdef HAVE_SIN6_LEN 150029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_len = sizeof(*sin6); 150129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 150229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 150329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen inp = (struct sctp_inpcb *)so->so_pcb; 1504f840325bb9bca0f8732b3f8179ce54fa594160abtuexen if ((inp == NULL) || 1505f840325bb9bca0f8732b3f8179ce54fa594160abtuexen ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0)) { 1506f840325bb9bca0f8732b3f8179ce54fa594160abtuexen /* UDP type and listeners will drop out here */ 150729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 150829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_FREE_SONAME(sin6); 150929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 1510f840325bb9bca0f8732b3f8179ce54fa594160abtuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOTCONN); 1511f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (ENOTCONN); 151229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 151329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RLOCK(inp); 151429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen stcb = LIST_FIRST(&inp->sctp_asoc_list); 151529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb) { 151629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_LOCK(stcb); 151729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 151829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_INP_RUNLOCK(inp); 151929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (stcb == NULL) { 152029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 152129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_FREE_SONAME(sin6); 152229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 152329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ECONNRESET); 1524f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (ECONNRESET); 152529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 152629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen fnd = 0; 152729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) { 152829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin_a6 = (struct sockaddr_in6 *)&net->ro._l_addr; 152929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (sin_a6->sin6_family == AF_INET6) { 153029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen fnd = 1; 153129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_port = stcb->rport; 153229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sin6->sin6_addr = sin_a6->sin6_addr; 153329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 153429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 153529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 153629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_TCB_UNLOCK(stcb); 153729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (!fnd) { 153829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* No IPv4 address */ 153929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 154029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_FREE_SONAME(sin6); 154129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 154229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, ENOENT); 1543f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (ENOENT); 154429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 154529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_EMBEDDED_V6_SCOPE 154629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef SCTP_KAME 154729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if ((error = sa6_recoverscope(sin6)) != 0) 154829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 154929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 155029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_recoverscope(sin6, &sin6->sin6_addr, NULL); 155129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* SCTP_KAME */ 155229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif /* SCTP_EMBEDDED_V6_SCOPE */ 155329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 155429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen *addr = (struct sockaddr *)sin6; 155529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 155629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (0); 155729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 155829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 155929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 156029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 156129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_in6getaddr(struct socket *so, struct sockaddr **nam) 156229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 156329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 156429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr; 156529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 156629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 156729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 156829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_in6getaddr(struct socket *so, struct sockaddr *nam, uint32_t *namelen) 156929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 157029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = nam; 15718a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#elif defined(__Userspace__) 15728a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexenint 15738a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexensctp6_in6getaddr(struct socket *so, struct mbuf *nam) 15748a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen{ 1575e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET 15768a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 15778a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#endif 157829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 157929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 158029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_in6getaddr(struct socket *so, struct mbuf *nam) 158129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 1582e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET 158329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 158429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 158562652de4033658198a44c989a8396f0461be889btuexen#endif 158629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct in6pcb *inp6 = sotoin6pcb(so); 158729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 158829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 158929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp6 == NULL) { 159029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1591f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 159229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 159329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 159429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* allow v6 addresses precedence */ 159529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_getaddr(so, nam); 159629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 159729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) { 159829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* try v4 next if v6 failed */ 159929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_ingetaddr(so, nam); 160029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) { 160129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 160229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 160329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 160429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen addr = *nam; 160529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 160629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* if I'm V6ONLY, convert it to v4-mapped */ 160729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (SCTP_IPV6_V6ONLY(inp6)) { 160829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 sin6; 160929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 161029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6); 161129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen memcpy(addr, &sin6, sizeof(struct sockaddr_in6)); 161229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 161329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 161429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 161529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__Panda__) 161629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen *namelen = nam->sa_len; 161729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 161829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 161929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 162029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 162129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 162229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 162329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstatic int 162429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getpeeraddr(struct socket *so, struct sockaddr **nam) 162529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 162629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 162729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr; 162829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 162929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif defined(__Panda__) 163029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 163129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getpeeraddr(struct socket *so, struct sockaddr *nam, uint32_t *namelen) 163229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 163329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = (struct sockaddr *)nam; 16348a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#elif defined(__Userspace__) 16358a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexenint 16368a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexensctp6_getpeeraddr(struct socket *so, struct mbuf *nam) 16378a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen{ 1638e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET 16398a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 16408a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexen#endif 164129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 16428a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexenstatic 16438a5b814e559643cabe8ac7e88e0b747ea0a76fe3tuexenint 164429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_getpeeraddr(struct socket *so, struct mbuf *nam) 164529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 1646e857b728270b80432f048a8de3c84aa9089dd06btuexen#ifdef INET 164729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr *addr = mtod(nam, struct sockaddr *); 164862652de4033658198a44c989a8396f0461be889btuexen#endif 164929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 165029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 165129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct in6pcb *inp6 = sotoin6pcb(so); 165229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error; 165329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 165429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (inp6 == NULL) { 165529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 1656f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (EINVAL); 165729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 165829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 165929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* allow v6 addresses precedence */ 166029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_peeraddr(so, nam); 166129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET 166229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) { 166329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* try v4 next if v6 failed */ 166429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_peeraddr(so, nam); 166529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (error) { 166629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 166729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 166829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 166929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen addr = *nam; 167029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 167129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* if I'm V6ONLY, convert it to v4-mapped */ 167229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (SCTP_IPV6_V6ONLY(inp6)) { 167329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct sockaddr_in6 sin6; 167429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 167529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen in6_sin_2_v4mapsin6((struct sockaddr_in *)addr, &sin6); 167629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen memcpy(addr, &sin6, sizeof(struct sockaddr_in6)); 167729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 167829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 167929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 168029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__Panda__) 168129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen *namelen = nam->sa_len; 168229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 1683f840325bb9bca0f8732b3f8179ce54fa594160abtuexen return (error); 168429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 168529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 168629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__Windows__) 168729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenstruct pr_usrreqs sctp6_usrreqs = { 16887fbcb406549bdf370031d2ad5befb44e39b95ffft#if defined(__FreeBSD__) 168929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_abort = sctp6_abort, 169029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_accept = sctp_accept, 169129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_attach = sctp6_attach, 169229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_bind = sctp6_bind, 169329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_connect = sctp6_connect, 169429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_control = in6_control, 169529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#if __FreeBSD_version >= 690000 169629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_close = sctp6_close, 169729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_detach = sctp6_close, 169829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_sopoll = sopoll_generic, 1699000a5bac556b28e74e4e98c540f66b1743e9312dtuexen .pru_flush = sctp_flush, 170029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#else 170129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_detach = sctp6_detach, 170229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_sopoll = sopoll, 170329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 170429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_disconnect = sctp6_disconnect, 170529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_listen = sctp_listen, 170629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_peeraddr = sctp6_getpeeraddr, 170729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_send = sctp6_send, 170829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_shutdown = sctp_shutdown, 170929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_sockaddr = sctp6_in6getaddr, 171029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_sosend = sctp_sosend, 171129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen .pru_soreceive = sctp_soreceive 17127fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__APPLE__) 17137fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_abort = sctp6_abort, 17147fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_accept = sctp_accept, 17157fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_attach = sctp6_attach, 17167fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_bind = sctp6_bind, 17177fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_connect = sctp6_connect, 17187fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_connect2 = pru_connect2_notsupp, 17197fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_control = in6_control, 17207fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_detach = sctp6_detach, 17217fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_disconnect = sctp6_disconnect, 17227fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_listen = sctp_listen, 17237fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_peeraddr = sctp6_getpeeraddr, 17247fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_rcvd = NULL, 17257fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_rcvoob = pru_rcvoob_notsupp, 17267fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_send = sctp6_send, 17277fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sense = pru_sense_null, 17287fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_shutdown = sctp_shutdown, 17297fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sockaddr = sctp6_in6getaddr, 17307fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_sosend = sctp_sosend, 17317fbcb406549bdf370031d2ad5befb44e39b95ffft .pru_soreceive = sctp_soreceive, 1732e2828360ea9cf8951730d46f5c14626c9425cb30t .pru_sopoll = sopoll 17337fbcb406549bdf370031d2ad5befb44e39b95ffft#elif defined(__Windows__) 173429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_abort, 173529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_accept, 173629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_attach, 173729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_bind, 173829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_connect, 173929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen pru_connect2_notsupp, 174029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen NULL, 174129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen NULL, 174229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_disconnect, 174329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_listen, 174429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_getpeeraddr, 174529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen NULL, 174629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen pru_rcvoob_notsupp, 174729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen NULL, 174829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen pru_sense_null, 174929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_shutdown, 175029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_flush, 175129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_in6getaddr, 175229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_sosend, 175329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp_soreceive, 175429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sopoll_generic, 175529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen NULL, 175629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen sctp6_close 175729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 175829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen}; 175929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 176029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#elif !defined(__Panda__) && !defined(__Userspace__) 176129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexenint 176229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexensctp6_usrreq(so, req, m, nam, control, p) 176329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct socket *so; 176429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int req; 176529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct mbuf *m, *nam, *control; 176629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen struct proc *p; 176729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen{ 176829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int s; 176929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int error = 0; 177029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen int family; 177129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen uint32_t vrf_id; 177229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen family = so->so_proto->pr_domain->dom_family; 177329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 177429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (req == PRU_CONTROL) { 177529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen switch (family) { 177629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PF_INET: 177729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = in_control(so, (long)m, (caddr_t)nam, 177829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (struct ifnet *)control 177929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen ); 178029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#ifdef INET6 178129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PF_INET6: 178229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = in6_control(so, (long)m, (caddr_t)nam, 178329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen (struct ifnet *)control, p); 178429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 178529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen default: 178629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT); 178729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = EAFNOSUPPORT; 178829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 178929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 179029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 179129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen switch (req) { 179229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_ATTACH: 179329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_attach(so, family, p); 179429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 179529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_DETACH: 179629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_detach(so); 179729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 179829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_BIND: 179929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (nam == NULL) { 180029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 180129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 180229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 180329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_bind(so, nam, p); 180429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 180529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_LISTEN: 180629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_listen(so, p); 180729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 180829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_CONNECT: 180929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (nam == NULL) { 181029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 181129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 181229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 181329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_connect(so, nam, p); 181429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 181529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_DISCONNECT: 181629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_disconnect(so); 181729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 181829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_ACCEPT: 181929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen if (nam == NULL) { 182029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EINVAL); 182129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (EINVAL); 182229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 182329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_accept(so, nam); 182429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 182529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_SHUTDOWN: 182629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_shutdown(so); 182729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 182829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 182929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_RCVD: 183029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* 183129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * For OpenBSD and NetBSD, this is real ugly. The (mbuf *) 183229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * nam that is passed (by soreceive()) is the int flags cast 183329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen * as a (mbuf *) yuck! 183429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen */ 183529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp_usr_recvd(so, (int)((long)nam)); 183629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 183729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 183829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_SEND: 183929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen /* Flags are ignored */ 184029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_send(so, 0, m, nam, control, p); 184129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 184229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_ABORT: 184329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_abort(so); 184429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 184529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen 184629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_SENSE: 184729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = 0; 184829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 184929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_RCVOOB: 185029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT); 185129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = EAFNOSUPPORT; 185229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 185329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_SENDOOB: 185429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP6_USRREQ, EAFNOSUPPORT); 185529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = EAFNOSUPPORT; 185629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 185729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_PEERADDR: 185829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_getpeeraddr(so, nam); 185929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 186029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_SOCKADDR: 186129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = sctp6_in6getaddr(so, nam); 186229f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 186329f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen case PRU_SLOWTIMO: 186429f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen error = 0; 186529f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 186629f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen default: 186729f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen break; 186829f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen } 186929f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen return (error); 187029f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen} 187129f1aa98c8f38d5c1bb1765358f1edd541250d96tuexen#endif 1872c5e505da69d2f4a94b68ccdf8fcbd336110ff77ctuexen#endif 1873