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 *
socksdp_create(struct sockparams * sp,int family,int type,int protocol,int version,int sflags,int * errorp,cred_t * cr)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
socksdp_destroy(struct sonode * so)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
_init(void)144 _init(void)
145 {
146 return (mod_install(&modlinkage));
147 }
148
149 int
_fini(void)150 _fini(void)
151 {
152 return (mod_remove(&modlinkage));
153 }
154
155 int
_info(struct modinfo * modinfop)156 _info(struct modinfo *modinfop)
157 {
158 return (mod_info(&modlinkage, modinfop));
159 }
160