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 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /* Copyright (c) 1990 Mentat Inc. */
  26 
  27 #include <sys/types.h>
  28 #include <sys/stream.h>
  29 #include <sys/strsun.h>
  30 #define _SUN_TPI_VERSION 2
  31 #include <sys/tihdr.h>
  32 #include <sys/xti_inet.h>
  33 #include <sys/ucred.h>
  34 #include <sys/zone.h>
  35 #include <sys/ddi.h>
  36 #include <sys/sunddi.h>
  37 #include <sys/cmn_err.h>
  38 #include <sys/debug.h>
  39 #include <sys/atomic.h>
  40 #include <sys/policy.h>
  41 
  42 #include <sys/systm.h>
  43 #include <sys/param.h>
 
 
 602                 case SO_DEBUG:
 603                         *i1 = connp->conn_debug ? SO_DEBUG : 0;
 604                         break;  /* goto sizeof (int) option return */
 605                 case SO_KEEPALIVE:
 606                         *i1 = connp->conn_keepalive ? SO_KEEPALIVE : 0;
 607                         break;
 608                 case SO_LINGER: {
 609                         struct linger *lgr = (struct linger *)ptr;
 610 
 611                         lgr->l_onoff = connp->conn_linger ? SO_LINGER : 0;
 612                         lgr->l_linger = connp->conn_lingertime;
 613                         }
 614                         return (sizeof (struct linger));
 615 
 616                 case SO_OOBINLINE:
 617                         *i1 = connp->conn_oobinline ? SO_OOBINLINE : 0;
 618                         break;
 619                 case SO_REUSEADDR:
 620                         *i1 = connp->conn_reuseaddr ? SO_REUSEADDR : 0;
 621                         break;  /* goto sizeof (int) option return */
 622                 case SO_TYPE:
 623                         *i1 = connp->conn_so_type;
 624                         break;  /* goto sizeof (int) option return */
 625                 case SO_DONTROUTE:
 626                         *i1 = (ixa->ixa_flags & IXAF_DONTROUTE) ?
 627                             SO_DONTROUTE : 0;
 628                         break;  /* goto sizeof (int) option return */
 629                 case SO_USELOOPBACK:
 630                         *i1 = connp->conn_useloopback ? SO_USELOOPBACK : 0;
 631                         break;  /* goto sizeof (int) option return */
 632                 case SO_BROADCAST:
 633                         *i1 = connp->conn_broadcast ? SO_BROADCAST : 0;
 634                         break;  /* goto sizeof (int) option return */
 635 
 636                 case SO_SNDBUF:
 637                         *i1 = connp->conn_sndbuf;
 638                         break;  /* goto sizeof (int) option return */
 639                 case SO_RCVBUF:
 640                         *i1 = connp->conn_rcvbuf;
 641                         break;  /* goto sizeof (int) option return */
 
