1 /*
   2  * CDDL HEADER START
   3  *
   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 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2012 David Hoeppner.  All rights reserved.
  29  */
  30 
  31 /*
  32  * This file contains functions related to getting and setting options
  33  * thought the getsockopt and setsockopt socket functions.
  34  */
  35 
  36 #include <sys/types.h>
  37 #include <sys/stream.h>
  38 #define _SUN_TPI_VERSION 2
  39 #include <sys/tihdr.h>
  40 #include <sys/xti_xtiopt.h>
  41 #include <sys/xti_inet.h>
  42 #include <sys/policy.h>
  43 
  44 #include <inet/common.h>
  45 #include <inet/ip.h>
  46 #include <inet/optcom.h>
  47 #include <netinet/ip.h>
  48 
  49 #include <sys/cmn_err.h>
  50 
  51 #include "dccp_impl.h"
  52 
  53 static int dccp_opt_default(queue_t *, int, int, uchar_t *);
  54 
  55 /*
  56  * Supported options.
  57  */
  58 opdes_t dccp_opt_arr[] = {
  59 { SO_DEBUG, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
  60 }; 
  61 
  62 /*
  63  * Supported levels.
  64  */
  65 optlevel_t dccp_valid_levels_arr[] = {
  66         SOL_SOCKET,
  67 };
  68 
  69 #define DCCP_OPT_ARR_CNT        A_CNT(dccp_opt_arr)
  70 #define DCCP_VALID_LEVELS_CNT   A_CNT(dccp_valid_levels_arr)
  71 
  72 uint_t dccp_max_optsize;
  73 
  74 /*
  75  * Options database object.
  76  */
  77 optdb_obj_t dccp_opt_obj = {
  78         dccp_opt_default,
  79         dccp_tpi_opt_get,
  80         dccp_tpi_opt_set,
  81         DCCP_OPT_ARR_CNT,
  82         dccp_opt_arr,
  83         DCCP_VALID_LEVELS_CNT,
  84         dccp_valid_levels_arr,
  85 };
  86 
  87 /*
  88  * Default value for certain options.
  89  */
  90 int
  91 dccp_opt_default(queue_t *q, int level, int name, uchar_t *ptr)
  92 {
  93         dccp_stack_t    *dccps = Q_TO_DCCP(q)->dccp_dccps;
  94         int32_t         *il = (int32_t *)ptr;
  95 
  96         return (sizeof (int));
  97 }
  98 
  99 int
 100 dccp_opt_get(conn_t *connp, int level, int name, uchar_t *ptr)
 101 {
 102         dccp_t          *dccp = connp->conn_dccp;
 103         conn_opt_arg_t  coas;
 104         int             retval;
 105 
 106         coas.coa_connp = connp;
 107         coas.coa_ixa = connp->conn_ixa;
 108         coas.coa_ipp = &connp->conn_xmit_ipp;
 109         coas.coa_ancillary = B_FALSE;
 110         coas.coa_changed = 0;
 111 
 112         switch (level) {
 113         case SOL_SOCKET:
 114                 break;
 115         case IPPROTO_TCP:
 116                 break;
 117         case IPPROTO_IP:
 118                 break;
 119         case IPPROTO_IPV6:
 120                 break;
 121         }
 122 
 123         mutex_enter(&connp->conn_lock);
 124         retval = conn_opt_get(&coas, level, name, ptr);
 125         mutex_exit(&connp->conn_lock);
 126 
 127         return (retval);
 128 }
 129 
 130 /* ARGSUSED */
 131 int
 132 dccp_opt_set(conn_t *connp, uint_t optset_context, int level, int name,
 133     uint_t inlen, uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
 134     void *thisdg_attrs, cred_t *cr)
 135 {
 136         dccp_t          *dccp = connp->conn_dccp;
 137         dccp_stack_t    *dccps = dccp->dccp_dccps;
 138         conn_opt_arg_t  coas;
 139         int             *i1 = (int *)invalp;
 140         int             error;
 141 
 142         coas.coa_connp = connp;
 143         coas.coa_ancillary = B_FALSE;
 144         coas.coa_changed = 0;
 145 
 146         error = conn_opt_set(&coas, level, name, inlen, invalp,
 147             B_FALSE, cr);
 148         if (error !=0) {
 149                 *outlenp = 0;
 150                 return (error);
 151         }
 152 
 153         return (0);
 154 }