xref: /minix/minix/tests/test92.c (revision 2a404668)
1 /* Tests for RAW sockets (LWIP) - by D.C. van Moolenbroek */
2 /* This test needs to be run as root: creating raw sockets is root-only. */
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stddef.h>
6 #include <sys/mman.h>
7 #include <sys/param.h>
8 #include <sys/socket.h>
9 #include <net/route.h>
10 #include <netinet/in.h>
11 #include <netinet/ip.h>
12 #include <netinet/udp.h>
13 #include <netinet/icmp6.h>
14 #include <netinet/in_pcb.h>
15 #include <netinet6/in6_pcb.h>
16 #include <arpa/inet.h>
17 #include <machine/vmparam.h>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <assert.h>
21 
22 #include "common.h"
23 #include "socklib.h"
24 
25 #define ITERATIONS	2
26 
27 #define TEST_PROTO		253	/* from RFC 3692 */
28 #define TEST_ICMPV6_TYPE_A	200	/* from RFC 4443 */
29 #define TEST_ICMPV6_TYPE_B	201	/* from RFC 4443 */
30 
31 static const enum state raw_states[] = {
32 		S_NEW,		S_N_SHUT_R,	S_N_SHUT_W,	S_N_SHUT_RW,
33 		S_BOUND,	S_CONNECTED,	S_SHUT_R,	S_SHUT_W,
34 		S_SHUT_RW,
35 };
36 
37 static const int raw_results[][__arraycount(raw_states)] = {
38 	[C_ACCEPT]		= {
39 		-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,
40 		-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,
41 		-EOPNOTSUPP,
42 	},
43 	[C_BIND]		= {
44 		0,		0,		0,		0,
45 		0,		-EINVAL,	-EINVAL,	-EINVAL,
46 		-EINVAL,
47 	},
48 	[C_CONNECT]		= {
49 		0,		0,		0,		0,
50 		0,		0,		0,		0,
51 		0,
52 	},
53 	[C_GETPEERNAME]		= {
54 		-ENOTCONN,	-ENOTCONN,	-ENOTCONN,	-ENOTCONN,
55 		-ENOTCONN,	0,		0,		0,
56 		0,
57 	},
58 	[C_GETSOCKNAME]		= {
59 		0,		0,		0,		0,
60 		0,		0,		0,		0,
61 		0,
62 	},
63 	[C_GETSOCKOPT_ERR]	= {
64 		0,		0,		0,		0,
65 		0,		0,		0,		0,
66 		0,
67 	},
68 	[C_GETSOCKOPT_KA]	= {
69 		0,		0,		0,		0,
70 		0,		0,		0,		0,
71 		0,
72 	},
73 	[C_GETSOCKOPT_RB]	= {
74 		0,		0,		0,		0,
75 		0,		0,		0,		0,
76 		0,
77 	},
78 	[C_IOCTL_NREAD]		= {
79 		0,		0,		0,		0,
80 		0,		0,		0,		0,
81 		0,
82 	},
83 	[C_LISTEN]		= {
84 		-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,
85 		-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,	-EOPNOTSUPP,
86 		-EOPNOTSUPP,
87 	},
88 	[C_RECV]		= {
89 		-EAGAIN,	0,		-EAGAIN,	0,
90 		-EAGAIN,	-EAGAIN,	0,		-EAGAIN,
91 		0,
92 	},
93 	[C_RECVFROM]		= {
94 		-EAGAIN,	0,		-EAGAIN,	0,
95 		-EAGAIN,	-EAGAIN,	0,		-EAGAIN,
96 		0,
97 	},
98 	[C_SEND]		= {
99 		-EDESTADDRREQ,	-EDESTADDRREQ,	-EPIPE,		-EPIPE,
100 		-EDESTADDRREQ,	1,		1,		-EPIPE,
101 		-EPIPE,
102 	},
103 	[C_SENDTO]		= {
104 		1,		1,		-EPIPE,		-EPIPE,
105 		1,		1,		1,		-EPIPE,
106 		-EPIPE,
107 	},
108 	[C_SELECT_R]		= {
109 		0,		1,		0,		1,
110 		0,		0,		1,		0,
111 		1,
112 	},
113 	[C_SELECT_W]		= {
114 		1,		1,		1,		1,
115 		1,		1,		1,		1,
116 		1,
117 	},
118 	[C_SELECT_X]		= {
119 		0,		0,		0,		0,
120 		0,		0,		0,		0,
121 		0,
122 	},
123 	[C_SETSOCKOPT_BC]	= {
124 		0,		0,		0,		0,
125 		0,		0,		0,		0,
126 		0,
127 	},
128 	[C_SETSOCKOPT_KA]	= {
129 		0,		0,		0,		0,
130 		0,		0,		0,		0,
131 		0,
132 	},
133 	[C_SETSOCKOPT_L]	= {
134 		0,		0,		0,		0,
135 		0,		0,		0,		0,
136 		0,
137 	},
138 	[C_SETSOCKOPT_RA]	= {
139 		0,		0,		0,		0,
140 		0,		0,		0,		0,
141 		0,
142 	},
143 	[C_SHUTDOWN_R]		= {
144 		0,		0,		0,		0,
145 		0,		0,		0,		0,
146 		0,
147 	},
148 	[C_SHUTDOWN_RW]		= {
149 		0,		0,		0,		0,
150 		0,		0,		0,		0,
151 		0,
152 	},
153 	[C_SHUTDOWN_W]		= {
154 		0,		0,		0,		0,
155 		0,		0,		0,		0,
156 		0,
157 	},
158 };
159 
160 /*
161  * Set up a RAW socket file descriptor in the requested state and pass it to
162  * socklib_sweep_call() along with local and remote addresses and their length.
163  */
164 static int
165 raw_sweep(int domain, int type, int protocol, enum state state,
166 	enum call call)
167 {
168 	struct sockaddr_in sinA, sinB;
169 	struct sockaddr_in6 sin6A, sin6B;
170 	struct sockaddr *addrA, *addrB;
171 	socklen_t addr_len;
172 	int r, fd, fd2;
173 
174 	if (domain == AF_INET) {
175 		memset(&sinA, 0, sizeof(sinA));
176 		sinA.sin_family = domain;
177 		sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
178 
179 		memcpy(&sinB, &sinA, sizeof(sinB));
180 
181 		addrA = (struct sockaddr *)&sinA;
182 		addrB = (struct sockaddr *)&sinB;
183 		addr_len = sizeof(sinA);
184 	} else {
185 		assert(domain == AF_INET6);
186 
187 		memset(&sin6A, 0, sizeof(sin6A));
188 		sin6A.sin6_family = domain;
189 		memcpy(&sin6A.sin6_addr, &in6addr_loopback,
190 		    sizeof(sin6A.sin6_addr));
191 
192 		memcpy(&sin6B, &sin6A, sizeof(sin6B));
193 
194 		addrA = (struct sockaddr *)&sin6A;
195 		addrB = (struct sockaddr *)&sin6B;
196 		addr_len = sizeof(sin6A);
197 	}
198 
199 	/* Create a bound remote socket. */
200 	if ((fd2 = socket(domain, type | SOCK_NONBLOCK, protocol)) < 0) e(0);
201 
202 	if (bind(fd2, addrB, addr_len) != 0) e(0);
203 
204 	switch (state) {
205 	case S_NEW:
206 	case S_N_SHUT_R:
207 	case S_N_SHUT_W:
208 	case S_N_SHUT_RW:
209 		if ((fd = socket(domain, type | SOCK_NONBLOCK,
210 		    protocol)) < 0) e(0);
211 
212 		switch (state) {
213 		case S_N_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
214 		case S_N_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
215 		case S_N_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
216 		default: break;
217 		}
218 
219 		break;
220 
221 	case S_BOUND:
222 	case S_CONNECTED:
223 	case S_SHUT_R:
224 	case S_SHUT_W:
225 	case S_SHUT_RW:
226 		if ((fd = socket(domain, type | SOCK_NONBLOCK,
227 		    protocol)) < 0) e(0);
228 
229 		if (bind(fd, addrA, addr_len) != 0) e(0);
230 
231 		if (state == S_BOUND)
232 			break;
233 
234 		if (connect(fd, addrB, addr_len) != 0) e(0);
235 
236 		switch (state) {
237 		case S_SHUT_R: if (shutdown(fd, SHUT_RD)) e(0); break;
238 		case S_SHUT_W: if (shutdown(fd, SHUT_WR)) e(0); break;
239 		case S_SHUT_RW: if (shutdown(fd, SHUT_RDWR)) e(0); break;
240 		default: break;
241 		}
242 
243 		break;
244 
245 	default:
246 		fd = -1;
247 		e(0);
248 	}
249 
250 	r = socklib_sweep_call(call, fd, addrA, addrB, addr_len);
251 
252 	if (close(fd) != 0) e(0);
253 	if (fd2 != -1 && close(fd2) != 0) e(0);
254 
255 	return r;
256 }
257 
258 /*
259  * Sweep test for socket calls versus socket states of RAW sockets.
260  */
261 static void
262 test92a(void)
263 {
264 
265 	subtest = 1;
266 
267 	socklib_sweep(AF_INET, SOCK_RAW, TEST_PROTO, raw_states,
268 	    __arraycount(raw_states), (const int *)raw_results, raw_sweep);
269 
270 	socklib_sweep(AF_INET6, SOCK_RAW, TEST_PROTO, raw_states,
271 	    __arraycount(raw_states), (const int *)raw_results, raw_sweep);
272 }
273 
274 /*
275  * Basic I/O test for raw sockets.
276  */
277 static void
278 test92b(void)
279 {
280 	struct sockaddr_in sinA, sinB, sinC;
281 	struct sockaddr_in6 sin6A, sin6B, sin6C;
282 	socklen_t len;
283 	unsigned int i;
284 	uint8_t buf[256], packet[5];
285 	int fd, fd2;
286 
287 	subtest = 2;
288 
289 	/* First test IPv4. */
290 	if ((fd = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
291 
292 	memset(&sinA, 0, sizeof(sinA));
293 	sinA.sin_family = AF_INET;
294 	sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
295 
296 	for (i = 0; i < __arraycount(packet); i++)
297 		packet[i] = (uint8_t)(-i);
298 
299 	if (sendto(fd, packet, sizeof(packet), 0, (struct sockaddr *)&sinA,
300 	    sizeof(sinA)) != sizeof(packet)) e(0);
301 
302 	memset(buf, 0, sizeof(buf));
303 	len = sizeof(sinB);
304 	if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sinB,
305 	    &len) != sizeof(struct ip) + sizeof(packet)) e(0);
306 
307 	if (memcmp(&buf[sizeof(struct ip)], packet, sizeof(packet)) != 0) e(0);
308 
309 	if (len != sizeof(sinB)) e(0);
310 	if (sinB.sin_len != sizeof(sinB)) e(0);
311 	if (sinB.sin_family != AF_INET) e(0);
312 	if (sinB.sin_port != htons(0)) e(0);
313 	if (sinB.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) e(0);
314 
315 	/*
316 	 * Test two additional things:
317 	 *
318 	 * 1) a non-zero port number is ignored when sending;
319 	 * 2) multiple raw sockets may receive the same packet.
320 	 */
321 	sinA.sin_port = htons(22);
322 
323 	if ((fd2 = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
324 
325 	if (sendto(fd, packet, sizeof(packet), 0, (struct sockaddr *)&sinA,
326 	    sizeof(sinA)) != sizeof(packet)) e(0);
327 
328 	memset(buf, 0, sizeof(buf));
329 	len = sizeof(sinC);
330 	if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sinC,
331 	    &len) != sizeof(struct ip) + sizeof(packet)) e(0);
332 
333 	if (memcmp(&buf[sizeof(struct ip)], packet, sizeof(packet)) != 0) e(0);
334 
335 	if (len != sizeof(sinC)) e(0);
336 	if (memcmp(&sinB, &sinC, sizeof(sinB)) != 0) e(0);
337 
338 	memset(buf, 0, sizeof(buf));
339 	len = sizeof(sinC);
340 	if (recvfrom(fd2, buf, sizeof(buf), 0, (struct sockaddr *)&sinC,
341 	    &len) != sizeof(struct ip) + sizeof(packet)) e(0);
342 
343 	if (memcmp(&buf[sizeof(struct ip)], packet, sizeof(packet)) != 0) e(0);
344 
345 	if (len != sizeof(sinC)) e(0);
346 	if (memcmp(&sinB, &sinC, sizeof(sinB)) != 0) e(0);
347 
348 	if (close(fd2) != 0) e(0);
349 	if (close(fd) != 0) e(0);
350 
351 	/* Then test IPv6. */
352 	if ((fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
353 
354 	memset(&sin6A, 0, sizeof(sin6A));
355 	sin6A.sin6_family = AF_INET6;
356 	memcpy(&sin6A.sin6_addr, &in6addr_loopback, sizeof(sin6A.sin6_addr));
357 
358 	if (sendto(fd, packet, sizeof(packet), 0, (struct sockaddr *)&sin6A,
359 	    sizeof(sin6A)) != sizeof(packet)) e(0);
360 
361 	memset(buf, 0, sizeof(buf));
362 	len = sizeof(sin6B);
363 	if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6B,
364 	    &len) != sizeof(packet)) e(0);
365 
366 	if (memcmp(buf, packet, sizeof(packet)) != 0) e(0);
367 
368 	if (len != sizeof(sin6B)) e(0);
369 	if (sin6B.sin6_len != sizeof(sin6B)) e(0);
370 	if (sin6B.sin6_family != AF_INET6) e(0);
371 	if (sin6B.sin6_port != htons(0)) e(0);
372 	if (memcmp(&sin6B.sin6_addr, &in6addr_loopback,
373 	    sizeof(sin6B.sin6_addr)) != 0) e(0);
374 
375 	/* As above. */
376 	sin6A.sin6_port = htons(22);
377 
378 	if ((fd2 = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
379 
380 	if (sendto(fd, packet, sizeof(packet), 0, (struct sockaddr *)&sin6A,
381 	    sizeof(sin6A)) != sizeof(packet)) e(0);
382 
383 	memset(buf, 0, sizeof(buf));
384 	len = sizeof(sin6C);
385 	if (recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6C,
386 	    &len) != sizeof(packet)) e(0);
387 
388 	if (memcmp(buf, packet, sizeof(packet)) != 0) e(0);
389 
390 	if (len != sizeof(sin6C)) e(0);
391 	if (memcmp(&sin6B, &sin6C, sizeof(sin6B)) != 0) e(0);
392 
393 	memset(buf, 0, sizeof(buf));
394 	len = sizeof(sin6C);
395 	if (recvfrom(fd2, buf, sizeof(buf), 0, (struct sockaddr *)&sin6C,
396 	    &len) != sizeof(packet)) e(0);
397 
398 	if (memcmp(buf, packet, sizeof(packet)) != 0) e(0);
399 
400 	if (len != sizeof(sin6C)) e(0);
401 	if (memcmp(&sin6B, &sin6C, sizeof(sin6B)) != 0) e(0);
402 
403 	if (close(fd2) != 0) e(0);
404 	if (close(fd) != 0) e(0);
405 }
406 
407 /*
408  * Test the IPV6_CHECKSUM socket option.
409  */
410 static void
411 test92c(void)
412 {
413 	struct sockaddr_in6 sin6;
414 	struct icmp6_hdr icmp6_hdr;
415 	uint8_t buf[6], buf2[6], *buf3;
416 	socklen_t len;
417 	unsigned int i;
418 	int fd, fd2, val;
419 
420 	subtest = 3;
421 
422 	if ((fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
423 
424 	if (shutdown(fd, SHUT_RD) != 0) e(0);
425 
426 	/* For non-ICMPv6 sockets, checksumming is disabled by default. */
427 	len = sizeof(val);
428 	if (getsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val, &len) != 0) e(0);
429 	if (len != sizeof(val)) e(0);
430 	if (val != -1) e(0);
431 
432 	/* Test bad offsets. */
433 	val = -2;
434 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
435 	    sizeof(val)) != -1) e(0);
436 	if (errno != EINVAL) e(0);
437 
438 	val = 1;
439 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
440 	    sizeof(val)) != -1) e(0);
441 	if (errno != EINVAL) e(0);
442 
443 	/* Now test real checksum computation. */
444 	val = 0;
445 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
446 	    sizeof(val)) != 0) e(0);
447 
448 	if ((fd2 = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
449 
450 	if (shutdown(fd2, SHUT_WR) != 0) e(0);
451 
452 	memset(buf, 0, sizeof(buf));
453 	buf[2] = 0xfe;
454 	buf[3] = 0x95;
455 	buf[4] = 0x4d;
456 
457 	memset(&sin6, 0, sizeof(sin6));
458 	sin6.sin6_family = AF_INET6;
459 	memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
460 
461 	if (sendto(fd, buf, 5, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 5)
462 		e(0);
463 
464 	if (recv(fd2, buf2, sizeof(buf2), 0) != 5) e(0);
465 
466 	if (buf2[0] != 0xb3 || buf2[1] != 0x65) e(0);
467 	if (memcmp(&buf2[2], &buf[2], 3) != 0) e(0);
468 
469 	/* Turn on checksum verification on the receiving socket. */
470 	val = 0;
471 	if (setsockopt(fd2, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
472 	    sizeof(val)) != 0) e(0);
473 
474 	/*
475 	 * The current value of the checksum field should not be incorporated
476 	 * in the checksum, as that would result in an invalid checksum.
477 	 */
478 	buf[0] = 0xab;
479 	buf[1] = 0xcd;
480 
481 	if (sendto(fd, buf, 5, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 5)
482 		e(0);
483 
484 	if (recv(fd2, buf2, sizeof(buf2), 0) != 5) e(0);
485 
486 	if (buf2[0] != 0xb3 || buf2[1] != 0x65) e(0);
487 	if (memcmp(&buf2[2], &buf[2], 3) != 0) e(0);
488 
489 	/*
490 	 * Turn off checksum computation on the sending side, so that the
491 	 * packet ends up being dropped on the receiving side.
492 	 */
493 	val = -1;
494 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
495 	    sizeof(val)) != 0) e(0);
496 
497 	if (sendto(fd, buf, 5, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 5)
498 		e(0);
499 
500 	/* Send some packets that are too small to contain the checksum. */
501 	if (sendto(fd, buf, 0, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 0)
502 		e(0);
503 	if (sendto(fd, buf, 1, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 1)
504 		e(0);
505 
506 	/*
507 	 * If this recv call is "too soon" (it should not be) and the packets
508 	 * arrive later anyway, then we will get a failure below.
509 	 */
510 	if (recv(fd2, buf2, sizeof(buf2), MSG_DONTWAIT) != -1) e(0);
511 	if (errno != EWOULDBLOCK) e(0);
512 
513 	buf[0] = 0;
514 	buf[1] = 0x67;
515 	if (sendto(fd, buf, 4, 0, (struct sockaddr *)&sin6,
516 	    sizeof(sin6)) != 4) e(0);
517 
518 	if (recv(fd2, buf2, sizeof(buf2), 0) != 4) e(0);
519 	if (memcmp(buf, buf2, 4) != 0) e(0);
520 
521 	/*
522 	 * We repeat some of the tests with a non-zero checksum offset, just to
523 	 * be sure.
524 	 */
525 	val = 2;
526 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
527 	    sizeof(val)) != 0) e(0);
528 
529 	len = sizeof(val);
530 	if (getsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val, &len) != 0) e(0);
531 	if (len != sizeof(val)) e(0);
532 	if (val != 2) e(0);
533 
534 	buf[0] = 0x56;
535 	buf[1] = 0x78;
536 
537 	for (i = 0; i <= 3; i++) {
538 		if (sendto(fd, buf, i, 0, (struct sockaddr *)&sin6,
539 		    sizeof(sin6)) != -1) e(0);
540 		if (errno != EINVAL) e(0);
541 	}
542 
543 	val = 2;
544 	if (setsockopt(fd2, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
545 	    sizeof(val)) != 0) e(0);
546 
547 	if (sendto(fd, buf, 4, 0, (struct sockaddr *)&sin6,
548 	    sizeof(sin6)) != 4) e(0);
549 
550 	if (recv(fd2, buf2, sizeof(buf2), 0) != 4) e(0);
551 	if (memcmp(buf, buf2, 2) != 0) e(0);
552 	if (buf2[2] != 0xa8 || buf2[3] != 0x84) e(0);
553 
554 	val = -1;
555 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
556 	    sizeof(val)) != 0) e(0);
557 
558 	buf[2] = 0xa8;
559 	buf[3] = 0x85; /* deliberately bad checksum */
560 
561 	/* All these should be dropped on the receiver side. */
562 	for (i = 0; i <= 4; i++) {
563 		if (sendto(fd, buf, i, 0, (struct sockaddr *)&sin6,
564 		    sizeof(sin6)) != i) e(0);
565 	}
566 
567 	buf[3] = 0x84; /* good checksum */
568 	if (sendto(fd, buf, 4, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 4)
569 		e(0);
570 
571 	if (recv(fd2, buf2, sizeof(buf2), 0) != 4) e(0);
572 	if (memcmp(buf, buf2, 4) != 0) e(0);
573 
574 	if (recv(fd2, buf2, sizeof(buf2), MSG_DONTWAIT) != -1) e(0);
575 	if (errno != EWOULDBLOCK) e(0);
576 
577 	val = -1;
578 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
579 	    sizeof(val)) != 0) e(0);
580 	if (setsockopt(fd2, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
581 	    sizeof(val)) != 0) e(0);
582 
583 	buf[3] = 0x85;
584 	if (sendto(fd, buf, 4, 0, (struct sockaddr *)&sin6, sizeof(sin6)) != 4)
585 		e(0);
586 
587 	if (recv(fd2, buf2, sizeof(buf2), 0) != 4) e(0);
588 	if (memcmp(buf, buf2, 4) != 0) e(0);
589 
590 	/*
591 	 * The following is a lwIP-specific test: lwIP does not support storing
592 	 * generated checksums beyond the first pbuf.  We do not know the size
593 	 * of the first pbuf until we actually send a packet, so the setsockopt
594 	 * call will not fail, but sending the packet will.  Depending on the
595 	 * buffer allocation strategy, the following test may or may not
596 	 * trigger this case; simply ensure that we do not crash the service.
597 	 */
598 	if ((buf3 = malloc(4096)) == NULL) e(0);
599 
600 	val = 4094;
601 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
602 	    sizeof(val)) != 0) e(0);
603 
604 	/* This call may or may not fail, but if it fails, it yields EINVAL. */
605 	if (sendto(fd, buf3, 4096, 0, (struct sockaddr *)&sin6,
606 	    sizeof(sin6)) == -1 && errno != EINVAL) e(0);
607 
608 	free(buf3);
609 
610 	if (close(fd2) != 0) e(0);
611 	if (close(fd) != 0) e(0);
612 
613 	/* For ICMPv6 packets, checksumming is always enabled. */
614 	if ((fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) e(0);
615 
616 	len = sizeof(val);
617 	if (getsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val, &len) != 0) e(0);
618 	if (len != sizeof(val)) e(0);
619 	if (val != 2) e(0);
620 
621 	val = -1;
622 	if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
623 	    sizeof(val)) != -1) e(0);
624 	if (errno != EINVAL) e(0);
625 
626 	memset(&icmp6_hdr, 0, sizeof(icmp6_hdr));
627 	icmp6_hdr.icmp6_type = TEST_ICMPV6_TYPE_A;
628 	icmp6_hdr.icmp6_code = 123;
629 	icmp6_hdr.icmp6_cksum = htons(0);
630 
631 	len = offsetof(struct icmp6_hdr, icmp6_dataun);
632 	if (sendto(fd, &icmp6_hdr, len, 0, (struct sockaddr *)&sin6,
633 	   sizeof(sin6)) != len) e(0);
634 
635 	if (recv(fd, &icmp6_hdr, sizeof(icmp6_hdr), 0) != len) e(0);
636 
637 	if (icmp6_hdr.icmp6_type != TEST_ICMPV6_TYPE_A) e(0);
638 	if (icmp6_hdr.icmp6_code != 123) e(0);
639 	if (ntohs(icmp6_hdr.icmp6_cksum) != 0x3744) e(0);
640 
641 	if (close(fd) != 0) e(0);
642 
643 	/* For IPv4 and non-RAW IPv6 sockets, the option does not work. */
644 	for (i = 0; i <= 2; i++) {
645 		switch (i) {
646 		case 0: fd = socket(AF_INET6, SOCK_DGRAM, 0); break;
647 		case 1: fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMPV6); break;
648 		case 2: fd = socket(AF_INET, SOCK_RAW, TEST_PROTO); break;
649 		}
650 		if (fd < 0) e(0);
651 
652 		val = -1;
653 		if (setsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
654 		    sizeof(val)) != -1) e(0);
655 		if (errno != ENOPROTOOPT) e(0);
656 
657 		len = sizeof(val);
658 		if (getsockopt(fd, IPPROTO_IPV6, IPV6_CHECKSUM, &val,
659 		    &len) != -1) e(0);
660 		if (errno != ENOPROTOOPT) e(0);
661 
662 		if (close(fd) != 0) e(0);
663 	}
664 }
665 
666 /*
667  * Test the ICMP6_FILTER socket option.
668  */
669 static void
670 test92d(void)
671 {
672 	struct sockaddr_in6 sin6;
673 	struct sockaddr_in sin;
674 	struct icmp6_filter filter;
675 	struct icmp6_hdr packet;
676 	socklen_t len;
677 	struct timeval tv;
678 	unsigned int i;
679 	int fd, fd2;
680 
681 	subtest = 4;
682 
683 	/*
684 	 * We use two different sockets to eliminate the possibility that the
685 	 * filter is also applied when sending packets--it should not be.
686 	 */
687 	if ((fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) e(0);
688 
689 	if (shutdown(fd, SHUT_WR) != 0) e(0);
690 
691 	len = sizeof(filter);
692 	if (getsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, &len) != 0)
693 		e(0);
694 
695 	/* We do not aim to test the ICMP6_FILTER macros here. */
696 	for (i = 0; i <= UINT8_MAX; i++)
697 		if (!ICMP6_FILTER_WILLPASS(i, &filter)) e(0);
698 
699 	if ((fd2 = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) e(0);
700 
701 	ICMP6_FILTER_SETBLOCKALL(&filter);
702 	if (setsockopt(fd2, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
703 	    sizeof(filter)) != 0) e(0);
704 
705 	len = sizeof(filter);
706 	if (getsockopt(fd2, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, &len) != 0)
707 		e(0);
708 
709 	for (i = 0; i <= UINT8_MAX; i++)
710 		if (ICMP6_FILTER_WILLPASS(i, &filter)) e(0);
711 
712 	ICMP6_FILTER_SETPASSALL(&filter);
713 	ICMP6_FILTER_SETBLOCK(TEST_ICMPV6_TYPE_A, &filter);
714 	if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
715 	    sizeof(filter)) != 0) e(0);
716 
717 	memset(&sin6, 0, sizeof(sin6));
718 	sin6.sin6_family = AF_INET6;
719 	memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
720 
721 	memset(&packet, 0, sizeof(packet));
722 	packet.icmp6_type = TEST_ICMPV6_TYPE_A;
723 	packet.icmp6_code = 12;
724 
725 	if (sendto(fd2, &packet, sizeof(packet), 0, (struct sockaddr *)&sin6,
726 	    sizeof(sin6)) != sizeof(packet)) e(0);
727 
728 	packet.icmp6_type = TEST_ICMPV6_TYPE_B;
729 	packet.icmp6_code = 34;
730 
731 	if (sendto(fd2, &packet, sizeof(packet), 0, (struct sockaddr *)&sin6,
732 	    sizeof(sin6)) != sizeof(packet)) e(0);
733 
734 	memset(&packet, 0, sizeof(packet));
735 
736 	if (recv(fd, &packet, sizeof(packet), 0) != sizeof(packet)) e(0);
737 	if (packet.icmp6_type != TEST_ICMPV6_TYPE_B) e(0);
738 	if (packet.icmp6_code != 34) e(0);
739 
740 	if (recv(fd, &packet, sizeof(packet), MSG_DONTWAIT) != -1) e(0);
741 	if (errno != EWOULDBLOCK) e(0);
742 
743 	ICMP6_FILTER_SETBLOCKALL(&filter);
744 	ICMP6_FILTER_SETPASS(TEST_ICMPV6_TYPE_A, &filter);
745 	if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
746 	    sizeof(filter)) != 0) e(0);
747 
748 	memset(&packet, 0, sizeof(packet));
749 	packet.icmp6_type = TEST_ICMPV6_TYPE_B;
750 	packet.icmp6_code = 56;
751 
752 	if (sendto(fd2, &packet, sizeof(packet), 0, (struct sockaddr *)&sin6,
753 	    sizeof(sin6)) != sizeof(packet)) e(0);
754 
755 	packet.icmp6_type = TEST_ICMPV6_TYPE_A;
756 	packet.icmp6_code = 78;
757 
758 	if (sendto(fd2, &packet, sizeof(packet), 0, (struct sockaddr *)&sin6,
759 	    sizeof(sin6)) != sizeof(packet)) e(0);
760 
761 	/*
762 	 * RFC 3542 states that setting a zero-length filter resets the filter.
763 	 * This seems like one of those things that a standardization RFC
764 	 * should not mandate: it is redundant at the API level (one can set a
765 	 * PASSALL filter, which is the required default), it relies on an edge
766 	 * case (setsockopt taking a zero-length argument), and as a "shortcut"
767 	 * it does not even cover a case that is likely to occur (no actual
768 	 * program would reset its filter on a regular basis).  Presumably it
769 	 * is a way to deallocate filter memory on some platforms, but was that
770 	 * worth the RFC inclusion?  Anyhow, we support it; NetBSD does not.
771 	 */
772 	if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, NULL, 0) != 0) e(0);
773 
774 	packet.icmp6_type = TEST_ICMPV6_TYPE_B;
775 	packet.icmp6_code = 90;
776 
777 	if (sendto(fd2, &packet, sizeof(packet), 0, (struct sockaddr *)&sin6,
778 	    sizeof(sin6)) != sizeof(packet)) e(0);
779 
780 	memset(&packet, 0, sizeof(packet));
781 
782 	if (recv(fd, &packet, sizeof(packet), 0) != sizeof(packet)) e(0);
783 	if (packet.icmp6_type != TEST_ICMPV6_TYPE_A) e(0);
784 	if (packet.icmp6_code != 78) e(0);
785 
786 	if (recv(fd, &packet, sizeof(packet), 0) != sizeof(packet)) e(0);
787 	if (packet.icmp6_type != TEST_ICMPV6_TYPE_B) e(0);
788 	if (packet.icmp6_code != 90) e(0);
789 
790 	if (recv(fd, &packet, sizeof(packet), MSG_DONTWAIT) != -1) e(0);
791 	if (errno != EWOULDBLOCK) e(0);
792 
793 	if (recv(fd2, &packet, sizeof(packet), MSG_DONTWAIT) != -1) e(0);
794 	if (errno != EWOULDBLOCK) e(0);
795 
796 	len = sizeof(filter);
797 	if (getsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter, &len) != 0)
798 		e(0);
799 
800 	for (i = 0; i <= UINT8_MAX; i++)
801 		if (!ICMP6_FILTER_WILLPASS(i, &filter)) e(0);
802 
803 	if (close(fd2) != 0) e(0);
804 
805 	/*
806 	 * Let's get weird and send an ICMPv6 packet from an IPv4 socket.
807 	 * Currently, such packets are always dropped based on the rule that
808 	 * IPv6 sockets with checksumming enabled drop all IPv4 packets.  As it
809 	 * happens, that is also all that is keeping this packet from arriving.
810 	 */
811 	if ((fd2 = socket(AF_INET, SOCK_RAW, IPPROTO_ICMPV6)) < 0) e(0);
812 
813 	ICMP6_FILTER_SETBLOCKALL(&filter);
814 	if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
815 	    sizeof(filter)) != 0) e(0);
816 
817 	memset(&sin, 0, sizeof(sin));
818 	sin.sin_family = AF_INET;
819 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
820 
821 	memset(&packet, 0, sizeof(packet));
822 	packet.icmp6_type = TEST_ICMPV6_TYPE_A;
823 	packet.icmp6_code = 123;
824 	packet.icmp6_cksum = htons(0); /* TODO: use valid checksum */
825 
826 	if (sendto(fd2, &packet, sizeof(packet), 0, (struct sockaddr *)&sin,
827 	    sizeof(sin)) != sizeof(packet)) e(0);
828 
829 	/*
830 	 * If the packet were to arrive at all, it should arrive instantly, so
831 	 * this is just an excuse to use SO_RCVTIMEO.
832 	 */
833 	tv.tv_sec = 0;
834 	tv.tv_usec = 100000;
835 	if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) != 0)
836 		e(0);
837 
838 	if (recv(fd, &packet, sizeof(packet), 0) != -1) e(0);
839 	if (errno != EWOULDBLOCK) e(0);
840 
841 	if (close(fd2) != 0) e(0);
842 
843 	if (close(fd) != 0) e(0);
844 
845 	/* Make sure ICMP6_FILTER works on IPv6-ICMPv6 sockets only. */
846 	for (i = 0; i <= 2; i++) {
847 		switch (i) {
848 		case 0: fd = socket(AF_INET6, SOCK_DGRAM, 0); break;
849 		case 1: fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO); break;
850 		case 2: fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMPV6); break;
851 		}
852 		if (fd < 0) e(0);
853 
854 		if (setsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
855 		    sizeof(filter)) != -1) e(0);
856 		if (errno != ENOPROTOOPT) e(0);
857 
858 		len = sizeof(filter);
859 		if (getsockopt(fd, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
860 		    &len) != -1) e(0);
861 		if (errno != ENOPROTOOPT) e(0);
862 
863 		if (close(fd) != 0) e(0);
864 	}
865 }
866 
867 /*
868  * Test that IPPROTO_ICMPV6 has no special value on IPv4 raw sockets.  In
869  * particular, test that no checksum is generated or verified.  By now we have
870  * already tested that none of the IPv6 socket options work on such sockets.
871  */
872 static void
873 test92e(void)
874 {
875 	char buf[sizeof(struct ip) + sizeof(struct icmp6_hdr)];
876 	struct sockaddr_in sin;
877 	struct icmp6_hdr packet;
878 	int fd;
879 
880 	subtest = 5;
881 
882 	if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMPV6)) < 0) e(0);
883 
884 	memset(&packet, 0, sizeof(packet));
885 	packet.icmp6_type = TEST_ICMPV6_TYPE_A;
886 	packet.icmp6_code = 123;
887 	packet.icmp6_cksum = htons(0);
888 
889 	memset(&sin, 0, sizeof(sin));
890 	sin.sin_family = AF_INET;
891 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
892 
893 	if (sendto(fd, &packet, sizeof(packet), 0, (struct sockaddr *)&sin,
894 	    sizeof(sin)) != sizeof(packet)) e(0);
895 
896 	if (recv(fd, buf, sizeof(buf), 0) != sizeof(buf)) e(0);
897 
898 	memcpy(&packet, &buf[sizeof(struct ip)], sizeof(packet));
899 	if (packet.icmp6_type != TEST_ICMPV6_TYPE_A) e(0);
900 	if (packet.icmp6_code != 123) e(0);
901 	if (packet.icmp6_cksum != htons(0)) e(0);
902 
903 	if (close(fd) != 0) e(0);
904 }
905 
906 struct testpkt {
907 	struct ip ip;
908 	struct udphdr udp;
909 	uint8_t data[6];
910 } __packed;
911 
912 /*
913  * Test the IP_HDRINCL socket option.
914  */
915 static void
916 test92f(void)
917 {
918 	struct sockaddr_in sin;
919 	struct testpkt pkt, pkt2;
920 	socklen_t len;
921 	char buf[7];
922 	unsigned int i;
923 	int fd, fd2, val;
924 
925 	subtest = 6;
926 
927 	/* See if we can successfully feign a UDP packet. */
928 	memset(&pkt, 0, sizeof(pkt));
929 	pkt.ip.ip_v = IPVERSION;
930 	pkt.ip.ip_hl = sizeof(pkt.ip) >> 2;
931 	pkt.ip.ip_tos = 123;
932 	pkt.ip.ip_len = sizeof(pkt);			/* swapped by OS */
933 	pkt.ip.ip_id = htons(456);
934 	pkt.ip.ip_off = IP_DF;				/* swapped by OS */
935 	pkt.ip.ip_ttl = 78;
936 	pkt.ip.ip_p = IPPROTO_UDP;
937 	pkt.ip.ip_sum = htons(0);			/* filled by OS */
938 	pkt.ip.ip_src.s_addr = htonl(INADDR_LOOPBACK);
939 	pkt.ip.ip_dst.s_addr = htonl(INADDR_LOOPBACK);
940 	pkt.udp.uh_sport = htons(TEST_PORT_B);
941 	pkt.udp.uh_dport = htons(TEST_PORT_A);
942 	pkt.udp.uh_sum = htons(0); /* lazy.. */
943 	pkt.udp.uh_ulen = htons(sizeof(pkt.udp) + sizeof(pkt.data));
944 	memcpy(pkt.data, "Hello!", sizeof(pkt.data));
945 
946 	if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) e(0);
947 
948 	if (shutdown(fd, SHUT_RD) != 0) e(0);
949 
950 	/* IP_HDRINCL is never enabled by default. */
951 	len = sizeof(val);
952 	if (getsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, &len) != 0) e(0);
953 	if (len != sizeof(val)) e(0);
954 	if (val != 0) e(0);
955 
956 	val = 1;
957 	if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) != 0)
958 		e(0);
959 
960 	len = sizeof(val);
961 	if (getsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, &len) != 0) e(0);
962 	if (len != sizeof(val)) e(0);
963 	if (val != 1) e(0);
964 
965 	if ((fd2 = socket(AF_INET, SOCK_DGRAM, 0)) < 0) e(0);
966 
967 	memset(&sin, 0, sizeof(sin));
968 	sin.sin_family = AF_INET;
969 	sin.sin_port = htons(TEST_PORT_A);
970 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
971 
972 	if (bind(fd2, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
973 
974 	sin.sin_port = htons(0);
975 
976 	if (sendto(fd, &pkt, sizeof(pkt), 0, (struct sockaddr *)&sin,
977 	    sizeof(sin)) != sizeof(pkt)) e(0);
978 
979 	if (recv(fd2, &buf, sizeof(buf), 0) != sizeof(pkt.data)) e(0);
980 	if (memcmp(buf, pkt.data, sizeof(pkt.data)) != 0) e(0);
981 
982 	if (close(fd2) != 0) e(0);
983 	if (close(fd) != 0) e(0);
984 
985 	if ((fd = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
986 
987 	len = sizeof(val);
988 	if (getsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, &len) != 0) e(0);
989 	if (len != sizeof(val)) e(0);
990 	if (val != 0) e(0);
991 
992 	if (shutdown(fd, SHUT_RD) != 0) e(0);
993 
994 	/* See if we can receive a packet for our own protocol. */
995 	pkt.ip.ip_p = TEST_PROTO;
996 
997 	if ((fd2 = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
998 
999 	val = 1;
1000 	if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) != 0)
1001 		e(0);
1002 
1003 	if (sendto(fd, &pkt, sizeof(pkt), 0, (struct sockaddr *)&sin,
1004 	    sizeof(sin)) != sizeof(pkt)) e(0);
1005 
1006 	if (recv(fd2, &pkt2, sizeof(pkt2), 0) != sizeof(pkt2)) e(0);
1007 
1008 	if (pkt2.ip.ip_v != pkt.ip.ip_v) e(0);
1009 	if (pkt2.ip.ip_hl != pkt.ip.ip_hl) e(0);
1010 	if (pkt2.ip.ip_tos != pkt.ip.ip_tos) e(0);
1011 	if (pkt2.ip.ip_len != pkt.ip.ip_len) e(0);
1012 	if (pkt2.ip.ip_id != pkt.ip.ip_id) e(0);
1013 	if (pkt2.ip.ip_off != pkt.ip.ip_off) e(0);
1014 	if (pkt2.ip.ip_ttl != pkt.ip.ip_ttl) e(0);
1015 	if (pkt2.ip.ip_p != pkt.ip.ip_p) e(0);
1016 	if (pkt2.ip.ip_sum == htons(0)) e(0);
1017 	if (pkt2.ip.ip_src.s_addr != pkt.ip.ip_src.s_addr) e(0);
1018 	if (pkt2.ip.ip_dst.s_addr != pkt.ip.ip_dst.s_addr) e(0);
1019 
1020 	/*
1021 	 * Test sending packets with weird sizes to ensure that we do not crash
1022 	 * the service.  These packets would never arrive anyway.
1023 	 */
1024 	if (sendto(fd, &pkt, 0, 0, (struct sockaddr *)&sin,
1025 	    sizeof(sin)) != -1) e(0);
1026 	if (errno != EINVAL) e(0);
1027 	if (sendto(fd, &pkt, sizeof(pkt.ip) - 1, 0, (struct sockaddr *)&sin,
1028 	    sizeof(sin)) != -1) e(0);
1029 	if (errno != EINVAL) e(0);
1030 	if (sendto(fd, &pkt, sizeof(pkt.ip), 0, (struct sockaddr *)&sin,
1031 	    sizeof(sin)) != sizeof(pkt.ip)) e(0);
1032 
1033 	if (recv(fd2, &pkt2, sizeof(pkt2), MSG_DONTWAIT) != -1) e(0);
1034 	if (errno != EWOULDBLOCK) e(0);
1035 
1036 	if (close(fd2) != 0) e(0);
1037 	if (close(fd) != 0) e(0);
1038 
1039 	/* Ensure that the socket option does not work on other types. */
1040 	for (i = 0; i <= 1; i++) {
1041 		switch (i) {
1042 		case 0: fd = socket(AF_INET, SOCK_DGRAM, 0); break;
1043 		case 1: fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO); break;
1044 		}
1045 		if (fd < 0) e(0);
1046 
1047 		len = sizeof(val);
1048 		if (getsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val,
1049 		    &len) != -1) e(0);
1050 		if (errno != ENOPROTOOPT) e(0);
1051 
1052 		if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val,
1053 		    sizeof(val)) != -1) e(0);
1054 		if (errno != ENOPROTOOPT) e(0);
1055 
1056 		if (close(fd) != 0) e(0);
1057 	}
1058 }
1059 
1060 /*
1061  * Test the IPPROTO_RAW socket protocol.  This test mostly shows that the
1062  * IPPROTO_RAW protocol is nothing special: for both IPv4 and IPv6, it sends
1063  * and receives packets with that protocol number.  We already tested earlier
1064  * that IP_HDRINCL is disabled by default on IPPROTO_RAW sockets, too.
1065  */
1066 static void
1067 test92g(void)
1068 {
1069 	struct sockaddr_in sin;
1070 	struct sockaddr_in6 sin6;
1071 	char buf[sizeof(struct ip) + 1];
1072 	int fd;
1073 
1074 	subtest = 7;
1075 
1076 	if ((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) e(0);
1077 
1078 	memset(&sin, 0, sizeof(sin));
1079 	sin.sin_family = AF_INET;
1080 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1081 
1082 	if (sendto(fd, "A", 1, 0, (struct sockaddr *)&sin,
1083 	    sizeof(sin)) != 1) e(0);
1084 
1085 	if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != sizeof(buf)) e(0);
1086 	if (buf[sizeof(struct ip)] != 'A') e(0);
1087 
1088 	if (close(fd) != 0) e(0);
1089 
1090 	if ((fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW)) < 0) e(0);
1091 
1092 	memset(&sin6, 0, sizeof(sin6));
1093 	sin6.sin6_family = AF_INET6;
1094 	memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
1095 
1096 	if (sendto(fd, "B", 1, 0, (struct sockaddr *)&sin6,
1097 	    sizeof(sin6)) != 1) e(0);
1098 
1099 	if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != 1) e(0);
1100 	if (buf[0] != 'B') e(0);
1101 
1102 	if (close(fd) != 0) e(0);
1103 }
1104 
1105 /*
1106  * Test that connected raw sockets perform correct source-based filtering.
1107  */
1108 static void
1109 test92h(void)
1110 {
1111 	struct sockaddr_in sinA, sinB;
1112 	struct sockaddr_in6 sin6A, sin6B;
1113 	struct sockaddr sa;
1114 	socklen_t len;
1115 	char buf[sizeof(struct ip) + 1];
1116 	int fd, fd2;
1117 
1118 	subtest = 8;
1119 
1120 	if ((fd = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1121 
1122 	len = sizeof(sinB);
1123 	if (getpeername(fd, (struct sockaddr *)&sinB, &len) != -1) e(0);
1124 	if (errno != ENOTCONN) e(0);
1125 
1126 	memset(&sinA, 0, sizeof(sinA));
1127 	sinA.sin_family = AF_INET;
1128 	sinA.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1129 
1130 	/*
1131 	 * First test that packets with the right source are accepted.
1132 	 * Unfortunately, source and destination are the same in this case, so
1133 	 * this test is far from perfect.
1134 	 */
1135 	if (connect(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0) e(0);
1136 
1137 	if (getpeername(fd, (struct sockaddr *)&sinB, &len) != 0) e(0);
1138 
1139 	if ((fd2 = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1140 
1141 	if (sendto(fd2, "A", 1, 0, (struct sockaddr *)&sinA,
1142 	    sizeof(sinA)) != 1) e(0);
1143 
1144 	buf[0] = '\0';
1145 	if (recv(fd2, buf, sizeof(buf), 0) != sizeof(struct ip) + 1) e(0);
1146 	if (buf[sizeof(struct ip)] != 'A') e(0);
1147 
1148 	buf[0] = '\0';
1149 	if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) !=
1150 	    sizeof(struct ip) + 1) e(0);
1151 	if (buf[sizeof(struct ip)] != 'A') e(0);
1152 
1153 	memset(&sa, 0, sizeof(sa));
1154 	sa.sa_family = AF_UNSPEC;
1155 
1156 	sinA.sin_addr.s_addr = htonl(INADDR_NONE);
1157 
1158 	/* While here, test unconnecting the socket. */
1159 	if (connect(fd, &sa, sizeof(sa)) != 0) e(0);
1160 
1161 	if (getpeername(fd, (struct sockaddr *)&sinB, &len) != -1) e(0);
1162 	if (errno != ENOTCONN) e(0);
1163 
1164 	/* Then test that packets with the wrong source are ignored. */
1165 	if (connect(fd, (struct sockaddr *)&sinA, sizeof(sinA)) != 0) e(0);
1166 
1167 	if (sendto(fd2, "B", 1, 0, (struct sockaddr *)&sinB,
1168 	    sizeof(sinB)) != 1) e(0);
1169 
1170 	buf[0] = '\0';
1171 	if (recv(fd2, buf, sizeof(buf), 0) != sizeof(struct ip) + 1) e(0);
1172 	if (buf[sizeof(struct ip)] != 'B') e(0);
1173 
1174 	if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
1175 	if (errno != EWOULDBLOCK) e(0);
1176 
1177 	if (close(fd2) != 0) e(0);
1178 	if (close(fd) != 0) e(0);
1179 
1180 	/* Repeat for IPv6, but now the other way around. */
1181 	if ((fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1182 
1183 	len = sizeof(sin6B);
1184 	if (getpeername(fd, (struct sockaddr *)&sin6B, &len) != -1) e(0);
1185 	if (errno != ENOTCONN) e(0);
1186 
1187 	memset(&sin6A, 0, sizeof(sin6A));
1188 	sin6A.sin6_family = AF_INET6;
1189 	memcpy(&sin6A.sin6_addr, &in6addr_loopback, sizeof(sin6A.sin6_addr));
1190 
1191 	memcpy(&sin6B, &sin6A, sizeof(sin6B));
1192 	if (inet_pton(AF_INET6, "::2", &sin6B.sin6_addr) != 1) e(0);
1193 
1194 	if (connect(fd, (struct sockaddr *)&sin6B, sizeof(sin6B)) != 0) e(0);
1195 
1196 	if ((fd2 = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1197 
1198 	if (sendto(fd2, "C", 1, 0, (struct sockaddr *)&sin6A,
1199 	    sizeof(sin6A)) != 1) e(0);
1200 
1201 	buf[0] = '\0';
1202 	if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
1203 	if (buf[0] != 'C') e(0);
1204 
1205 	if (recv(fd, buf, sizeof(buf), MSG_DONTWAIT) != -1) e(0);
1206 	if (errno != EWOULDBLOCK) e(0);
1207 
1208 	if (connect(fd, &sa, sizeof(sa)) != 0) e(0);
1209 
1210 	if (connect(fd, (struct sockaddr *)&sin6A, sizeof(sin6A)) != 0) e(0);
1211 
1212 	if (sendto(fd2, "D", 1, 0, (struct sockaddr *)&sin6A,
1213 	    sizeof(sin6A)) != 1) e(0);
1214 
1215 	buf[0] = '\0';
1216 	if (recv(fd2, buf, sizeof(buf), 0) != 1) e(0);
1217 	if (buf[0] != 'D') e(0);
1218 
1219 	buf[0] = '\0';
1220 	if (recv(fd, buf, sizeof(buf), 0) != 1) e(0);
1221 	if (buf[0] != 'D') e(0);
1222 
1223 	if (close(fd2) != 0) e(0);
1224 	if (close(fd) != 0) e(0);
1225 }
1226 
1227 /*
1228  * Test sending large and small RAW packets.  This test is an altered copy of
1229  * test91e, but has been changed to IPv6 to cover a greater spectrum together.
1230  */
1231 static void
1232 test92i(void)
1233 {
1234 	struct sockaddr_in6 sin6;
1235 	struct msghdr msg;
1236 	struct iovec iov;
1237 	char *buf;
1238 	unsigned int i, j;
1239 	int r, fd, fd2, val;
1240 
1241 	subtest = 9;
1242 
1243 	if ((buf = malloc(65536)) == NULL) e(0);
1244 
1245 	if ((fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1246 
1247 	memset(&sin6, 0, sizeof(sin6));
1248 	sin6.sin6_family = AF_INET6;
1249 	memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
1250 
1251 	if (bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) != 0) e(0);
1252 
1253 	val = 65536;
1254 	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) != 0)
1255 		e(0);
1256 
1257 	if ((fd2 = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1258 
1259 	/*
1260 	 * A maximum send buffer size of a full packet size's worth may always
1261 	 * be set, although this is not necessarily the actual maximum.
1262 	 */
1263 	val = 65535;
1264 	if (setsockopt(fd2, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) != 0)
1265 		e(0);
1266 
1267 	/* Find the largest possible packet size that can actually be sent. */
1268 	for (i = 0; i < val; i += sizeof(int)) {
1269 		j = i ^ 0xdeadbeef;
1270 		memcpy(&buf[i], &j, sizeof(j));
1271 	}
1272 
1273 	for (val = 65536; val > 0; val--) {
1274 		if ((r = sendto(fd2, buf, val, 0, (struct sockaddr *)&sin6,
1275 		    sizeof(sin6))) == val)
1276 			break;
1277 		if (r != -1) e(0);
1278 		if (errno != EMSGSIZE) e(0);
1279 	}
1280 
1281 	if (val != 65535 - sizeof(struct ip6_hdr)) e(0);
1282 
1283 	memset(buf, 0, val);
1284 	buf[val] = 'X';
1285 
1286 	memset(&iov, 0, sizeof(iov));
1287 	iov.iov_base = buf;
1288 	iov.iov_len = val + 1;
1289 	memset(&msg, 0, sizeof(msg));
1290 	msg.msg_iov = &iov;
1291 	msg.msg_iovlen = 1;
1292 	if (recvmsg(fd, &msg, 0) != val) e(0);
1293 	if (msg.msg_flags != 0) e(0);
1294 
1295 	for (i = 0; i < val; i += sizeof(int)) {
1296 		j = i ^ 0xdeadbeef;
1297 		if (memcmp(&buf[i], &j, MIN(sizeof(j), val - i))) e(0);
1298 	}
1299 	if (buf[val] != 'X') e(0);
1300 
1301 	if (sendto(fd2, buf, val, 0, (struct sockaddr *)&sin6, sizeof(sin6)) !=
1302 	    val) e(0);
1303 
1304 	/*
1305 	 * Make sure that there are no off-by-one errors in the receive code,
1306 	 * and that MSG_TRUNC is set (only) when not the whole packet was
1307 	 * received.
1308 	 */
1309 	memset(&iov, 0, sizeof(iov));
1310 	iov.iov_base = buf;
1311 	iov.iov_len = val;
1312 	memset(&msg, 0, sizeof(msg));
1313 	msg.msg_iov = &iov;
1314 	msg.msg_iovlen = 1;
1315 	if (recvmsg(fd, &msg, 0) != val) e(0);
1316 	if (msg.msg_flags != 0) e(0);
1317 
1318 	if (sendto(fd2, buf, val, 0, (struct sockaddr *)&sin6, sizeof(sin6)) !=
1319 	    val) e(0);
1320 
1321 	buf[val - 1] = 'Y';
1322 
1323 	memset(&iov, 0, sizeof(iov));
1324 	iov.iov_base = buf;
1325 	iov.iov_len = val - 1;
1326 	memset(&msg, 0, sizeof(msg));
1327 	msg.msg_iov = &iov;
1328 	msg.msg_iovlen = 1;
1329 	if (recvmsg(fd, &msg, 0) != val - 1) e(0);
1330 	if (msg.msg_flags != MSG_TRUNC) e(0);
1331 
1332 	for (i = 0; i < val - 1; i += sizeof(int)) {
1333 		j = i ^ 0xdeadbeef;
1334 		if (memcmp(&buf[i], &j, MIN(sizeof(j), val - 1 - i))) e(0);
1335 	}
1336 	if (buf[val - 1] != 'Y') e(0);
1337 
1338 	if (sendto(fd2, buf, val, 0, (struct sockaddr *)&sin6, sizeof(sin6)) !=
1339 	    val) e(0);
1340 
1341 	buf[0] = 'Z';
1342 
1343 	memset(&iov, 0, sizeof(iov));
1344 	iov.iov_base = buf;
1345 	iov.iov_len = 0;
1346 	memset(&msg, 0, sizeof(msg));
1347 	msg.msg_iov = &iov;
1348 	msg.msg_iovlen = 1;
1349 	if (recvmsg(fd, &msg, 0) != 0) e(0);
1350 	if (msg.msg_flags != MSG_TRUNC) e(0);
1351 	if (buf[0] != 'Z') e(0);
1352 
1353 	/* Make sure that zero-sized packets can be sent and received. */
1354 	if (sendto(fd2, buf, 0, 0, (struct sockaddr *)&sin6,
1355 	    sizeof(sin6)) != 0) e(0);
1356 
1357 	/*
1358 	 * Note how we currently assume that packets sent over localhost will
1359 	 * arrive immediately, so that we can use MSG_DONTWAIT to avoid that
1360 	 * the test freezes.
1361 	 */
1362 	memset(&msg, 0, sizeof(msg));
1363 	msg.msg_iov = &iov;
1364 	msg.msg_iovlen = 1;
1365 	if (recvmsg(fd, &msg, MSG_DONTWAIT) != 0) e(0);
1366 	if (msg.msg_flags != 0) e(0);
1367 	if (buf[0] != 'Z') e(0);
1368 
1369 	if (recv(fd, buf, val, MSG_DONTWAIT) != -1) e(0);
1370 	if (errno != EWOULDBLOCK) e(0);
1371 
1372 	/*
1373 	 * When sending lots of small packets, ensure that fewer packets arrive
1374 	 * than we sent.  This sounds weird, but we cannot actually check the
1375 	 * internal TCP/IP buffer granularity and yet we want to make sure that
1376 	 * the receive queue is measured in terms of buffers rather than packet
1377 	 * sizes.  In addition, we check that older packets are favored,
1378 	 * instead discarding new ones when the receive buffer is full.
1379 	 */
1380 	for (i = 0; i < 65536 / sizeof(j); i++) {
1381 		j = i;
1382 		if (sendto(fd2, &j, sizeof(j), 0, (struct sockaddr *)&sin6,
1383 		    sizeof(sin6)) != sizeof(j)) e(0);
1384 	}
1385 
1386 	for (i = 0; i < 1025; i++) {
1387 		r = recv(fd, &j, sizeof(j), MSG_DONTWAIT);
1388 		if (r == -1) {
1389 			if (errno != EWOULDBLOCK) e(0);
1390 			break;
1391 		}
1392 		if (r != sizeof(j)) e(0);
1393 		if (i != j) e(0);
1394 	}
1395 	if (i == 1025) e(0);
1396 
1397 	if (close(fd2) != 0) e(0);
1398 	if (close(fd) != 0) e(0);
1399 
1400 	free(buf);
1401 }
1402 
1403 /*
1404  * Test sending and receiving with bad pointers.
1405  */
1406 static void
1407 test92j(void)
1408 {
1409 	struct sockaddr_in sin;
1410 	char *ptr;
1411 	int i, fd;
1412 
1413 	subtest = 10;
1414 
1415 	if ((ptr = mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE,
1416 	    MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED) e(0);
1417 
1418 	if (munmap(&ptr[PAGE_SIZE], PAGE_SIZE) != 0) e(0);
1419 
1420 	if ((fd = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1421 
1422 	memset(&sin, 0, sizeof(sin));
1423 	sin.sin_family = AF_INET;
1424 	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1425 
1426 	if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) != 0) e(0);
1427 
1428 	memset(ptr, 'A', PAGE_SIZE);
1429 
1430 	if (sendto(fd, &ptr[PAGE_SIZE / 2], PAGE_SIZE, 0,
1431 	    (struct sockaddr *)&sin, sizeof(sin)) != -1) e(0);
1432 	if (errno != EFAULT) e(0);
1433 
1434 	memset(ptr, 'B', PAGE_SIZE);
1435 
1436 	if (sendto(fd, ptr, PAGE_SIZE - sizeof(struct ip), 0,
1437 	    (struct sockaddr *)&sin, sizeof(sin)) !=
1438 	    PAGE_SIZE - sizeof(struct ip)) e(0);
1439 
1440 	memset(ptr, 0, PAGE_SIZE);
1441 
1442 	if (recvfrom(fd, &ptr[PAGE_SIZE / 2], PAGE_SIZE, 0, NULL, 0) != -1)
1443 		e(0);
1444 	if (errno != EFAULT) e(0);
1445 
1446 	if (recvfrom(fd, ptr, PAGE_SIZE * 2, 0, NULL, 0) != PAGE_SIZE) e(0);
1447 	for (i = sizeof(struct ip); i < PAGE_SIZE; i++)
1448 		if (ptr[i] != 'B') e(0);
1449 
1450 	if (close(fd) != 0) e(0);
1451 
1452 	if (munmap(ptr, PAGE_SIZE) != 0) e(0);
1453 }
1454 
1455 /*
1456  * Test basic sysctl(2) socket enumeration support.
1457  */
1458 static void
1459 test92k(void)
1460 {
1461 	struct kinfo_pcb ki;
1462 	struct sockaddr_in lsin, rsin;
1463 	struct sockaddr_in6 lsin6, rsin6;
1464 	int fd, fd2, val;
1465 
1466 	subtest = 11;
1467 
1468 	if (socklib_find_pcb("net.inet.raw.pcblist", TEST_PROTO, 0, 0,
1469 	    &ki) != 0) e(0);
1470 
1471 	if ((fd = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1472 
1473 	memset(&lsin, 0, sizeof(lsin));
1474 	lsin.sin_len = sizeof(lsin);
1475 	lsin.sin_family = AF_INET;
1476 
1477 	memset(&rsin, 0, sizeof(rsin));
1478 	rsin.sin_len = sizeof(rsin);
1479 	rsin.sin_family = AF_INET;
1480 
1481 	if (socklib_find_pcb("net.inet.raw.pcblist", TEST_PROTO, 0, 0,
1482 	    &ki) != 1) e(0);
1483 	if (ki.ki_type != SOCK_RAW) e(0);
1484 	if (ki.ki_tstate != 0) e(0);
1485 	if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
1486 	if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
1487 	if (ki.ki_sndq != 0) e(0);
1488 	if (ki.ki_rcvq != 0) e(0);
1489 
1490 	if (socklib_find_pcb("net.inet6.raw6.pcblist", TEST_PROTO, 0, 0,
1491 	    &ki) != 0) e(0);
1492 
1493 	lsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1494 
1495 	if (bind(fd, (struct sockaddr *)&lsin, sizeof(lsin)) != 0) e(0);
1496 
1497 	if (socklib_find_pcb("net.inet.raw.pcblist", TEST_PROTO, 0, 0,
1498 	    &ki) != 1) e(0);
1499 	if (ki.ki_type != SOCK_RAW) e(0);
1500 	if (ki.ki_tstate != 0) e(0);
1501 	if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
1502 	if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
1503 	if (ki.ki_sndq != 0) e(0);
1504 	if (ki.ki_rcvq != 0) e(0);
1505 	if (ki.ki_pflags & INP_HDRINCL) e(0);
1506 
1507 	rsin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1508 	if (connect(fd, (struct sockaddr *)&rsin, sizeof(rsin)) != 0) e(0);
1509 
1510 	if (socklib_find_pcb("net.inet.raw.pcblist", TEST_PROTO, 0, 0,
1511 	    &ki) != 1) e(0);
1512 	if (ki.ki_type != SOCK_RAW) e(0);
1513 	if (ki.ki_tstate != 0) e(0);
1514 	if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
1515 	if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
1516 	if (ki.ki_sndq != 0) e(0);
1517 	if (ki.ki_rcvq != 0) e(0);
1518 
1519 	if ((fd2 = socket(AF_INET, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1520 
1521 	if (sendto(fd2, "ABC", 3, 0, (struct sockaddr *)&lsin,
1522 	    sizeof(lsin)) != 3) e(0);
1523 
1524 	if (close(fd2) != 0) e(0);
1525 
1526 	val = 1;
1527 	if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &val, sizeof(val)) != 0)
1528 		e(0);
1529 
1530 	if (socklib_find_pcb("net.inet.raw.pcblist", TEST_PROTO, 0, 0,
1531 	    &ki) != 1) e(0);
1532 	if (ki.ki_type != SOCK_RAW) e(0);
1533 	if (ki.ki_tstate != 0) e(0);
1534 	if (memcmp(&ki.ki_src, &lsin, sizeof(lsin)) != 0) e(0);
1535 	if (memcmp(&ki.ki_dst, &rsin, sizeof(rsin)) != 0) e(0);
1536 	if (ki.ki_sndq != 0) e(0);
1537 	if (ki.ki_rcvq < 3) e(0);	/* size is rounded up */
1538 	if (!(ki.ki_pflags & INP_HDRINCL)) e(0);
1539 
1540 	if (socklib_find_pcb("net.inet6.raw6.pcblist", TEST_PROTO, 0, 0,
1541 	    &ki) != 0) e(0);
1542 
1543 	if (close(fd) != 0) e(0);
1544 
1545 	/* Test IPv6 sockets as well. */
1546 	if ((fd = socket(AF_INET6, SOCK_RAW, TEST_PROTO)) < 0) e(0);
1547 
1548 	memset(&lsin6, 0, sizeof(lsin6));
1549 	lsin6.sin6_len = sizeof(lsin6);
1550 	lsin6.sin6_family = AF_INET6;
1551 
1552 	memset(&rsin6, 0, sizeof(rsin6));
1553 	rsin6.sin6_len = sizeof(rsin6);
1554 	rsin6.sin6_family = AF_INET6;
1555 
1556 	if (socklib_find_pcb("net.inet6.raw6.pcblist", TEST_PROTO, 0, 0,
1557 	    &ki) != 1) e(0);
1558 	if (ki.ki_type != SOCK_RAW) e(0);
1559 	if (ki.ki_tstate != 0) e(0);
1560 	if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
1561 	if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
1562 	if (ki.ki_sndq != 0) e(0);
1563 	if (ki.ki_rcvq != 0) e(0);
1564 
1565 	memcpy(&lsin6.sin6_addr, &in6addr_loopback, sizeof(lsin6.sin6_addr));
1566 	if (bind(fd, (struct sockaddr *)&lsin6, sizeof(lsin6)) != 0) e(0);
1567 
1568 	if (socklib_find_pcb("net.inet6.raw6.pcblist", TEST_PROTO, 0, 0,
1569 	    &ki) != 1) e(0);
1570 	if (ki.ki_type != SOCK_RAW) e(0);
1571 	if (ki.ki_tstate != 0) e(0);
1572 	if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
1573 	if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
1574 	if (ki.ki_sndq != 0) e(0);
1575 	if (ki.ki_rcvq != 0) e(0);
1576 	if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
1577 
1578 	memcpy(&rsin6.sin6_addr, &in6addr_loopback, sizeof(rsin6.sin6_addr));
1579 	if (connect(fd, (struct sockaddr *)&rsin6, sizeof(rsin6)) != 0)
1580 		e(0);
1581 
1582 	if (socklib_find_pcb("net.inet6.raw6.pcblist", TEST_PROTO, 0, 0,
1583 	    &ki) != 1) e(0);
1584 	if (ki.ki_type != SOCK_RAW) e(0);
1585 	if (ki.ki_tstate != 0) e(0);
1586 	if (memcmp(&ki.ki_src, &lsin6, sizeof(lsin6)) != 0) e(0);
1587 	if (memcmp(&ki.ki_dst, &rsin6, sizeof(rsin6)) != 0) e(0);
1588 	if (ki.ki_sndq != 0) e(0);
1589 	if (ki.ki_rcvq != 0) e(0);
1590 	if (!(ki.ki_pflags & IN6P_IPV6_V6ONLY)) e(0);
1591 
1592 	if (socklib_find_pcb("net.inet.raw.pcblist", TEST_PROTO, 0, 0,
1593 	    &ki) != 0) e(0);
1594 
1595 	if (close(fd) != 0) e(0);
1596 
1597 	if (socklib_find_pcb("net.inet6.raw6.pcblist", TEST_PROTO, 0, 0,
1598 	    &ki) != 0) e(0);
1599 }
1600 
1601 /*
1602  * Test local and remote IPv6 address handling.  In particular, test scope IDs
1603  * and IPv4-mapped IPv6 addresses.
1604  */
1605 static void
1606 test92l(void)
1607 {
1608 
1609 	subtest = 12;
1610 
1611 	socklib_test_addrs(SOCK_RAW, TEST_PROTO);
1612 }
1613 
1614 /*
1615  * Test setting and retrieving basic multicast transmission options.
1616  */
1617 static void
1618 test92m(void)
1619 {
1620 
1621 	subtest = 13;
1622 
1623 	socklib_multicast_tx_options(SOCK_RAW);
1624 }
1625 
1626 /*
1627  * Test multicast support.
1628  */
1629 static void
1630 test92n(void)
1631 {
1632 
1633 	subtest = 14;
1634 
1635 	socklib_test_multicast(SOCK_RAW, TEST_PROTO);
1636 }
1637 
1638 /*
1639  * Test small and large ICMP echo ("ping") packets.  This test aims to confirm
1640  * expected behavior resulting from the LWIP service's memory pool policies:
1641  * lwIP should reply to ICMP echo requests that fit in a single 512-byte buffer
1642  * (including space for ethernet headers, even on loopback interfaces), but not
1643  * to requests exceeding a single buffer.
1644  */
1645 static void
1646 test92o(void)
1647 {
1648 	struct sockaddr_in6 sin6;
1649 	struct icmp6_hdr packet;
1650 	char buf[512];
1651 	int fd;
1652 
1653 	subtest = 15;
1654 
1655 	/* IPv6 only for now, for simplicity reasons. */
1656 	if ((fd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) e(0);
1657 
1658 	memset(&sin6, 0, sizeof(sin6));
1659 	sin6.sin6_family = AF_INET6;
1660 	memcpy(&sin6.sin6_addr, &in6addr_loopback, sizeof(sin6.sin6_addr));
1661 
1662 	memset(&packet, 0, sizeof(packet));
1663 	packet.icmp6_type = ICMP6_ECHO_REQUEST;
1664 	packet.icmp6_code = 0;
1665 	packet.icmp6_id = getpid();
1666 	packet.icmp6_seq = 1;
1667 
1668 	memset(buf, 'A', sizeof(buf));
1669 	memcpy(buf, &packet, sizeof(packet));
1670 
1671 	if (sendto(fd, buf, sizeof(buf), 0, (struct sockaddr *)&sin6,
1672 	    sizeof(sin6)) != sizeof(buf)) e(0);
1673 
1674 	packet.icmp6_seq = 2;
1675 
1676 	memset(buf, 'B', sizeof(buf));
1677 	memcpy(buf, &packet, sizeof(packet));
1678 
1679 	if (sendto(fd, buf, sizeof(buf) - 100, 0, (struct sockaddr *)&sin6,
1680 	    sizeof(sin6)) != sizeof(buf) - 100) e(0);
1681 
1682 	do {
1683 		memset(buf, '\0', sizeof(buf));
1684 
1685 		if (recv(fd, buf, sizeof(buf), 0) <= 0) e(0);
1686 
1687 		memcpy(&packet, buf, sizeof(packet));
1688 	} while (packet.icmp6_type == ICMP6_ECHO_REQUEST);
1689 
1690 	if (packet.icmp6_type != ICMP6_ECHO_REPLY) e(0);
1691 	if (packet.icmp6_code != 0) e(0);
1692 	if (packet.icmp6_id != getpid()) e(0);
1693 	if (packet.icmp6_seq != 2) e(0);
1694 	if (buf[sizeof(buf) - 101] != 'B') e(0);
1695 
1696 	if (close(fd) != 0) e(0);
1697 }
1698 
1699 /*
1700  * Test program for LWIP RAW sockets.
1701  */
1702 int
1703 main(int argc, char ** argv)
1704 {
1705 	int i, m;
1706 
1707 	start(92);
1708 
1709 	if (argc == 2)
1710 		m = atoi(argv[1]);
1711 	else
1712 		m = 0xFFFF;
1713 
1714 	for (i = 0; i < ITERATIONS; i++) {
1715 		if (m & 0x0001) test92a();
1716 		if (m & 0x0002) test92b();
1717 		if (m & 0x0004) test92c();
1718 		if (m & 0x0008) test92d();
1719 		if (m & 0x0010) test92e();
1720 		if (m & 0x0020) test92f();
1721 		if (m & 0x0040) test92g();
1722 		if (m & 0x0080) test92h();
1723 		if (m & 0x0100) test92i();
1724 		if (m & 0x0200) test92j();
1725 		if (m & 0x0400) test92k();
1726 		if (m & 0x0400) test92k();
1727 		if (m & 0x0800) test92l();
1728 		if (m & 0x1000) test92m();
1729 		if (m & 0x2000) test92n();
1730 		if (m & 0x4000) test92o();
1731 	}
1732 
1733 	quit();
1734 	/* NOTREACHED */
1735 }
1736