7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, Joyent Inc. All rights reserved.
25 * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
26 * Copyright (c) 2013 by Delphix. All rights reserved.
27 */
28 /* Copyright (c) 1990 Mentat Inc. */
29
30 #include <sys/types.h>
31 #include <sys/stream.h>
32 #include <sys/strsun.h>
33 #include <sys/strsubr.h>
34 #include <sys/stropts.h>
35 #include <sys/strlog.h>
36 #define _SUN_TPI_VERSION 2
37 #include <sys/tihdr.h>
38 #include <sys/timod.h>
39 #include <sys/ddi.h>
40 #include <sys/sunddi.h>
41 #include <sys/suntpi.h>
42 #include <sys/xti_inet.h>
43 #include <sys/cmn_err.h>
44 #include <sys/debug.h>
45 #include <sys/sdt.h>
46 #include <sys/vtrace.h>
1566 /*
1567 * SunOS 4.x and 4.3 BSD allow an application
1568 * to connect a TCP socket to INADDR_ANY.
1569 * When they do this, the kernel picks the
1570 * address of one interface and uses it
1571 * instead. The kernel usually ends up
1572 * picking the address of the loopback
1573 * interface. This is an undocumented feature.
1574 * However, we provide the same thing here
1575 * in order to have source and binary
1576 * compatibility with SunOS 4.x.
1577 * Update the T_CONN_REQ (sin/sin6) since it is used to
1578 * generate the T_CONN_CON.
1579 */
1580 dstaddr = htonl(INADDR_LOOPBACK);
1581 *dstaddrp = dstaddr;
1582 }
1583
1584 /* Handle __sin6_src_id if socket not bound to an IP address */
1585 if (srcid != 0 && connp->conn_laddr_v4 == INADDR_ANY) {
1586 ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
1587 IPCL_ZONEID(connp), tcps->tcps_netstack);
1588 connp->conn_saddr_v6 = connp->conn_laddr_v6;
1589 }
1590
1591 IN6_IPADDR_TO_V4MAPPED(dstaddr, &connp->conn_faddr_v6);
1592 connp->conn_fport = dstport;
1593
1594 /*
1595 * At this point the remote destination address and remote port fields
1596 * in the tcp-four-tuple have been filled in the tcp structure. Now we
1597 * have to see which state tcp was in so we can take appropriate action.
1598 */
1599 if (tcp->tcp_state == TCPS_IDLE) {
1600 /*
1601 * We support a quick connect capability here, allowing
1602 * clients to transition directly from IDLE to SYN_SENT
1603 * tcp_bindi will pick an unused port, insert the connection
1604 * in the bind hash and transition to BOUND state.
1605 */
1606 lport = tcp_update_next_port(tcps->tcps_next_port_to_try,
1607 tcp, B_TRUE);
1648
1649 /*
1650 * If we're here, it means that the destination address is a native
1651 * IPv6 address. Return an error if conn_ipversion is not IPv6. A
1652 * reason why it might not be IPv6 is if the socket was bound to an
1653 * IPv4-mapped IPv6 address.
1654 */
1655 if (connp->conn_ipversion != IPV6_VERSION)
1656 return (-TBADADDR);
1657
1658 /*
1659 * Interpret a zero destination to mean loopback.
1660 * Update the T_CONN_REQ (sin/sin6) since it is used to
1661 * generate the T_CONN_CON.
1662 */
1663 if (IN6_IS_ADDR_UNSPECIFIED(dstaddrp))
1664 *dstaddrp = ipv6_loopback;
1665
1666 /* Handle __sin6_src_id if socket not bound to an IP address */
1667 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1668 ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
1669 IPCL_ZONEID(connp), tcps->tcps_netstack);
1670 connp->conn_saddr_v6 = connp->conn_laddr_v6;
1671 }
1672
1673 /*
1674 * Take care of the scope_id now.
1675 */
1676 if (scope_id != 0 && IN6_IS_ADDR_LINKSCOPE(dstaddrp)) {
1677 connp->conn_ixa->ixa_flags |= IXAF_SCOPEID_SET;
1678 connp->conn_ixa->ixa_scopeid = scope_id;
1679 } else {
1680 connp->conn_ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
1681 }
1682
1683 connp->conn_flowinfo = flowinfo;
1684 connp->conn_faddr_v6 = *dstaddrp;
1685 connp->conn_fport = dstport;
1686
1687 /*
1688 * At this point the remote destination address and remote port fields
1689 * in the tcp-four-tuple have been filled in the tcp structure. Now we
|
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2011, Joyent Inc. All rights reserved.
25 * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
26 * Copyright (c) 2013 by Delphix. All rights reserved.
27 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
28 */
29 /* Copyright (c) 1990 Mentat Inc. */
30
31 #include <sys/types.h>
32 #include <sys/stream.h>
33 #include <sys/strsun.h>
34 #include <sys/strsubr.h>
35 #include <sys/stropts.h>
36 #include <sys/strlog.h>
37 #define _SUN_TPI_VERSION 2
38 #include <sys/tihdr.h>
39 #include <sys/timod.h>
40 #include <sys/ddi.h>
41 #include <sys/sunddi.h>
42 #include <sys/suntpi.h>
43 #include <sys/xti_inet.h>
44 #include <sys/cmn_err.h>
45 #include <sys/debug.h>
46 #include <sys/sdt.h>
47 #include <sys/vtrace.h>
1567 /*
1568 * SunOS 4.x and 4.3 BSD allow an application
1569 * to connect a TCP socket to INADDR_ANY.
1570 * When they do this, the kernel picks the
1571 * address of one interface and uses it
1572 * instead. The kernel usually ends up
1573 * picking the address of the loopback
1574 * interface. This is an undocumented feature.
1575 * However, we provide the same thing here
1576 * in order to have source and binary
1577 * compatibility with SunOS 4.x.
1578 * Update the T_CONN_REQ (sin/sin6) since it is used to
1579 * generate the T_CONN_CON.
1580 */
1581 dstaddr = htonl(INADDR_LOOPBACK);
1582 *dstaddrp = dstaddr;
1583 }
1584
1585 /* Handle __sin6_src_id if socket not bound to an IP address */
1586 if (srcid != 0 && connp->conn_laddr_v4 == INADDR_ANY) {
1587 if (!ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
1588 IPCL_ZONEID(connp), B_TRUE, tcps->tcps_netstack)) {
1589 /* Mismatch - conn_laddr_v6 would be v6 address. */
1590 return (EADDRNOTAVAIL);
1591 }
1592 connp->conn_saddr_v6 = connp->conn_laddr_v6;
1593 }
1594
1595 IN6_IPADDR_TO_V4MAPPED(dstaddr, &connp->conn_faddr_v6);
1596 connp->conn_fport = dstport;
1597
1598 /*
1599 * At this point the remote destination address and remote port fields
1600 * in the tcp-four-tuple have been filled in the tcp structure. Now we
1601 * have to see which state tcp was in so we can take appropriate action.
1602 */
1603 if (tcp->tcp_state == TCPS_IDLE) {
1604 /*
1605 * We support a quick connect capability here, allowing
1606 * clients to transition directly from IDLE to SYN_SENT
1607 * tcp_bindi will pick an unused port, insert the connection
1608 * in the bind hash and transition to BOUND state.
1609 */
1610 lport = tcp_update_next_port(tcps->tcps_next_port_to_try,
1611 tcp, B_TRUE);
1652
1653 /*
1654 * If we're here, it means that the destination address is a native
1655 * IPv6 address. Return an error if conn_ipversion is not IPv6. A
1656 * reason why it might not be IPv6 is if the socket was bound to an
1657 * IPv4-mapped IPv6 address.
1658 */
1659 if (connp->conn_ipversion != IPV6_VERSION)
1660 return (-TBADADDR);
1661
1662 /*
1663 * Interpret a zero destination to mean loopback.
1664 * Update the T_CONN_REQ (sin/sin6) since it is used to
1665 * generate the T_CONN_CON.
1666 */
1667 if (IN6_IS_ADDR_UNSPECIFIED(dstaddrp))
1668 *dstaddrp = ipv6_loopback;
1669
1670 /* Handle __sin6_src_id if socket not bound to an IP address */
1671 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&connp->conn_laddr_v6)) {
1672 if (!ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
1673 IPCL_ZONEID(connp), B_FALSE, tcps->tcps_netstack)) {
1674 /* Mismatch - conn_laddr_v6 would be v4-mapped. */
1675 return (EADDRNOTAVAIL);
1676 }
1677 connp->conn_saddr_v6 = connp->conn_laddr_v6;
1678 }
1679
1680 /*
1681 * Take care of the scope_id now.
1682 */
1683 if (scope_id != 0 && IN6_IS_ADDR_LINKSCOPE(dstaddrp)) {
1684 connp->conn_ixa->ixa_flags |= IXAF_SCOPEID_SET;
1685 connp->conn_ixa->ixa_scopeid = scope_id;
1686 } else {
1687 connp->conn_ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
1688 }
1689
1690 connp->conn_flowinfo = flowinfo;
1691 connp->conn_faddr_v6 = *dstaddrp;
1692 connp->conn_fport = dstport;
1693
1694 /*
1695 * At this point the remote destination address and remote port fields
1696 * in the tcp-four-tuple have been filled in the tcp structure. Now we
|