1169         return (0);
1170 }
1171 
1172 /* Handle IPPROTO_IP */
1173 static int
1174 conn_opt_set_ip(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
1175     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
1176 {
1177         conn_t          *connp = coa->coa_connp;
1178         ip_xmit_attr_t  *ixa = coa->coa_ixa;
1179         ip_pkt_t        *ipp = coa->coa_ipp;
1180         int             *i1 = (int *)invalp;
1181         boolean_t       onoff = (*i1 == 0) ? 0 : 1;
1182         ipaddr_t        addr = (ipaddr_t)*i1;
1183         uint_t          ifindex;
1184         zoneid_t        zoneid = IPCL_ZONEID(connp);
1185         ipif_t          *ipif;
1186         ip_stack_t      *ipst = connp->conn_netstack->netstack_ip;
1187         int             error;
1188 
1189         if (connp->conn_family != AF_INET)
1190                 return (EINVAL);
1191 
1192         switch (name) {
1193         case IP_TTL:
1194                 /* Don't allow zero */
1195                 if (*i1 < 1 || *i1 > 255)
1196                         return (EINVAL);
1197                 break;
1198         case IP_MULTICAST_IF:
1199                 if (addr == INADDR_ANY) {
1200                         /* Clear */
1201                         ifindex = 0;
1202                         break;
1203                 }
1204                 ipif = ipif_lookup_addr(addr, NULL, zoneid, ipst);
1205                 if (ipif == NULL)
1206                         return (EHOSTUNREACH);
1207                 /* not supported by the virtual network iface */
1208                 if (IS_VNI(ipif->ipif_ill)) {
1209                         ipif_refrele(ipif);
1210                         return (EINVAL);
 
 | 
 
 
   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 /*
  23  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2016 Joyent, Inc.
  25  */
  26 /* Copyright (c) 1990 Mentat Inc. */
  27 
  28 #include <sys/types.h>
  29 #include <sys/stream.h>
  30 #include <sys/strsun.h>
  31 #define _SUN_TPI_VERSION 2
  32 #include <sys/tihdr.h>
  33 #include <sys/xti_inet.h>
  34 #include <sys/ucred.h>
  35 #include <sys/zone.h>
  36 #include <sys/ddi.h>
  37 #include <sys/sunddi.h>
  38 #include <sys/cmn_err.h>
  39 #include <sys/debug.h>
  40 #include <sys/atomic.h>
  41 #include <sys/policy.h>
  42 
  43 #include <sys/systm.h>
  44 #include <sys/param.h>
 
 
 603                 case SO_DEBUG:
 604                         *i1 = connp->conn_debug ? SO_DEBUG : 0;
 605                         break;  /* goto sizeof (int) option return */
 606                 case SO_KEEPALIVE:
 607                         *i1 = connp->conn_keepalive ? SO_KEEPALIVE : 0;
 608                         break;
 609                 case SO_LINGER: {
 610                         struct linger *lgr = (struct linger *)ptr;
 611 
 612                         lgr->l_onoff = connp->conn_linger ? SO_LINGER : 0;
 613                         lgr->l_linger = connp->conn_lingertime;
 614                         }
 615                         return (sizeof (struct linger));
 616 
 617                 case SO_OOBINLINE:
 618                         *i1 = connp->conn_oobinline ? SO_OOBINLINE : 0;
 619                         break;
 620                 case SO_REUSEADDR:
 621                         *i1 = connp->conn_reuseaddr ? SO_REUSEADDR : 0;
 622                         break;  /* goto sizeof (int) option return */
 623                 case SO_REUSEPORT:
 624                         *i1 = connp->conn_reuseport;
 625                         break;  /* goto sizeof (int) option return */
 626                 case SO_TYPE:
 627                         *i1 = connp->conn_so_type;
 628                         break;  /* goto sizeof (int) option return */
 629                 case SO_DONTROUTE:
 630                         *i1 = (ixa->ixa_flags & IXAF_DONTROUTE) ?
 631                             SO_DONTROUTE : 0;
 632                         break;  /* goto sizeof (int) option return */
 633                 case SO_USELOOPBACK:
 634                         *i1 = connp->conn_useloopback ? SO_USELOOPBACK : 0;
 635                         break;  /* goto sizeof (int) option return */
 636                 case SO_BROADCAST:
 637                         *i1 = connp->conn_broadcast ? SO_BROADCAST : 0;
 638                         break;  /* goto sizeof (int) option return */
 639 
 640                 case SO_SNDBUF:
 641                         *i1 = connp->conn_sndbuf;
 642                         break;  /* goto sizeof (int) option return */
 643                 case SO_RCVBUF:
 644                         *i1 = connp->conn_rcvbuf;
 645                         break;  /* goto sizeof (int) option return */
 
1173         return (0);
1174 }
1175 
1176 /* Handle IPPROTO_IP */
1177 static int
1178 conn_opt_set_ip(conn_opt_arg_t *coa, t_scalar_t name, uint_t inlen,
1179     uchar_t *invalp, boolean_t checkonly, cred_t *cr)
1180 {
1181         conn_t          *connp = coa->coa_connp;
1182         ip_xmit_attr_t  *ixa = coa->coa_ixa;
1183         ip_pkt_t        *ipp = coa->coa_ipp;
1184         int             *i1 = (int *)invalp;
1185         boolean_t       onoff = (*i1 == 0) ? 0 : 1;
1186         ipaddr_t        addr = (ipaddr_t)*i1;
1187         uint_t          ifindex;
1188         zoneid_t        zoneid = IPCL_ZONEID(connp);
1189         ipif_t          *ipif;
1190         ip_stack_t      *ipst = connp->conn_netstack->netstack_ip;
1191         int             error;
1192 
1193         if (connp->conn_family == AF_INET6 &&
1194             connp->conn_ipversion == IPV4_VERSION) {
1195                 /*
1196                  * Allow certain IPv4 options to be set on an AF_INET6 socket
1197                  * if the connection is still IPv4.
1198                  */
1199                 switch (name) {
1200                 case IP_TOS:
1201                 case T_IP_TOS:
1202                 case IP_TTL:
1203                 case IP_DONTFRAG:
1204                         break;
1205                 default:
1206                         return (EINVAL);
1207                 }
1208         } else if (connp->conn_family != AF_INET) {
1209                 return (EINVAL);
1210         }
1211 
1212         switch (name) {
1213         case IP_TTL:
1214                 /* Don't allow zero */
1215                 if (*i1 < 1 || *i1 > 255)
1216                         return (EINVAL);
1217                 break;
1218         case IP_MULTICAST_IF:
1219                 if (addr == INADDR_ANY) {
1220                         /* Clear */
1221                         ifindex = 0;
1222                         break;
1223                 }
1224                 ipif = ipif_lookup_addr(addr, NULL, zoneid, ipst);
1225                 if (ipif == NULL)
1226                         return (EHOSTUNREACH);
1227                 /* not supported by the virtual network iface */
1228                 if (IS_VNI(ipif->ipif_ill)) {
1229                         ipif_refrele(ipif);
1230                         return (EINVAL);
 
 |