4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 */
25 /* Copyright (c) 1990 Mentat Inc. */
26
27 #include <sys/types.h>
28 #include <sys/stream.h>
29 #include <sys/stropts.h>
30 #include <sys/strlog.h>
31 #include <sys/strsun.h>
32 #define _SUN_TPI_VERSION 2
33 #include <sys/tihdr.h>
34 #include <sys/timod.h>
35 #include <sys/ddi.h>
36 #include <sys/sunddi.h>
37 #include <sys/strsubr.h>
38 #include <sys/suntpi.h>
39 #include <sys/xti_inet.h>
40 #include <sys/kmem.h>
41 #include <sys/cred_impl.h>
42 #include <sys/policy.h>
43 #include <sys/priv.h>
2697 ASSERT(is_absreq_failure == 0);
2698
2699 mutex_enter(&connp->conn_lock);
2700 /*
2701 * If laddr is unspecified then we look at sin6_src_id.
2702 * We will give precedence to a source address set with IPV6_PKTINFO
2703 * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
2704 * want ip_attr_connect to select a source (since it can fail) when
2705 * IPV6_PKTINFO is specified.
2706 * If this doesn't result in a source address then we get a source
2707 * from ip_attr_connect() below.
2708 */
2709 v6src = connp->conn_saddr_v6;
2710 if (sin != NULL) {
2711 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
2712 dstport = sin->sin_port;
2713 flowinfo = 0;
2714 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2715 ixa->ixa_flags |= IXAF_IS_IPV4;
2716 } else if (sin6 != NULL) {
2717 v6dst = sin6->sin6_addr;
2718 dstport = sin6->sin6_port;
2719 flowinfo = sin6->sin6_flowinfo;
2720 srcid = sin6->__sin6_src_id;
2721 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
2722 ixa->ixa_scopeid = sin6->sin6_scope_id;
2723 ixa->ixa_flags |= IXAF_SCOPEID_SET;
2724 } else {
2725 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2726 }
2727 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
2728 ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
2729 connp->conn_netstack);
2730 }
2731 if (IN6_IS_ADDR_V4MAPPED(&v6dst))
2732 ixa->ixa_flags |= IXAF_IS_IPV4;
2733 else
2734 ixa->ixa_flags &= ~IXAF_IS_IPV4;
2735 } else {
2736 /* Connected case */
2737 v6dst = connp->conn_faddr_v6;
2738 dstport = connp->conn_fport;
2739 flowinfo = connp->conn_flowinfo;
2740 }
2741 mutex_exit(&connp->conn_lock);
2742
2743 /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
2744 if (ipp->ipp_fields & IPPF_ADDR) {
2745 if (ixa->ixa_flags & IXAF_IS_IPV4) {
2746 if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2747 v6src = ipp->ipp_addr;
2748 } else {
2749 if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2750 v6src = ipp->ipp_addr;
2751 }
2752 }
2753
2754 ip_attr_nexthop(ipp, ixa, &v6dst, &v6nexthop);
3705 goto ud_error;
3706 }
3707
3708 /* In case previous destination was multicast or multirt */
3709 ip_attr_newdst(ixa);
3710
3711 /*
3712 * If laddr is unspecified then we look at sin6_src_id.
3713 * We will give precedence to a source address set with IPV6_PKTINFO
3714 * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
3715 * want ip_attr_connect to select a source (since it can fail) when
3716 * IPV6_PKTINFO is specified.
3717 * If this doesn't result in a source address then we get a source
3718 * from ip_attr_connect() below.
3719 */
3720 v6src = connp->conn_saddr_v6;
3721 if (sin != NULL) {
3722 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
3723 dstport = sin->sin_port;
3724 flowinfo = 0;
3725 srcid = 0;
3726 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3727 if (srcid != 0 && V4_PART_OF_V6(&v6src) == INADDR_ANY) {
3728 ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3729 connp->conn_netstack);
3730 }
3731 ixa->ixa_flags |= IXAF_IS_IPV4;
3732 } else {
3733 v6dst = sin6->sin6_addr;
3734 dstport = sin6->sin6_port;
3735 flowinfo = sin6->sin6_flowinfo;
3736 srcid = sin6->__sin6_src_id;
3737 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
3738 ixa->ixa_scopeid = sin6->sin6_scope_id;
3739 ixa->ixa_flags |= IXAF_SCOPEID_SET;
3740 } else {
3741 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3742 }
3743 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
3744 ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3745 connp->conn_netstack);
3746 }
3747 if (IN6_IS_ADDR_V4MAPPED(&v6dst))
3748 ixa->ixa_flags |= IXAF_IS_IPV4;
3749 else
3750 ixa->ixa_flags &= ~IXAF_IS_IPV4;
3751 }
3752 /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
3753 if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
3754 ip_pkt_t *ipp = &connp->conn_xmit_ipp;
3755
3756 if (ixa->ixa_flags & IXAF_IS_IPV4) {
3757 if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3758 v6src = ipp->ipp_addr;
3759 } else {
3760 if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3761 v6src = ipp->ipp_addr;
3762 }
3763 }
3764
3765 ip_attr_nexthop(&connp->conn_xmit_ipp, ixa, &v6dst, &v6nexthop);
3766 mutex_exit(&connp->conn_lock);
3767
3768 error = ip_attr_connect(connp, ixa, &v6src, &v6dst, &v6nexthop, dstport,
3769 &v6src, NULL, IPDF_ALLOW_MCBC | IPDF_VERIFY_DST | IPDF_IPSEC);
3770 switch (error) {
3771 case 0:
5509 udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
5510 cred_t *cr, pid_t pid)
5511 {
5512 sin6_t *sin6;
5513 sin_t *sin;
5514 in6_addr_t v6dst;
5515 ipaddr_t v4dst;
5516 uint16_t dstport;
5517 uint32_t flowinfo;
5518 udp_fanout_t *udpf;
5519 udp_t *udp, *udp1;
5520 ushort_t ipversion;
5521 udp_stack_t *us;
5522 int error;
5523 conn_t *connp1;
5524 ip_xmit_attr_t *ixa;
5525 ip_xmit_attr_t *oldixa;
5526 uint_t scopeid = 0;
5527 uint_t srcid = 0;
5528 in6_addr_t v6src = connp->conn_saddr_v6;
5529
5530 udp = connp->conn_udp;
5531 us = udp->udp_us;
5532
5533 /*
5534 * Address has been verified by the caller
5535 */
5536 switch (len) {
5537 default:
5538 /*
5539 * Should never happen
5540 */
5541 return (EINVAL);
5542
5543 case sizeof (sin_t):
5544 sin = (sin_t *)sa;
5545 v4dst = sin->sin_addr.s_addr;
5546 dstport = sin->sin_port;
5547 IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
5548 ASSERT(connp->conn_ipversion == IPV4_VERSION);
5549 ipversion = IPV4_VERSION;
5550 break;
5551
5552 case sizeof (sin6_t):
5553 sin6 = (sin6_t *)sa;
5554 v6dst = sin6->sin6_addr;
5555 dstport = sin6->sin6_port;
5556 srcid = sin6->__sin6_src_id;
5557 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
5558 ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
5559 connp->conn_netstack);
5560 }
5561 if (IN6_IS_ADDR_V4MAPPED(&v6dst)) {
5562 if (connp->conn_ipv6_v6only)
5563 return (EADDRNOTAVAIL);
5564
5565 /*
5566 * Destination adress is mapped IPv6 address.
5567 * Source bound address should be unspecified or
5568 * IPv6 mapped address as well.
5569 */
5570 if (!IN6_IS_ADDR_UNSPECIFIED(
5571 &connp->conn_bound_addr_v6) &&
5572 !IN6_IS_ADDR_V4MAPPED(&connp->conn_bound_addr_v6)) {
5573 return (EADDRNOTAVAIL);
5574 }
5575 IN6_V4MAPPED_TO_IPADDR(&v6dst, v4dst);
5576 ipversion = IPV4_VERSION;
5577 flowinfo = 0;
5578 } else {
5579 ipversion = IPV6_VERSION;
5580 flowinfo = sin6->sin6_flowinfo;
5581 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
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 * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
25 */
26 /* Copyright (c) 1990 Mentat Inc. */
27
28 #include <sys/types.h>
29 #include <sys/stream.h>
30 #include <sys/stropts.h>
31 #include <sys/strlog.h>
32 #include <sys/strsun.h>
33 #define _SUN_TPI_VERSION 2
34 #include <sys/tihdr.h>
35 #include <sys/timod.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/strsubr.h>
39 #include <sys/suntpi.h>
40 #include <sys/xti_inet.h>
41 #include <sys/kmem.h>
42 #include <sys/cred_impl.h>
43 #include <sys/policy.h>
44 #include <sys/priv.h>
2698 ASSERT(is_absreq_failure == 0);
2699
2700 mutex_enter(&connp->conn_lock);
2701 /*
2702 * If laddr is unspecified then we look at sin6_src_id.
2703 * We will give precedence to a source address set with IPV6_PKTINFO
2704 * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
2705 * want ip_attr_connect to select a source (since it can fail) when
2706 * IPV6_PKTINFO is specified.
2707 * If this doesn't result in a source address then we get a source
2708 * from ip_attr_connect() below.
2709 */
2710 v6src = connp->conn_saddr_v6;
2711 if (sin != NULL) {
2712 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
2713 dstport = sin->sin_port;
2714 flowinfo = 0;
2715 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2716 ixa->ixa_flags |= IXAF_IS_IPV4;
2717 } else if (sin6 != NULL) {
2718 boolean_t v4mapped;
2719
2720 v6dst = sin6->sin6_addr;
2721 dstport = sin6->sin6_port;
2722 flowinfo = sin6->sin6_flowinfo;
2723 srcid = sin6->__sin6_src_id;
2724 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
2725 ixa->ixa_scopeid = sin6->sin6_scope_id;
2726 ixa->ixa_flags |= IXAF_SCOPEID_SET;
2727 } else {
2728 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
2729 }
2730 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
2731 if (v4mapped)
2732 ixa->ixa_flags |= IXAF_IS_IPV4;
2733 else
2734 ixa->ixa_flags &= ~IXAF_IS_IPV4;
2735 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
2736 if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
2737 v4mapped, connp->conn_netstack)) {
2738 /* Mismatch - v4mapped/v6 specified by srcid. */
2739 mutex_exit(&connp->conn_lock);
2740 error = EADDRNOTAVAIL;
2741 goto failed; /* Does freemsg() and mib. */
2742 }
2743 }
2744 } else {
2745 /* Connected case */
2746 v6dst = connp->conn_faddr_v6;
2747 dstport = connp->conn_fport;
2748 flowinfo = connp->conn_flowinfo;
2749 }
2750 mutex_exit(&connp->conn_lock);
2751
2752 /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
2753 if (ipp->ipp_fields & IPPF_ADDR) {
2754 if (ixa->ixa_flags & IXAF_IS_IPV4) {
2755 if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2756 v6src = ipp->ipp_addr;
2757 } else {
2758 if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
2759 v6src = ipp->ipp_addr;
2760 }
2761 }
2762
2763 ip_attr_nexthop(ipp, ixa, &v6dst, &v6nexthop);
3714 goto ud_error;
3715 }
3716
3717 /* In case previous destination was multicast or multirt */
3718 ip_attr_newdst(ixa);
3719
3720 /*
3721 * If laddr is unspecified then we look at sin6_src_id.
3722 * We will give precedence to a source address set with IPV6_PKTINFO
3723 * (aka IPPF_ADDR) but that is handled in build_hdrs. However, we don't
3724 * want ip_attr_connect to select a source (since it can fail) when
3725 * IPV6_PKTINFO is specified.
3726 * If this doesn't result in a source address then we get a source
3727 * from ip_attr_connect() below.
3728 */
3729 v6src = connp->conn_saddr_v6;
3730 if (sin != NULL) {
3731 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &v6dst);
3732 dstport = sin->sin_port;
3733 flowinfo = 0;
3734 /* Don't bother with ip_srcid_find_id(), but indicate anyway. */
3735 srcid = 0;
3736 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3737 ixa->ixa_flags |= IXAF_IS_IPV4;
3738 } else {
3739 boolean_t v4mapped;
3740
3741 v6dst = sin6->sin6_addr;
3742 dstport = sin6->sin6_port;
3743 flowinfo = sin6->sin6_flowinfo;
3744 srcid = sin6->__sin6_src_id;
3745 if (IN6_IS_ADDR_LINKSCOPE(&v6dst) && sin6->sin6_scope_id != 0) {
3746 ixa->ixa_scopeid = sin6->sin6_scope_id;
3747 ixa->ixa_flags |= IXAF_SCOPEID_SET;
3748 } else {
3749 ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
3750 }
3751 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
3752 if (v4mapped)
3753 ixa->ixa_flags |= IXAF_IS_IPV4;
3754 else
3755 ixa->ixa_flags &= ~IXAF_IS_IPV4;
3756 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
3757 if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
3758 v4mapped, connp->conn_netstack)) {
3759 /* Mismatched v4mapped/v6 specified by srcid. */
3760 mutex_exit(&connp->conn_lock);
3761 error = EADDRNOTAVAIL;
3762 goto ud_error;
3763 }
3764 }
3765 }
3766 /* Handle IP_PKTINFO/IPV6_PKTINFO setting source address. */
3767 if (connp->conn_xmit_ipp.ipp_fields & IPPF_ADDR) {
3768 ip_pkt_t *ipp = &connp->conn_xmit_ipp;
3769
3770 if (ixa->ixa_flags & IXAF_IS_IPV4) {
3771 if (IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3772 v6src = ipp->ipp_addr;
3773 } else {
3774 if (!IN6_IS_ADDR_V4MAPPED(&ipp->ipp_addr))
3775 v6src = ipp->ipp_addr;
3776 }
3777 }
3778
3779 ip_attr_nexthop(&connp->conn_xmit_ipp, ixa, &v6dst, &v6nexthop);
3780 mutex_exit(&connp->conn_lock);
3781
3782 error = ip_attr_connect(connp, ixa, &v6src, &v6dst, &v6nexthop, dstport,
3783 &v6src, NULL, IPDF_ALLOW_MCBC | IPDF_VERIFY_DST | IPDF_IPSEC);
3784 switch (error) {
3785 case 0:
5523 udp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
5524 cred_t *cr, pid_t pid)
5525 {
5526 sin6_t *sin6;
5527 sin_t *sin;
5528 in6_addr_t v6dst;
5529 ipaddr_t v4dst;
5530 uint16_t dstport;
5531 uint32_t flowinfo;
5532 udp_fanout_t *udpf;
5533 udp_t *udp, *udp1;
5534 ushort_t ipversion;
5535 udp_stack_t *us;
5536 int error;
5537 conn_t *connp1;
5538 ip_xmit_attr_t *ixa;
5539 ip_xmit_attr_t *oldixa;
5540 uint_t scopeid = 0;
5541 uint_t srcid = 0;
5542 in6_addr_t v6src = connp->conn_saddr_v6;
5543 boolean_t v4mapped;
5544
5545 udp = connp->conn_udp;
5546 us = udp->udp_us;
5547
5548 /*
5549 * Address has been verified by the caller
5550 */
5551 switch (len) {
5552 default:
5553 /*
5554 * Should never happen
5555 */
5556 return (EINVAL);
5557
5558 case sizeof (sin_t):
5559 sin = (sin_t *)sa;
5560 v4dst = sin->sin_addr.s_addr;
5561 dstport = sin->sin_port;
5562 IN6_IPADDR_TO_V4MAPPED(v4dst, &v6dst);
5563 ASSERT(connp->conn_ipversion == IPV4_VERSION);
5564 ipversion = IPV4_VERSION;
5565 break;
5566
5567 case sizeof (sin6_t):
5568 sin6 = (sin6_t *)sa;
5569 v6dst = sin6->sin6_addr;
5570 dstport = sin6->sin6_port;
5571 srcid = sin6->__sin6_src_id;
5572 v4mapped = IN6_IS_ADDR_V4MAPPED(&v6dst);
5573 if (srcid != 0 && IN6_IS_ADDR_UNSPECIFIED(&v6src)) {
5574 if (ip_srcid_find_id(srcid, &v6src, IPCL_ZONEID(connp),
5575 v4mapped, connp->conn_netstack)) {
5576 /* Mismatch v4mapped/v6 specified by srcid. */
5577 return (EADDRNOTAVAIL);
5578 }
5579 }
5580 if (v4mapped) {
5581 if (connp->conn_ipv6_v6only)
5582 return (EADDRNOTAVAIL);
5583
5584 /*
5585 * Destination adress is mapped IPv6 address.
5586 * Source bound address should be unspecified or
5587 * IPv6 mapped address as well.
5588 */
5589 if (!IN6_IS_ADDR_UNSPECIFIED(
5590 &connp->conn_bound_addr_v6) &&
5591 !IN6_IS_ADDR_V4MAPPED(&connp->conn_bound_addr_v6)) {
5592 return (EADDRNOTAVAIL);
5593 }
5594 IN6_V4MAPPED_TO_IPADDR(&v6dst, v4dst);
5595 ipversion = IPV4_VERSION;
5596 flowinfo = 0;
5597 } else {
5598 ipversion = IPV6_VERSION;
5599 flowinfo = sin6->sin6_flowinfo;
5600 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
|