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