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, 66 NULL 67 }; 68 69 /* 70 * Creates a sdp socket data structure. 71 */ 72 /* ARGSUSED */ 73 struct sonode * 74 socksdp_create(struct sockparams *sp, int family, int type, int protocol, 75 int version, int sflags, int *errorp, cred_t *cr) 76 { 77 struct sonode *so; 78 int kmflags = (sflags & SOCKET_NOSLEEP) ? KM_NOSLEEP : KM_SLEEP; 79 80 dprint(4, ("Inside sosdp_create: domain:%d proto:%d type:%d", 81 family, protocol, type)); 82 83 *errorp = 0; 84 if (is_system_labeled()) { 85 *errorp = EOPNOTSUPP; 86 return (NULL); 87 } 88 89 if (version == SOV_STREAM) { 90 *errorp = EINVAL; 91 return (NULL); 92 } 93 94 /* 95 * We only support one type of SDP socket. Let sotpi_create() 96 * handle all other cases, such as raw socket. 97 */ 98 if (!(family == AF_INET || family == AF_INET6) || 99 !(type == SOCK_STREAM)) { 100 *errorp = EINVAL; 101 return (NULL); 102 } 103 104 so = kmem_cache_alloc(socket_cache, kmflags); 105 if (so == NULL) { 106 *errorp = ENOMEM; 107 return (NULL); 108 } 109 110 sonode_init(so, sp, family, type, protocol, &sosdp_sonodeops); 111 so->so_pollev |= SO_POLLEV_ALWAYS; 112 113 dprint(2, ("sosdp_create: %p domain %d type %d\n", (void *)so, family, 114 type)); 115 116 if (version == SOV_DEFAULT) { 117 version = so_default_version; 118 } 119 so->so_version = (short)version; 120 121 /* 122 * set the default values to be INFPSZ 123 * if a protocol desires it can change the value later 124 */ 125 so->so_proto_props.sopp_rxhiwat = SOCKET_RECVHIWATER; 126 so->so_proto_props.sopp_rxlowat = SOCKET_RECVLOWATER; 127 so->so_proto_props.sopp_maxpsz = INFPSZ; 128 so->so_proto_props.sopp_maxblk = INFPSZ; 129 130 return (so); 131 } 132 133 static void 134 socksdp_destroy(struct sonode *so) 135 { 136 ASSERT(so->so_ops == &sosdp_sonodeops); 137 138 sosdp_fini(so, CRED()); 139 140 kmem_cache_free(socket_cache, so); 141 } 142 143 int 144 _init(void) 145 { 146 return (mod_install(&modlinkage)); 147 } 148 149 int 150 _fini(void) 151 { 152 return (mod_remove(&modlinkage)); 153 } 154 155 int 156 _info(struct modinfo *modinfop) 157 { 158 return (mod_info(&modlinkage, modinfop)); 159 }