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 (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 #include <sys/sysmacros.h> 27 #include <sys/strsubr.h> 28 #include <sys/socket.h> 29 #include <sys/socketvar.h> 30 #include <sys/modctl.h> 31 #include <sys/cmn_err.h> 32 #include <sys/vfs.h> 33 #include <inet/sdp_itf.h> 34 #include <fs/sockfs/sockcommon.h> 35 #include "socksdp.h" 36 37 struct sonode *socksdp_create(struct sockparams *, int, int, int, 38 int, int, int *, cred_t *); 39 static void socksdp_destroy(struct sonode *); 40 41 static __smod_priv_t sosdp_priv = { 42 socksdp_create, 43 socksdp_destroy, 44 NULL 45 }; 46 47 static smod_reg_t sinfo = { 48 SOCKMOD_VERSION, 49 "socksdp", 50 SOCK_UC_VERSION, 51 SOCK_DC_VERSION, 52 NULL, 53 &sosdp_priv 54 }; 55 56 /* 57 * Module linkage information for the kernel 58 */ 59 static struct modlsockmod modlsockmod = { 60 &mod_sockmodops, "SDP socket module", &sinfo 61 }; 62 63 static struct modlinkage modlinkage = { 64 MODREV_1, 65 { &modlsockmod, NULL } 66 }; 67 68 /* 69 * Creates a sdp socket data structure. 70 */ 71 /* ARGSUSED */ 72 struct sonode * 73 socksdp_create(struct sockparams *sp, int family, int type, int protocol, 74 int version, int sflags, int *errorp, cred_t *cr) 75 { 76 struct sonode *so; 77 int kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP; 78 79 dprint(4, ("Inside sosdp_create: domain:%d proto:%d type:%d", 80 family, protocol, type)); 81 82 *errorp = 0; 83 if (is_system_labeled()) { 84 *errorp = EOPNOTSUPP; 85 return (NULL); 86 } 87 88 if (version == SOV_STREAM) { 89 *errorp = EINVAL; 90 return (NULL); 91 } 92 93 /* 94 * We only support one type of SDP socket. Let sotpi_create() 95 * handle all other cases, such as raw socket. 96 */ 97 if (!(family == AF_INET || family == AF_INET6) || 98 !(type == SOCK_STREAM)) { 99 *errorp = EINVAL; 100 return (NULL); 101 } 102 103 so = kmem_cache_alloc(socket_cache, kmflags); 104 if (so == NULL) { 105 *errorp = ENOMEM; 106 return (NULL); 107 } 108 109 sonode_init(so, sp, family, type, protocol, &sosdp_sonodeops); 110 so->so_pollev |= SO_POLLEV_ALWAYS; 111 112 dprint(2, ("sosdp_create: %p domain %d type %d\n", (void *)so, family, 113 type)); 114 115 if (version == SOV_DEFAULT) { 116 version = so_default_version; 117 } 118 so->so_version = (short)version; 119 120 /* 121 * set the default values to be INFPSZ 122 * if a protocol desires it can change the value later 123 */ 124 so->so_proto_props.sopp_rxhiwat = SOCKET_RECVHIWATER; 125 so->so_proto_props.sopp_rxlowat = SOCKET_RECVLOWATER; 126 so->so_proto_props.sopp_maxpsz = INFPSZ; 127 so->so_proto_props.sopp_maxblk = INFPSZ; 128 129 return (so); 130 } 131 132 static void 133 socksdp_destroy(struct sonode *so) 134 { 135 ASSERT(so->so_ops == &sosdp_sonodeops); 136 137 sosdp_fini(so, CRED()); 138 139 kmem_cache_free(socket_cache, so); 140 } 141 142 int 143 _init(void) 144 { 145 return (mod_install(&modlinkage)); 146 } 147 148 int 149 _fini(void) 150 { 151 return (mod_remove(&modlinkage)); 152 } 153 154 int 155 _info(struct modinfo *modinfop) 156 { 157 return (mod_info(&modlinkage, modinfop)); 158 }