1 /*- 2 * Copyright (c) 2008 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /* 28 * This regression test creates a raw IPv6 socket and confirms that it can 29 * set and get filters on the socket. No attempt is made to validate that 30 * the filter is implemented, just that it can be properly retrieved, set, 31 * etc. 32 */ 33 34 #include <sys/types.h> 35 #include <sys/socket.h> 36 37 #include <netinet/in.h> 38 #include <netinet/icmp6.h> 39 40 #include <err.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 /* 45 * Reference filters to set/test. 46 */ 47 static struct icmp6_filter ic6f_passall; 48 static struct icmp6_filter ic6f_blockall; 49 50 int 51 main(int argc, char *argv[]) 52 { 53 struct icmp6_filter ic6f; 54 socklen_t len; 55 int s; 56 57 ICMP6_FILTER_SETPASSALL(&ic6f_passall); 58 ICMP6_FILTER_SETBLOCKALL(&ic6f_blockall); 59 60 s = socket(PF_INET6, SOCK_RAW, 0); 61 if (s < 0) 62 err(-1, "socket(PF_INET6, SOCK_RAW, 0)"); 63 64 /* 65 * Confirm that we can read before the first set, and that the 66 * default is to pass all ICMP. 67 */ 68 len = sizeof(ic6f); 69 if (getsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, &len) < 0) 70 err(-1, "1: getsockopt(ICMP6_FILTER)"); 71 if (memcmp(&ic6f, &ic6f_passall, sizeof(ic6f)) != 0) 72 errx(-1, "1: getsockopt(ICMP6_FILTER) - default not passall"); 73 74 /* 75 * Confirm that we can write a pass all filter to the socket. 76 */ 77 len = sizeof(ic6f); 78 ICMP6_FILTER_SETPASSALL(&ic6f); 79 if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, len) < 0) 80 err(-1, "2: setsockopt(ICMP6_FILTER, PASSALL)"); 81 82 /* 83 * Confirm that we can still read a pass all filter. 84 */ 85 len = sizeof(ic6f); 86 if (getsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, &len) < 0) 87 err(-1, "3: getsockopt(ICMP6_FILTER)"); 88 if (memcmp(&ic6f, &ic6f_passall, sizeof(ic6f)) != 0) 89 errx(-1, "3: getsockopt(ICMP6_FILTER) - not passall"); 90 91 /* 92 * Confirm that we can write a block all filter to the socket. 93 */ 94 len = sizeof(ic6f); 95 ICMP6_FILTER_SETBLOCKALL(&ic6f); 96 if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, len) < 0) 97 err(-1, "4: setsockopt(ICMP6_FILTER, BLOCKALL)"); 98 99 /* 100 * Confirm that we can read back a block all filter. 101 */ 102 len = sizeof(ic6f); 103 if (getsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, &len) < 0) 104 err(-1, "5: getsockopt(ICMP6_FILTER)"); 105 if (memcmp(&ic6f, &ic6f_blockall, sizeof(ic6f)) != 0) 106 errx(-1, "5: getsockopt(ICMP6_FILTER) - not blockall"); 107 108 /* 109 * For completeness, confirm that we can reset to the default. 110 */ 111 len = sizeof(ic6f); 112 ICMP6_FILTER_SETPASSALL(&ic6f); 113 if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, len) < 0) 114 err(-1, "6: setsockopt(ICMP6_FILTER, PASSALL)"); 115 116 /* 117 * ... And that we can read back the pass all rule again. 118 */ 119 len = sizeof(ic6f); 120 if (getsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &ic6f, &len) < 0) 121 err(-1, "7: getsockopt(ICMP6_FILTER)"); 122 if (memcmp(&ic6f, &ic6f_passall, sizeof(ic6f)) != 0) 123 errx(-1, "7: getsockopt(ICMP6_FILTER) - not passall"); 124 125 close(s); 126 return (0); 127 } 128