Print this page
OS-5007 support SO_ATTACH_FILTER on ICMP sockets
Reviewed by: Cody Mello <melloc@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/inet/ip/icmp_opt_data.c
+++ new/usr/src/uts/common/inet/ip/icmp_opt_data.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright 2016 Joyent, Inc.
24 25 */
25 26
26 27 #include <sys/types.h>
27 28 #include <sys/stream.h>
28 29 #define _SUN_TPI_VERSION 2
29 30 #include <sys/tihdr.h>
30 31 #include <sys/socket.h>
31 32 #include <sys/xti_xtiopt.h>
32 33 #include <sys/xti_inet.h>
33 34
34 35 #include <netinet/in.h>
35 36 #include <netinet/icmp6.h>
36 37 #include <inet/common.h>
37 38 #include <netinet/ip6.h>
38 39 #include <inet/ip.h>
39 40
40 41 #include <netinet/tcp.h>
41 42 #include <netinet/ip_mroute.h>
42 43 #include <inet/optcom.h>
43 44 #include <inet/rawip_impl.h>
45 +#include <net/bpf.h>
44 46
45 47 /*
46 48 * Table of all known options handled on a ICMP protocol stack.
47 49 *
48 50 * Note: This table contains options processed by both ICMP and IP levels
49 51 * and is the superset of options that can be performed on a ICMP over IP
50 52 * stack.
51 53 */
52 54 opdes_t icmp_opt_arr[] = {
53 55
54 56 { SO_DEBUG, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
55 57 { SO_DONTROUTE, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
56 58 { SO_USELOOPBACK, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
57 59 },
58 60 { SO_BROADCAST, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
59 61 { SO_REUSEADDR, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
60 62
61 63 #ifdef SO_PROTOTYPE
62 64 /*
63 65 * icmp will only allow IPPROTO_ICMP for non-privileged streams
64 66 * that check is made on an adhoc basis.
65 67 */
66 68 { SO_PROTOTYPE, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
67 69 #endif
68 70
69 71 { SO_TYPE, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
70 72 { SO_SNDBUF, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
71 73 { SO_RCVBUF, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
72 74 { SO_SNDTIMEO, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0,
73 75 sizeof (struct timeval), 0 },
74 76 { SO_RCVTIMEO, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0,
75 77 sizeof (struct timeval), 0 },
76 78 { SO_DGRAM_ERRIND, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
77 79 0 },
78 80 { SO_TIMESTAMP, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0
|
↓ open down ↓ |
25 lines elided |
↑ open up ↑ |
79 81 },
80 82 { SO_MAC_EXEMPT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
81 83 0 },
82 84 { SO_MAC_IMPLICIT, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
83 85 0 },
84 86
85 87 { SO_ALLZONES, SOL_SOCKET, OA_R, OA_RW, OP_CONFIG, 0, sizeof (int),
86 88 0 },
87 89 { SO_DOMAIN, SOL_SOCKET, OA_R, OA_R, OP_NP, 0, sizeof (int), 0 },
88 90
91 +{ SO_ATTACH_FILTER, SOL_SOCKET, OA_W, OA_W, OP_NP, 0,
92 + sizeof (struct bpf_program), 0 },
93 +{ SO_DETACH_FILTER, SOL_SOCKET, OA_W, OA_W, OP_NP, 0, 0, 0 },
94 +
89 95 { IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
90 96 (OP_VARLEN|OP_NODEFAULT),
91 97 IP_MAX_OPT_LENGTH + IP_ADDR_LEN, -1 /* not initialized */ },
92 98 { T_IP_OPTIONS, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
93 99 (OP_VARLEN|OP_NODEFAULT),
94 100 IP_MAX_OPT_LENGTH + IP_ADDR_LEN, -1 /* not initialized */ },
95 101
96 102 { IP_HDRINCL, IPPROTO_IP, OA_R, OA_RW, OP_RAW, 0,
97 103 sizeof (int), 0 },
98 104 { IP_TOS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
99 105 { T_IP_TOS, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
100 106 { IP_TTL, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
101 107
102 108 { IP_MULTICAST_IF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0,
103 109 sizeof (struct in_addr), 0 /* INADDR_ANY */ },
104 110
105 111 { IP_MULTICAST_LOOP, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_DEF_FN,
106 112 sizeof (uchar_t), -1 /* not initialized */},
107 113
108 114 { IP_MULTICAST_TTL, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_DEF_FN,
109 115 sizeof (uchar_t), -1 /* not initialized */ },
110 116
111 117 { IP_ADD_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
112 118 sizeof (struct ip_mreq), -1 /* not initialized */ },
113 119
114 120 { IP_DROP_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
115 121 sizeof (struct ip_mreq), 0 },
116 122
117 123 { IP_BLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
118 124 sizeof (struct ip_mreq_source), -1 },
119 125
120 126 { IP_UNBLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP, OP_NODEFAULT,
121 127 sizeof (struct ip_mreq_source), -1 },
122 128
123 129 { IP_ADD_SOURCE_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP,
124 130 OP_NODEFAULT, sizeof (struct ip_mreq_source), -1 },
125 131
126 132 { IP_DROP_SOURCE_MEMBERSHIP, IPPROTO_IP, OA_X, OA_X, OP_NP,
127 133 OP_NODEFAULT, sizeof (struct ip_mreq_source), -1 },
128 134
129 135 { IP_SEC_OPT, IPPROTO_IP, OA_RW, OA_RW, OP_NP, OP_NODEFAULT,
130 136 sizeof (ipsec_req_t), -1 /* not initialized */ },
131 137
132 138 { IP_BOUND_IF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0,
133 139 sizeof (int), 0 /* no ifindex */ },
134 140
135 141 { IP_UNSPEC_SRC, IPPROTO_IP, OA_R, OA_RW, OP_RAW, 0,
136 142 sizeof (int), 0 },
137 143
138 144 { IP_BROADCAST_TTL, IPPROTO_IP, OA_R, OA_RW, OP_RAW, 0, sizeof (uchar_t),
139 145 0 /* disabled */ },
140 146
141 147 { IP_RECVIF, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
142 148
143 149 { IP_PKTINFO, IPPROTO_IP, OA_RW, OA_RW, OP_NP,
144 150 (OP_NODEFAULT|OP_VARLEN),
145 151 sizeof (struct in_pktinfo), -1 /* not initialized */ },
146 152
147 153 { IP_DONTFRAG, IPPROTO_IP, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
148 154
149 155 { IP_NEXTHOP, IPPROTO_IP, OA_R, OA_RW, OP_CONFIG, 0,
150 156 sizeof (in_addr_t), -1 /* not initialized */ },
151 157
152 158 { MRT_INIT, IPPROTO_IP, 0, OA_X, OP_CONFIG,
153 159 OP_NODEFAULT, sizeof (int),
154 160 -1 /* not initialized */ },
155 161
156 162 { MRT_DONE, IPPROTO_IP, 0, OA_X, OP_CONFIG,
157 163 OP_NODEFAULT, 0, -1 /* not initialized */ },
158 164
159 165 { MRT_ADD_VIF, IPPROTO_IP, 0, OA_X, OP_CONFIG, OP_NODEFAULT,
160 166 sizeof (struct vifctl), -1 /* not initialized */ },
161 167
162 168 { MRT_DEL_VIF, IPPROTO_IP, 0, OA_X, OP_CONFIG, OP_NODEFAULT,
163 169 sizeof (vifi_t), -1 /* not initialized */ },
164 170
165 171 { MRT_ADD_MFC, IPPROTO_IP, 0, OA_X, OP_CONFIG, OP_NODEFAULT,
166 172 sizeof (struct mfcctl), -1 /* not initialized */ },
167 173
168 174 { MRT_DEL_MFC, IPPROTO_IP, 0, OA_X, OP_CONFIG, OP_NODEFAULT,
169 175 sizeof (struct mfcctl), -1 /* not initialized */ },
170 176
171 177 { MRT_VERSION, IPPROTO_IP, OA_R, OA_R, OP_NP, OP_NODEFAULT,
172 178 sizeof (int), -1 /* not initialized */ },
173 179
174 180 { MRT_ASSERT, IPPROTO_IP, 0, OA_RW, OP_CONFIG,
175 181 OP_NODEFAULT,
176 182 sizeof (int), -1 /* not initialized */ },
177 183
178 184 { MCAST_JOIN_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
179 185 OP_NODEFAULT, sizeof (struct group_req),
180 186 -1 /* not initialized */ },
181 187 { MCAST_LEAVE_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
182 188 OP_NODEFAULT, sizeof (struct group_req),
183 189 -1 /* not initialized */ },
184 190 { MCAST_BLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP,
185 191 OP_NODEFAULT, sizeof (struct group_source_req),
186 192 -1 /* not initialized */ },
187 193 { MCAST_UNBLOCK_SOURCE, IPPROTO_IP, OA_X, OA_X, OP_NP,
188 194 OP_NODEFAULT, sizeof (struct group_source_req),
189 195 -1 /* not initialized */ },
190 196 { MCAST_JOIN_SOURCE_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
191 197 OP_NODEFAULT, sizeof (struct group_source_req),
192 198 -1 /* not initialized */ },
193 199 { MCAST_LEAVE_SOURCE_GROUP, IPPROTO_IP, OA_X, OA_X, OP_NP,
194 200 OP_NODEFAULT, sizeof (struct group_source_req),
195 201 -1 /* not initialized */ },
196 202
197 203 { IPV6_MULTICAST_IF, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
198 204 sizeof (int), 0 },
199 205
200 206 { IPV6_MULTICAST_HOPS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
201 207 OP_DEF_FN, sizeof (int), -1 /* not initialized */ },
202 208
203 209 { IPV6_MULTICAST_LOOP, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
204 210 OP_DEF_FN, sizeof (int), -1 /* not initialized */},
205 211
206 212 { IPV6_JOIN_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP, OP_NODEFAULT,
207 213 sizeof (struct ipv6_mreq), -1 /* not initialized */ },
208 214
209 215 { IPV6_LEAVE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP, OP_NODEFAULT,
210 216 sizeof (struct ipv6_mreq), -1 /* not initialized */ },
211 217
212 218 { IPV6_UNICAST_HOPS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, OP_DEF_FN,
213 219 sizeof (int), -1 /* not initialized */ },
214 220
215 221 { IPV6_BOUND_IF, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
216 222 sizeof (int), 0 /* no ifindex */ },
217 223
218 224 { IPV6_UNSPEC_SRC, IPPROTO_IPV6, OA_R, OA_RW, OP_RAW, 0,
219 225 sizeof (int), 0 },
220 226
221 227 { IPV6_CHECKSUM, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0, sizeof (int),
222 228 -1 },
223 229
224 230 { ICMP6_FILTER, IPPROTO_ICMPV6, OA_RW, OA_RW, OP_NP, OP_DEF_FN|OP_VARLEN,
225 231 sizeof (icmp6_filter_t), 0 },
226 232 { IPV6_PKTINFO, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
227 233 (OP_NODEFAULT|OP_VARLEN),
228 234 sizeof (struct in6_pktinfo), -1 /* not initialized */ },
229 235 { IPV6_HOPLIMIT, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
230 236 (OP_NODEFAULT|OP_VARLEN),
231 237 sizeof (int), -1 /* not initialized */ },
232 238 { IPV6_NEXTHOP, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
233 239 (OP_NODEFAULT|OP_VARLEN),
234 240 sizeof (sin6_t), -1 /* not initialized */ },
235 241 { IPV6_HOPOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
236 242 (OP_VARLEN|OP_NODEFAULT),
237 243 MAX_EHDR_LEN, -1 /* not initialized */ },
238 244 { IPV6_DSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
239 245 (OP_VARLEN|OP_NODEFAULT),
240 246 MAX_EHDR_LEN, -1 /* not initialized */ },
241 247 { IPV6_RTHDRDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
242 248 (OP_VARLEN|OP_NODEFAULT),
243 249 MAX_EHDR_LEN, -1 /* not initialized */ },
244 250 { IPV6_RTHDR, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
245 251 (OP_VARLEN|OP_NODEFAULT),
246 252 MAX_EHDR_LEN, -1 /* not initialized */ },
247 253 { IPV6_TCLASS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP,
248 254 (OP_NODEFAULT|OP_VARLEN),
249 255 sizeof (int), -1 /* not initialized */ },
250 256 { IPV6_PATHMTU, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
251 257 sizeof (struct ip6_mtuinfo), -1 },
252 258 { IPV6_DONTFRAG, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
253 259 sizeof (int), 0 },
254 260 { IPV6_USE_MIN_MTU, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
255 261 sizeof (int), 0 },
256 262 { IPV6_V6ONLY, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
257 263 sizeof (int), 0 },
258 264
259 265 { IPV6_RECVPKTINFO, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
260 266 sizeof (int), 0 },
261 267 { IPV6_RECVHOPLIMIT, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
262 268 sizeof (int), 0 },
263 269 { IPV6_RECVHOPOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
264 270 sizeof (int), 0 },
265 271 { _OLD_IPV6_RECVDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
266 272 sizeof (int), 0 },
267 273 { IPV6_RECVDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
268 274 sizeof (int), 0 },
269 275 { IPV6_RECVRTHDR, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
270 276 sizeof (int), 0 },
271 277 { IPV6_RECVRTHDRDSTOPTS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
272 278 sizeof (int), 0 },
273 279 { IPV6_RECVPATHMTU, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
274 280 sizeof (int), 0 },
275 281 { IPV6_RECVTCLASS, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
276 282 sizeof (int), 0 },
277 283
278 284 { IPV6_SEC_OPT, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, OP_NODEFAULT,
279 285 sizeof (ipsec_req_t), -1 /* not initialized */ },
280 286 { IPV6_SRC_PREFERENCES, IPPROTO_IPV6, OA_RW, OA_RW, OP_NP, 0,
281 287 sizeof (uint32_t), IPV6_PREFER_SRC_DEFAULT },
282 288
283 289 { MCAST_JOIN_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
284 290 OP_NODEFAULT, sizeof (struct group_req),
285 291 -1 /* not initialized */ },
286 292 { MCAST_LEAVE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
287 293 OP_NODEFAULT, sizeof (struct group_req),
288 294 -1 /* not initialized */ },
289 295 { MCAST_BLOCK_SOURCE, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
290 296 OP_NODEFAULT, sizeof (struct group_source_req),
291 297 -1 /* not initialized */ },
292 298 { MCAST_UNBLOCK_SOURCE, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
293 299 OP_NODEFAULT, sizeof (struct group_source_req),
294 300 -1 /* not initialized */ },
295 301 { MCAST_JOIN_SOURCE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
296 302 OP_NODEFAULT, sizeof (struct group_source_req),
297 303 -1 /* not initialized */ },
298 304 { MCAST_LEAVE_SOURCE_GROUP, IPPROTO_IPV6, OA_X, OA_X, OP_NP,
299 305 OP_NODEFAULT, sizeof (struct group_source_req),
300 306 -1 /* not initialized */ },
301 307 };
302 308
303 309 /*
304 310 * Table of all supported levels
305 311 * Note: Some levels (e.g. XTI_GENERIC) may be valid but may not have
306 312 * any supported options so we need this info separately.
307 313 *
308 314 * This is needed only for topmost tpi providers and is used only by
309 315 * XTI interfaces.
310 316 */
311 317 optlevel_t icmp_valid_levels_arr[] = {
312 318 XTI_GENERIC,
313 319 SOL_SOCKET,
314 320 IPPROTO_ICMP,
315 321 IPPROTO_IP,
316 322 IPPROTO_IPV6,
317 323 IPPROTO_ICMPV6
318 324 };
319 325
320 326 #define ICMP_VALID_LEVELS_CNT A_CNT(icmp_valid_levels_arr)
321 327 #define ICMP_OPT_ARR_CNT A_CNT(icmp_opt_arr)
322 328
323 329 uint_t icmp_max_optsize; /* initialized when ICMP driver is loaded */
324 330
325 331 /*
326 332 * Initialize option database object for ICMP
327 333 *
328 334 * This object represents database of options to search passed to
329 335 * {sock,tpi}optcom_req() interface routine to take care of option
330 336 * management and associated methods.
331 337 */
332 338
333 339 optdb_obj_t icmp_opt_obj = {
334 340 icmp_opt_default, /* ICMP default value function pointer */
335 341 icmp_tpi_opt_get, /* ICMP get function pointer */
336 342 icmp_tpi_opt_set, /* ICMP set function pointer */
337 343 ICMP_OPT_ARR_CNT, /* ICMP option database count of entries */
338 344 icmp_opt_arr, /* ICMP option database */
339 345 ICMP_VALID_LEVELS_CNT, /* ICMP valid level count of entries */
340 346 icmp_valid_levels_arr /* ICMP valid level array */
341 347 };
|
↓ open down ↓ |
243 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX