ipsockopt.c (136384) | ipsockopt.c (136390) |
---|---|
1/*- 2 * Copyright (c) 2004 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 unchanged lines hidden (view full) --- 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 * | 1/*- 2 * Copyright (c) 2004 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 unchanged lines hidden (view full) --- 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 * $FreeBSD: head/tools/regression/netinet/ipsockopt/ipsockopt.c 136384 2004-10-11 16:09:45Z rwatson $ | 26 * $FreeBSD: head/tools/regression/netinet/ipsockopt/ipsockopt.c 136390 2004-10-11 19:03:53Z rwatson $ |
27 */ 28 29#include <sys/types.h> 30#include <sys/socket.h> 31 32#include <netinet/in.h> 33#include <netinet/in_systm.h> 34#include <netinet/ip.h> --- 9 unchanged lines hidden (view full) --- 44 * The test tool exercises IP-level socket options by interrogating the 45 * getsockopt()/setsockopt() APIs. It does not currently test that the 46 * intended semantics of each option are implemented (i.e., that setting IP 47 * options on the socket results in packets with the desired IP options in 48 * it). 49 */ 50 51/* | 27 */ 28 29#include <sys/types.h> 30#include <sys/socket.h> 31 32#include <netinet/in.h> 33#include <netinet/in_systm.h> 34#include <netinet/ip.h> --- 9 unchanged lines hidden (view full) --- 44 * The test tool exercises IP-level socket options by interrogating the 45 * getsockopt()/setsockopt() APIs. It does not currently test that the 46 * intended semantics of each option are implemented (i.e., that setting IP 47 * options on the socket results in packets with the desired IP options in 48 * it). 49 */ 50 51/* |
52 * get_socket() is a wrapper function that returns a socket of the specified 53 * type, and created with or without restored root privilege (if running 54 * with a real uid of root and an effective uid of some other user). This 55 * us to test whether the same rights are granted using a socket with a 56 * privileged cached credential vs. a socket with a regular credential. 57 */ 58#define PRIV_ASIS 0 59#define PRIV_GETROOT 1 60static int 61get_socket_unpriv(int type) 62{ 63 64 return (socket(PF_INET, type, 0)); 65} 66 67static int 68get_socket_priv(int type) 69{ 70 uid_t olduid; 71 int sock; 72 73 if (getuid() != 0) 74 errx(-1, "get_sock_priv: running without real uid 0"); 75 76 olduid = geteuid(); 77 if (seteuid(0) < 0) 78 err(-1, "get_sock_priv: seteuid(0)"); 79 80 sock = socket(PF_INET, type, 0); 81 82 if (seteuid(olduid) < 0) 83 err(-1, "get_sock_priv: seteuid(%d)", olduid); 84 85 return (sock); 86} 87 88static int 89get_socket(int type, int priv) 90{ 91 92 if (priv) 93 return (get_socket_priv(type)); 94 else 95 return (get_socket_unpriv(type)); 96} 97 98/* |
|
52 * Exercise the IP_OPTIONS socket option. Confirm the following properties: 53 * 54 * - That there is no initial set of options (length returned is 0). 55 * - That if we set a specific set of options, we can read it back. 56 * - That if we then reset the options, they go away. 57 * 58 * Use a UDP socket for this. 59 */ 60static void | 99 * Exercise the IP_OPTIONS socket option. Confirm the following properties: 100 * 101 * - That there is no initial set of options (length returned is 0). 102 * - That if we set a specific set of options, we can read it back. 103 * - That if we then reset the options, they go away. 104 * 105 * Use a UDP socket for this. 106 */ 107static void |
61test_ip_options(void) | 108test_ip_options(int sock, const char *socktypename) |
62{ 63 u_int32_t new_options, test_options[2]; 64 socklen_t len; | 109{ 110 u_int32_t new_options, test_options[2]; 111 socklen_t len; |
65 int sock; | |
66 | 112 |
67 sock = socket(PF_INET, SOCK_DGRAM, 0); 68 if (sock == -1) 69 err(-1, "test_ip_options: socket(SOCK_DGRAM)"); 70 | |
71 /* 72 * Start off by confirming the default IP options on a socket are to 73 * have no options set. 74 */ 75 len = sizeof(test_options); 76 if (getsockopt(sock, IPPROTO_IP, IP_OPTIONS, test_options, &len) < 0) | 113 /* 114 * Start off by confirming the default IP options on a socket are to 115 * have no options set. 116 */ 117 len = sizeof(test_options); 118 if (getsockopt(sock, IPPROTO_IP, IP_OPTIONS, test_options, &len) < 0) |
77 err(-1, "test_ip_options: initial getsockopt()"); | 119 err(-1, "test_ip_options(%s): initial getsockopt()", 120 socktypename); |
78 79 if (len != 0) | 121 122 if (len != 0) |
80 errx(-1, "test_ip_options: initial getsockopt() returned " 81 "%d bytes", len); | 123 errx(-1, "test_ip_options(%s): initial getsockopt() returned " 124 "%d bytes", socktypename, len); |
82 83#define TEST_MAGIC 0xc34e4212 84#define NEW_OPTIONS htonl(IPOPT_EOL | (IPOPT_NOP << 8) | (IPOPT_NOP << 16) \ 85 | (IPOPT_NOP << 24)) 86 87 /* 88 * Write some new options into the socket. 89 */ 90 new_options = NEW_OPTIONS; 91 if (setsockopt(sock, IPPROTO_IP, IP_OPTIONS, &new_options, 92 sizeof(new_options)) < 0) | 125 126#define TEST_MAGIC 0xc34e4212 127#define NEW_OPTIONS htonl(IPOPT_EOL | (IPOPT_NOP << 8) | (IPOPT_NOP << 16) \ 128 | (IPOPT_NOP << 24)) 129 130 /* 131 * Write some new options into the socket. 132 */ 133 new_options = NEW_OPTIONS; 134 if (setsockopt(sock, IPPROTO_IP, IP_OPTIONS, &new_options, 135 sizeof(new_options)) < 0) |
93 err(-1, "test_ip_options: setsockopt(NOP|NOP|NOP|EOL)"); | 136 err(-1, "test_ip_options(%s): setsockopt(NOP|NOP|NOP|EOL)", 137 socktypename); |
94 95 /* 96 * Store some random cruft in a local variable and retrieve the 97 * options to make sure they set. Note that we pass in an array 98 * of u_int32_t's so that if whatever ended up in the option was 99 * larger than what we put in, we find out about it here. 100 */ 101 test_options[0] = TEST_MAGIC; 102 test_options[1] = TEST_MAGIC; 103 len = sizeof(test_options); 104 if (getsockopt(sock, IPPROTO_IP, IP_OPTIONS, test_options, &len) < 0) | 138 139 /* 140 * Store some random cruft in a local variable and retrieve the 141 * options to make sure they set. Note that we pass in an array 142 * of u_int32_t's so that if whatever ended up in the option was 143 * larger than what we put in, we find out about it here. 144 */ 145 test_options[0] = TEST_MAGIC; 146 test_options[1] = TEST_MAGIC; 147 len = sizeof(test_options); 148 if (getsockopt(sock, IPPROTO_IP, IP_OPTIONS, test_options, &len) < 0) |
105 err(-1, "test_ip_options: getsockopt() after set"); | 149 err(-1, "test_ip_options(%s): getsockopt() after set", 150 socktypename); |
106 107 /* 108 * Getting the right amount back is important. 109 */ 110 if (len != sizeof(new_options)) | 151 152 /* 153 * Getting the right amount back is important. 154 */ 155 if (len != sizeof(new_options)) |
111 errx(-1, "test_ip_options: getsockopt() after set returned " 112 "%d bytes of data", len); | 156 errx(-1, "test_ip_options(%s): getsockopt() after set " 157 "returned %d bytes of data", socktypename, len); |
113 114 /* 115 * One posible failure mode is that the call succeeds but neglects to 116 * copy out the data. 117 */ 118 if (test_options[0] == TEST_MAGIC) | 158 159 /* 160 * One posible failure mode is that the call succeeds but neglects to 161 * copy out the data. 162 */ 163 if (test_options[0] == TEST_MAGIC) |
119 errx(-1, "test_ip_options: getsockopt() after set didn't " 120 "return data"); | 164 errx(-1, "test_ip_options(%s): getsockopt() after set didn't " 165 "return data", socktypename); |
121 122 /* 123 * Make sure we get back what we wrote on. 124 */ 125 if (new_options != test_options[0]) | 166 167 /* 168 * Make sure we get back what we wrote on. 169 */ 170 if (new_options != test_options[0]) |
126 errx(-1, "test_ip_options: getsockopt() after set returned " 127 "wrong options (%08x, %08x)", new_options, 128 test_options[0]); | 171 errx(-1, "test_ip_options(%s): getsockopt() after set " 172 "returned wrong options (%08x, %08x)", socktypename, 173 new_options, test_options[0]); |
129 130 /* 131 * Now we reset the value to make sure clearing works. 132 */ 133 if (setsockopt(sock, IPPROTO_IP, IP_OPTIONS, NULL, 0) < 0) | 174 175 /* 176 * Now we reset the value to make sure clearing works. 177 */ 178 if (setsockopt(sock, IPPROTO_IP, IP_OPTIONS, NULL, 0) < 0) |
134 err(-1, "test_ip_options: setsockopt() to reset"); | 179 err(-1, "test_ip_options(%s): setsockopt() to reset", 180 socktypename); |
135 136 /* 137 * Make sure it was really cleared. 138 */ 139 test_options[0] = TEST_MAGIC; 140 test_options[1] = TEST_MAGIC; 141 len = sizeof(test_options); 142 if (getsockopt(sock, IPPROTO_IP, IP_OPTIONS, test_options, &len) < 0) | 181 182 /* 183 * Make sure it was really cleared. 184 */ 185 test_options[0] = TEST_MAGIC; 186 test_options[1] = TEST_MAGIC; 187 len = sizeof(test_options); 188 if (getsockopt(sock, IPPROTO_IP, IP_OPTIONS, test_options, &len) < 0) |
143 err(-1, "test_ip_options: getsockopt() after reset"); | 189 err(-1, "test_ip_options(%s): getsockopt() after reset", 190 socktypename); |
144 145 if (len != 0) | 191 192 if (len != 0) |
146 errx(-1, "test_ip_options: getsockopt() after reset returned " 147 "%d bytes", len); 148 149 close(sock); | 193 errx(-1, "test_ip_options(%s): getsockopt() after reset " 194 "returned %d bytes", socktypename, len); |
150} 151 152/* 153 * This test checks the behavior of the IP_HDRINCL socket option, which 154 * allows users with privilege to specify the full header on an IP raw 155 * socket. We test that the option can only be used with raw IP sockets, not 156 * with UDP or TCP sockets. We also confirm that the raw socket is only 157 * available to a privileged user (subject to the UID when called). We 158 * confirm that it defaults to off | 195} 196 197/* 198 * This test checks the behavior of the IP_HDRINCL socket option, which 199 * allows users with privilege to specify the full header on an IP raw 200 * socket. We test that the option can only be used with raw IP sockets, not 201 * with UDP or TCP sockets. We also confirm that the raw socket is only 202 * available to a privileged user (subject to the UID when called). We 203 * confirm that it defaults to off |
204 * 205 * Unlike other tests, doesn't use caller-provided socket. Probably should 206 * be fixed. |
|
159 */ 160static void 161test_ip_hdrincl(void) 162{ 163 int flag[2], sock; 164 socklen_t len; 165 166 /* 167 * Try to receive or set the IP_HDRINCL flag on a TCP socket. 168 */ 169 sock = socket(PF_INET, SOCK_STREAM, 0); | 207 */ 208static void 209test_ip_hdrincl(void) 210{ 211 int flag[2], sock; 212 socklen_t len; 213 214 /* 215 * Try to receive or set the IP_HDRINCL flag on a TCP socket. 216 */ 217 sock = socket(PF_INET, SOCK_STREAM, 0); |
170 if (sock == -1) { 171 perror("socket"); 172 exit(-1); 173 } | 218 if (sock == -1) 219 err(-1, "test_ip_hdrincl(): socket(SOCK_STREAM)"); |
174 175 flag[0] = -1; 176 len = sizeof(flag[0]); | 220 221 flag[0] = -1; 222 len = sizeof(flag[0]); |
177 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) == 0) { 178 fprintf(stderr, "getsockopt(IP_HDRINCL) on TCP succeeded\n"); 179 exit(-1); 180 } | 223 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) == 0) 224 err(-1, "test_ip_hdrincl(): initial getsockopt(IP_HDRINCL)"); |
181 | 225 |
182 if (errno != ENOPROTOOPT) { 183 fprintf(stderr, "getsockopt(IP_HDRINCL) on TCP returned %d " 184 "(%s) not ENOPROTOOPT\n", errno, strerror(errno)); 185 exit(-1); 186 } | 226 if (errno != ENOPROTOOPT) 227 errx(-1, "test_ip_hdrincl(): initial getsockopt(IP_HDRINC) " 228 "returned %d (%s) not ENOPROTOOPT", errno, 229 strerror(errno)); |
187 188 flag[0] = 1; 189 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) | 230 231 flag[0] = 1; 232 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) |
190 == 0) { 191 fprintf(stderr, "setsockopt(IP_HDRINCL) on TCP succeeded\n"); 192 exit(-1); 193 } | 233 == 0) 234 err(-1,"test_ip_hdrincl(): setsockopt(IP_HDRINCL) on TCP " 235 "succeeded\n"); |
194 | 236 |
195 if (errno != ENOPROTOOPT) { 196 fprintf(stderr, "setsockopt(IP_HDRINCL) on TCP returned %d " 197 "(%s) not ENOPROTOOPT\n", errno, strerror(errno)); 198 exit(-1); 199 } | 237 if (errno != ENOPROTOOPT) 238 errx(-1, "test_ip_hdrincl(): setsockopt(IP_HDRINCL) on TCP " 239 "returned %d (%s) not ENOPROTOOPT\n", errno, 240 strerror(errno)); |
200 201 close(sock); 202 203 /* 204 * Try to receive or set the IP_HDRINCL flag on a UDP socket. 205 */ 206 sock = socket(PF_INET, SOCK_DGRAM, 0); | 241 242 close(sock); 243 244 /* 245 * Try to receive or set the IP_HDRINCL flag on a UDP socket. 246 */ 247 sock = socket(PF_INET, SOCK_DGRAM, 0); |
207 if (sock == -1) { 208 perror("socket"); 209 exit(-1); 210 } | 248 if (sock == -1) 249 err(-1, "test_ip_hdrincl(): socket(SOCK_DGRAM"); |
211 212 flag[0] = -1; 213 len = sizeof(flag[0]); | 250 251 flag[0] = -1; 252 len = sizeof(flag[0]); |
214 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) == 0) { 215 fprintf(stderr, "getsockopt(IP_HDRINCL) on UDP succeeded\n"); 216 exit(-1); 217 } | 253 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) == 0) 254 err(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) on UDP " 255 "succeeded\n"); |
218 | 256 |
219 if (errno != ENOPROTOOPT) { 220 fprintf(stderr, "getsockopt(IP_HDRINCL) on UDP returned %d " 221 "(%s) not ENOPROTOOPT\n", errno, strerror(errno)); 222 exit(-1); 223 } | 257 if (errno != ENOPROTOOPT) 258 errx(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) on UDP " 259 "returned %d (%s) not ENOPROTOOPT\n", errno, 260 strerror(errno)); |
224 225 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) | 261 262 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) |
226 == 0) { 227 fprintf(stderr, "setsockopt(IP_HDRINCL) on UDPsucceeded\n"); 228 exit(-1); 229 } | 263 == 0) 264 err(-1, "test_ip_hdrincl(): setsockopt(IP_HDRINCL) on UDP " 265 "succeeded\n"); |
230 | 266 |
231 if (errno != ENOPROTOOPT) { 232 fprintf(stderr, "setsockopt(IP_HDRINCL) on UDP returned %d " 233 "(%s) not ENOPROTOOPT\n", errno, strerror(errno)); 234 exit(-1); 235 } | 267 if (errno != ENOPROTOOPT) 268 errx(-1, "test_ip_hdrincl(): setsockopt(IP_HDRINCL) on UDP " 269 "returned %d (%s) not ENOPROTOOPT\n", errno, 270 strerror(errno)); |
236 237 close(sock); 238 239 /* 240 * Now try on a raw socket. Access ontrol should prevent non-root 241 * users from creating the raw socket, so check that here based on 242 * geteuid(). If we're non-root, we just return assuming the socket 243 * create fails since the remainder of the tests apply only on a raw 244 * socket. 245 */ 246 sock = socket(PF_INET, SOCK_RAW, 0); 247 if (geteuid() != 0) { 248 if (sock != -1) 249 errx(-1, "test_ip_hdrincl: created raw socket as " 250 "uid %d", geteuid()); 251 return; 252 } | 271 272 close(sock); 273 274 /* 275 * Now try on a raw socket. Access ontrol should prevent non-root 276 * users from creating the raw socket, so check that here based on 277 * geteuid(). If we're non-root, we just return assuming the socket 278 * create fails since the remainder of the tests apply only on a raw 279 * socket. 280 */ 281 sock = socket(PF_INET, SOCK_RAW, 0); 282 if (geteuid() != 0) { 283 if (sock != -1) 284 errx(-1, "test_ip_hdrincl: created raw socket as " 285 "uid %d", geteuid()); 286 return; 287 } |
253 if (sock == -1) { 254 perror("test_ip_hdrincl: socket(PF_INET, SOCK_RAW)"); 255 exit(-1); 256 } | 288 if (sock == -1) 289 err(-1, "test_ip_hdrincl(): socket(PF_INET, SOCK_RAW)"); |
257 258 /* 259 * Make sure the initial value of the flag is 0 (disabled). 260 */ 261 flag[0] = -1; 262 flag[1] = -1; 263 len = sizeof(flag); | 290 291 /* 292 * Make sure the initial value of the flag is 0 (disabled). 293 */ 294 flag[0] = -1; 295 flag[1] = -1; 296 len = sizeof(flag); |
264 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) < 0) { 265 perror("test_ip_hdrincl: getsockopt(IP_HDRINCL) on raw"); 266 exit(-1); 267 } | 297 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) < 0) 298 err(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) on raw " 299 "socket"); |
268 | 300 |
269 if (len != sizeof(flag[0])) { 270 fprintf(stderr, "test_ip_hdrincl: %d bytes returned on " | 301 if (len != sizeof(flag[0])) 302 errx(-1, "test_ip_hdrincl(): %d bytes returned on " |
271 "initial get\n", len); | 303 "initial get\n", len); |
272 exit(-1); 273 } | |
274 | 304 |
275 if (flag[0] != 0) { 276 fprintf(stderr, "test_ip_hdrincl: initial flag value of %d\n", | 305 if (flag[0] != 0) 306 errx(-1, "test_ip_hdrincl(): initial flag value of %d\n", |
277 flag[0]); | 307 flag[0]); |
278 exit(-1); 279 } | |
280 281 /* 282 * Enable the IP_HDRINCL flag. 283 */ 284 flag[0] = 1; 285 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) | 308 309 /* 310 * Enable the IP_HDRINCL flag. 311 */ 312 flag[0] = 1; 313 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) |
286 < 0) { 287 perror("test_ip_hdrincl: setsockopt(IP_HDRINCL, 1)"); 288 exit(-1); 289 } | 314 < 0) 315 err(-1, "test_ip_hdrincl(): setsockopt(IP_HDRINCL, 1)"); |
290 291 /* 292 * Check that the IP_HDRINCL flag was set. 293 */ 294 flag[0] = -1; 295 flag[1] = -1; 296 len = sizeof(flag); | 316 317 /* 318 * Check that the IP_HDRINCL flag was set. 319 */ 320 flag[0] = -1; 321 flag[1] = -1; 322 len = sizeof(flag); |
297 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) < 0) { 298 perror("test_ip_hdrincl: getsockopt(IP_HDRINCL) after set"); 299 exit(-1); 300 } | 323 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) < 0) 324 err(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) after " 325 "set"); |
301 | 326 |
302 if (flag[0] == 0) { 303 fprintf(stderr, "test_ip_hdrincl: getsockopt(IP_HDRINCL) " | 327 if (flag[0] == 0) 328 errx(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) " |
304 "after set had flag of %d\n", flag[0]); | 329 "after set had flag of %d\n", flag[0]); |
305 exit(-1); 306 } | |
307 308#define HISTORICAL_INP_HDRINCL 8 | 330 331#define HISTORICAL_INP_HDRINCL 8 |
309 if (flag[0] != HISTORICAL_INP_HDRINCL) { 310 fprintf(stderr, "test_ip_hdrincl: WARNING: getsockopt(IP_H" | 332 if (flag[0] != HISTORICAL_INP_HDRINCL) 333 warnx("test_ip_hdrincl(): WARNING: getsockopt(IP_H" |
311 "DRINCL) after set had non-historical value of %d\n", 312 flag[0]); | 334 "DRINCL) after set had non-historical value of %d\n", 335 flag[0]); |
313 } | |
314 315 /* 316 * Reset the IP_HDRINCL flag to 0. 317 */ 318 flag[0] = 0; 319 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) | 336 337 /* 338 * Reset the IP_HDRINCL flag to 0. 339 */ 340 flag[0] = 0; 341 if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, sizeof(flag[0])) |
320 < 0) { 321 perror("test_ip_hdrincl: setsockopt(IP_HDRINCL, 0)"); 322 exit(-1); 323 } | 342 < 0) 343 err(-1, "test_ip_hdrincl(): setsockopt(IP_HDRINCL, 0)"); |
324 325 /* 326 * Check that the IP_HDRINCL flag was reset to 0. 327 */ 328 flag[0] = -1; 329 flag[1] = -1; 330 len = sizeof(flag); | 344 345 /* 346 * Check that the IP_HDRINCL flag was reset to 0. 347 */ 348 flag[0] = -1; 349 flag[1] = -1; 350 len = sizeof(flag); |
331 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) < 0) { 332 perror("test_ip_hdrincl: getsockopt(IP_HDRINCL) after reset"); 333 exit(-1); 334 } | 351 if (getsockopt(sock, IPPROTO_IP, IP_HDRINCL, flag, &len) < 0) 352 err(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) after " 353 "reset"); |
335 | 354 |
336 if (flag[0] != 0) { 337 fprintf(stderr, "test_ip_hdrincl: getsockopt(IP_HDRINCL) " | 355 if (flag[0] != 0) 356 errx(-1, "test_ip_hdrincl(): getsockopt(IP_HDRINCL) " |
338 "after set had flag of %d\n", flag[0]); | 357 "after set had flag of %d\n", flag[0]); |
339 exit(-1); 340 } | |
341 342 close(sock); 343} 344 345/* 346 * As with other non-int or larger sized socket options, the IP_TOS and 347 * IP_TTL fields in kernel is stored as an 8-bit value, reflecting the IP 348 * header fields, but useful I/O to the field occurs using 32-bit integers. --- 11 unchanged lines hidden (view full) --- 360 * bits of data. 361 * - When we set it to a non-zero value expressible with a u_char, we can 362 * read that value back. 363 * - When we reset it back to zero, we can read it as 0. 364 * - When we set it to a value >255, the value is truncated to something less 365 * than 255. 366 */ 367static void | 358 359 close(sock); 360} 361 362/* 363 * As with other non-int or larger sized socket options, the IP_TOS and 364 * IP_TTL fields in kernel is stored as an 8-bit value, reflecting the IP 365 * header fields, but useful I/O to the field occurs using 32-bit integers. --- 11 unchanged lines hidden (view full) --- 377 * bits of data. 378 * - When we set it to a non-zero value expressible with a u_char, we can 379 * read that value back. 380 * - When we reset it back to zero, we can read it as 0. 381 * - When we set it to a value >255, the value is truncated to something less 382 * than 255. 383 */ 384static void |
368test_ip_uchar(int option, char *optionname, int initial) | 385test_ip_uchar(int sock, const char *socktypename, int option, 386 const char *optionname, int initial) |
369{ | 387{ |
370 int sock, val[2]; | 388 int val[2]; |
371 socklen_t len; 372 | 389 socklen_t len; 390 |
373 sock = socket(PF_INET, SOCK_DGRAM, 0); 374 if (sock == -1) 375 err(-1, "test_ip_tosttl(%s): socket", optionname); 376 | |
377 /* 378 * Check that the initial value is 0, and that the size is one 379 * u_char; 380 */ 381 val[0] = -1; 382 val[1] = -1; 383 len = sizeof(val); 384 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) | 391 /* 392 * Check that the initial value is 0, and that the size is one 393 * u_char; 394 */ 395 val[0] = -1; 396 val[1] = -1; 397 len = sizeof(val); 398 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) |
385 err(-1, "test_ip_tosttl: initial getsockopt(%s)", 386 optionname); | 399 err(-1, "test_ip_uchar(%s, %s): initial getsockopt()", 400 socktypename, optionname); |
387 388 if (len != sizeof(val[0])) | 401 402 if (len != sizeof(val[0])) |
389 errx(-1, "test_ip_tosttl(%s): initial getsockopt() returned " 390 "%d bytes", optionname, len); | 403 errx(-1, "test_ip_uchar(%s, %s): initial getsockopt() " 404 "returned %d bytes", socktypename, optionname, len); |
391 392 if (val[0] == -1) | 405 406 if (val[0] == -1) |
393 errx(-1, "test_ip_tosttl(%s): initial getsockopt() didn't " 394 "return data", optionname); | 407 errx(-1, "test_ip_uchar(%s, %s): initial getsockopt() didn't " 408 "return data", socktypename, optionname); |
395 396 if (val[0] != initial) | 409 410 if (val[0] != initial) |
397 errx(-1, "test_ip_tosttl(%s): initial getsockopt() returned " 398 "value of %d, not %d", optionname, val[0], initial); | 411 errx(-1, "test_ip_uchar(%s, %s): initial getsockopt() " 412 "returned value of %d, not %d", socktypename, optionname, 413 val[0], initial); |
399 400 /* 401 * Set the field to a valid value. 402 */ 403 val[0] = 128; 404 val[1] = -1; 405 if (setsockopt(sock, IPPROTO_IP, option, val, sizeof(val[0])) < 0) | 414 415 /* 416 * Set the field to a valid value. 417 */ 418 val[0] = 128; 419 val[1] = -1; 420 if (setsockopt(sock, IPPROTO_IP, option, val, sizeof(val[0])) < 0) |
406 err(-1, "test_ip_tosttl(%s): setsockopt(128)", optionname); | 421 err(-1, "test_ip_uchar(%s, %s): setsockopt(128)", 422 socktypename, optionname); |
407 408 /* 409 * Check that when we read back the field, we get the same value. 410 */ 411 val[0] = -1; 412 val[1] = -1; 413 len = sizeof(val); 414 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) | 423 424 /* 425 * Check that when we read back the field, we get the same value. 426 */ 427 val[0] = -1; 428 val[1] = -1; 429 len = sizeof(val); 430 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) |
415 err(-1, "test_ip_tosttl(%s): getsockopt() after set to 128", 416 optionname); | 431 err(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 432 "128", socktypename, optionname); |
417 418 if (len != sizeof(val[0])) | 433 434 if (len != sizeof(val[0])) |
419 errx(-1, "test_ip_tosttl(%s): getsockopt() after set to 128 " 420 "returned %d bytes", optionname, len); | 435 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 436 "128 returned %d bytes", socktypename, optionname, len); |
421 422 if (val[0] == -1) | 437 438 if (val[0] == -1) |
423 errx(-1, "test_ip_tosttl(%s): getsockopt() after set to 128 " 424 "didn't return data", optionname); | 439 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 440 "128 didn't return data", socktypename, optionname); |
425 426 if (val[0] != 128) | 441 442 if (val[0] != 128) |
427 errx(-1, "test_ip_tosttl(%s): getsockopt() after set to 128 " 428 "returned %d", optionname, val[0]); | 443 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 444 "128 returned %d", socktypename, optionname, val[0]); |
429 430 /* 431 * Reset the value to 0, check that it was reset. 432 */ 433 val[0] = 0; 434 val[1] = 0; 435 if (setsockopt(sock, IPPROTO_IP, option, val, sizeof(val[0])) < 0) | 445 446 /* 447 * Reset the value to 0, check that it was reset. 448 */ 449 val[0] = 0; 450 val[1] = 0; 451 if (setsockopt(sock, IPPROTO_IP, option, val, sizeof(val[0])) < 0) |
436 err(-1, "test_ip_tosttl(%s): setsockopt() to reset from 128", 437 optionname); | 452 err(-1, "test_ip_uchar(%s, %s): setsockopt() to reset from " 453 "128", socktypename, optionname); |
438 439 if (len != sizeof(val[0])) | 454 455 if (len != sizeof(val[0])) |
440 errx(-1, "test_ip_tosttl(%s): getsockopt() after reset from " 441 "128 returned %d bytes", optionname, len); | 456 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after reset " 457 "from 128 returned %d bytes", socktypename, optionname, 458 len); |
442 443 if (val[0] == -1) | 459 460 if (val[0] == -1) |
444 errx(-1, "test_ip_tosttl(%s): getsockopt() after reset from " 445 "128 didn't return data", optionname); | 461 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after reset " 462 "from 128 didn't return data", socktypename, optionname); |
446 447 if (val[0] != 0) | 463 464 if (val[0] != 0) |
448 errx(-1, "test_ip_tosttl(%s): getsockopt() after reset from " 449 "128 returned %d", optionname, val[0]); | 465 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after reset " 466 "from 128 returned %d", socktypename, optionname, 467 val[0]); |
450 451 /* 452 * Set the value to something out of range and check that it comes 453 * back truncated, or that we get EINVAL back. Traditional u_char 454 * IP socket options truncate, but newer ones (such as multicast 455 * socket options) will return EINVAL. 456 */ 457 val[0] = 32000; 458 val[1] = -1; 459 if (setsockopt(sock, IPPROTO_IP, option, val, sizeof(val[0])) < 0) { 460 /* 461 * EINVAL is a fine outcome, no need to run the truncation 462 * tests. 463 */ | 468 469 /* 470 * Set the value to something out of range and check that it comes 471 * back truncated, or that we get EINVAL back. Traditional u_char 472 * IP socket options truncate, but newer ones (such as multicast 473 * socket options) will return EINVAL. 474 */ 475 val[0] = 32000; 476 val[1] = -1; 477 if (setsockopt(sock, IPPROTO_IP, option, val, sizeof(val[0])) < 0) { 478 /* 479 * EINVAL is a fine outcome, no need to run the truncation 480 * tests. 481 */ |
464 if (errno == EINVAL) { 465 close(sock); | 482 if (errno == EINVAL) |
466 return; | 483 return; |
467 } 468 err(-1, "test_ip_tosttl(%s): getsockopt(32000)", optionname); | 484 err(-1, "test_ip_uchar(%s, %s): getsockopt(32000)", 485 socktypename, optionname); |
469 } 470 471 val[0] = -1; 472 val[1] = -1; 473 len = sizeof(val); 474 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) | 486 } 487 488 val[0] = -1; 489 val[1] = -1; 490 len = sizeof(val); 491 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) |
475 err(-1, "test_ip_tosttl(%s): getsockopt() after set to 32000", 476 optionname); | 492 err(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 493 "32000", socktypename, optionname); |
477 478 if (len != sizeof(val[0])) | 494 495 if (len != sizeof(val[0])) |
479 errx(-1, "test_ip_tosttl(%s): getsockopt() after set to 32000" 480 "returned %d bytes", optionname, len); | 496 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 497 "32000 returned %d bytes", socktypename, optionname, 498 len); |
481 482 if (val[0] == -1) | 499 500 if (val[0] == -1) |
483 errx(-1, "test_ip_tosttl(%s): getsockopt() after set to 32000" 484 "didn't return data", optionname); | 501 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 502 "32000 didn't return data", socktypename, optionname); |
485 486 if (val[0] == 32000) | 503 504 if (val[0] == 32000) |
487 errx(-1, "test_ip_tosttl(%s): getsockopt() after set to 32000" 488 "returned 32000: failed to truncate", optionname); 489 490 close(sock); | 505 errx(-1, "test_ip_uchar(%s, %s): getsockopt() after set to " 506 "32000 returned 32000: failed to truncate", socktypename, 507 optionname); |
491} 492 493/* 494 * Generic test for a boolean socket option. Caller provides the option 495 * number, string name, expected default (initial) value, and whether or not 496 * the option is root-only. For each option, test: 497 * 498 * - That we can read the option. 499 * - That the initial value is as expected. 500 * - That we can modify the value. 501 * - That on modification, the new value can be read back. 502 * - That we can reset the value. 503 * - that on reset, the new value can be read back. | 508} 509 510/* 511 * Generic test for a boolean socket option. Caller provides the option 512 * number, string name, expected default (initial) value, and whether or not 513 * the option is root-only. For each option, test: 514 * 515 * - That we can read the option. 516 * - That the initial value is as expected. 517 * - That we can modify the value. 518 * - That on modification, the new value can be read back. 519 * - That we can reset the value. 520 * - that on reset, the new value can be read back. |
504 * 505 * Test using a UDP socket. | |
506 */ 507#define BOOLEAN_ANYONE 1 508#define BOOLEAN_ROOTONLY 1 509static void | 521 */ 522#define BOOLEAN_ANYONE 1 523#define BOOLEAN_ROOTONLY 1 524static void |
510test_ip_boolean(int option, char *optionname, int initial, int rootonly) | 525test_ip_boolean(int sock, const char *socktypename, int option, 526 char *optionname, int initial, int rootonly) |
511{ | 527{ |
512 int newvalue, sock, val[2]; | 528 int newvalue, val[2]; |
513 socklen_t len; 514 | 529 socklen_t len; 530 |
515 sock = socket(PF_INET, SOCK_DGRAM, 0); 516 if (sock == -1) 517 err(-1, "test_ip_boolean(%s): socket", optionname); 518 | |
519 /* 520 * The default for a boolean might be true or false. If it's false, 521 * we will try setting it to true (but using a non-1 value of true). 522 * If it's true, we'll set it to false. 523 */ 524 if (initial == 0) 525 newvalue = 0xff; 526 else 527 newvalue = 0; 528 529 val[0] = -1; 530 val[1] = -1; 531 len = sizeof(val); 532 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) 533 err(-1, "test_ip_boolean: initial getsockopt()"); 534 535 if (len != sizeof(val[0])) | 531 /* 532 * The default for a boolean might be true or false. If it's false, 533 * we will try setting it to true (but using a non-1 value of true). 534 * If it's true, we'll set it to false. 535 */ 536 if (initial == 0) 537 newvalue = 0xff; 538 else 539 newvalue = 0; 540 541 val[0] = -1; 542 val[1] = -1; 543 len = sizeof(val); 544 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) 545 err(-1, "test_ip_boolean: initial getsockopt()"); 546 547 if (len != sizeof(val[0])) |
536 errx(-1, "test_ip_boolean(%s): initial getsockopt() returned " 537 "%d bytes", optionname, len); | 548 errx(-1, "test_ip_boolean(%s, %s): initial getsockopt() " 549 "returned %d bytes", socktypename, optionname, len); |
538 539 if (val[0] == -1) | 550 551 if (val[0] == -1) |
540 errx(-1, "test_ip_boolean(%s): initial getsockopt() didn't " 541 "return data", optionname); | 552 errx(-1, "test_ip_boolean(%s, %s): initial getsockopt() " 553 "didn't return data", socktypename, optionname); |
542 543 if (val[0] != initial) | 554 555 if (val[0] != initial) |
544 errx(-1, "test_ip_boolean(%s): initial getsockopt() returned " 545 "%d (expected %d)", optionname, val[0], initial); | 556 errx(-1, "test_ip_boolean(%s, %s): initial getsockopt() " 557 "returned %d (expected %d)", socktypename, optionname, 558 val[0], initial); |
546 547 /* 548 * Set the socket option to a new non-default value. 549 */ 550 if (setsockopt(sock, IPPROTO_IP, option, &newvalue, sizeof(newvalue)) 551 < 0) | 559 560 /* 561 * Set the socket option to a new non-default value. 562 */ 563 if (setsockopt(sock, IPPROTO_IP, option, &newvalue, sizeof(newvalue)) 564 < 0) |
552 err(-1, "test_ip_boolean(%s): setsockopt() to %d", optionname, 553 newvalue); | 565 err(-1, "test_ip_boolean(%s, %s): setsockopt() to %d", 566 socktypename, optionname, newvalue); |
554 555 /* 556 * Read the value back and see if it is not the default (note: will 557 * not be what we set it to, as we set it to 0xff above). 558 */ 559 val[0] = -1; 560 val[1] = -1; 561 len = sizeof(val); 562 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) | 567 568 /* 569 * Read the value back and see if it is not the default (note: will 570 * not be what we set it to, as we set it to 0xff above). 571 */ 572 val[0] = -1; 573 val[1] = -1; 574 len = sizeof(val); 575 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) |
563 err(-1, "test_ip_boolean(%s): getsockopt() after set to %d", 564 optionname, newvalue); | 576 err(-1, "test_ip_boolean(%s, %s): getsockopt() after set to " 577 "%d", socktypename, optionname, newvalue); |
565 566 if (len != sizeof(val[0])) | 578 579 if (len != sizeof(val[0])) |
567 errx(-1, "test_ip_boolean(%s): getsockopt() after set to %d " 568 "returned %d bytes", optionname, newvalue, len); | 580 errx(-1, "test_ip_boolean(%s, %s): getsockopt() after set " 581 "to %d returned %d bytes", socktypename, optionname, 582 newvalue, len); |
569 570 if (val[0] == -1) | 583 584 if (val[0] == -1) |
571 errx(-1, "test_ip_boolean(%s): getsockopt() after set to %d " 572 "didn't return data", optionname, newvalue); | 585 errx(-1, "test_ip_boolean(%s, %s): getsockopt() after set " 586 "to %d didn't return data", socktypename, optionname, 587 newvalue); |
573 574 /* 575 * If we set it to true, check for '1', otherwise '0. 576 */ 577 if (val[0] != (newvalue ? 1 : 0)) | 588 589 /* 590 * If we set it to true, check for '1', otherwise '0. 591 */ 592 if (val[0] != (newvalue ? 1 : 0)) |
578 errx(-1, "test_ip_boolean(%s): getsockopt() after set to %d " 579 "returned %d", optionname, newvalue, val[0]); | 593 errx(-1, "test_ip_boolean(%s, %s): getsockopt() after set " 594 "to %d returned %d", socktypename, optionname, newvalue, 595 val[0]); |
580 581 /* 582 * Reset to initial value. 583 */ 584 newvalue = initial; 585 if (setsockopt(sock, IPPROTO_IP, option, &newvalue, sizeof(newvalue)) 586 < 0) | 596 597 /* 598 * Reset to initial value. 599 */ 600 newvalue = initial; 601 if (setsockopt(sock, IPPROTO_IP, option, &newvalue, sizeof(newvalue)) 602 < 0) |
587 err(-1, "test_ip_boolean(%s): setsockopt() to reset", 588 optionname); | 603 err(-1, "test_ip_boolean(%s, %s): setsockopt() to reset", 604 socktypename, optionname); |
589 590 /* 591 * Check reset version. 592 */ 593 val[0] = -1; 594 val[1] = -1; 595 len = sizeof(val); 596 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) | 605 606 /* 607 * Check reset version. 608 */ 609 val[0] = -1; 610 val[1] = -1; 611 len = sizeof(val); 612 if (getsockopt(sock, IPPROTO_IP, option, val, &len) < 0) |
597 err(-1, "test_ip_boolean(%s): getsockopt() after reset", 598 optionname); | 613 err(-1, "test_ip_boolean(%s, %s): getsockopt() after reset", 614 socktypename, optionname); |
599 600 if (len != sizeof(val[0])) | 615 616 if (len != sizeof(val[0])) |
601 errx(-1, "test_ip_boolean(%s): getsockopt() after reset " 602 "returned %d bytes", optionname, len); | 617 errx(-1, "test_ip_boolean(%s, %s): getsockopt() after reset " 618 "returned %d bytes", socktypename, optionname, len); |
603 604 if (val[0] == -1) | 619 620 if (val[0] == -1) |
605 errx(-1, "test_ip_boolean(%s): getsockopt() after reset " 606 "didn't return data", optionname); | 621 errx(-1, "test_ip_boolean(%s, %s): getsockopt() after reset " 622 "didn't return data", socktypename, optionname); |
607 608 if (val[0] != newvalue) | 623 624 if (val[0] != newvalue) |
609 errx(-1, "test_ip_boolean(%s): getsockopt() after reset " 610 "returned %d", optionname, newvalue); 611 612 close(sock); | 625 errx(-1, "test_ip_boolean(%s, %s): getsockopt() after reset " 626 "returned %d", socktypename, optionname, newvalue); |
613} 614 615/* 616 * XXX: For now, nothing here. 617 */ 618static void | 627} 628 629/* 630 * XXX: For now, nothing here. 631 */ 632static void |
619test_ip_multicast_if(void) | 633test_ip_multicast_if(int sock, const char *socktypename) |
620{ 621 622 /* 623 * It's probably worth trying INADDR_ANY and INADDR_LOOPBACK here 624 * to see what happens. 625 */ 626} 627 628/* 629 * XXX: For now, nothing here. 630 */ 631static void | 634{ 635 636 /* 637 * It's probably worth trying INADDR_ANY and INADDR_LOOPBACK here 638 * to see what happens. 639 */ 640} 641 642/* 643 * XXX: For now, nothing here. 644 */ 645static void |
632test_ip_multicast_vif(void) | 646test_ip_multicast_vif(int sock, const char *socktypename) |
633{ 634 635 /* 636 * This requires some knowledge of the number of virtual interfaces, 637 * and what is valid. 638 */ 639} 640 641/* 642 * XXX: For now, nothing here. 643 */ 644static void | 647{ 648 649 /* 650 * This requires some knowledge of the number of virtual interfaces, 651 * and what is valid. 652 */ 653} 654 655/* 656 * XXX: For now, nothing here. 657 */ 658static void |
645test_ip_multicast_membership(void) | 659test_ip_multicast_membership(int sock, const char *socktypename) |
646{ 647 648} 649 650static void | 660{ 661 662} 663 664static void |
651test_ip_multicast(void) | 665testsuite(int priv) |
652{ | 666{ |
667 const char *socktypenameset[] = {"SOCK_DGRAM", "SOCK_STREAM", 668 "SOCK_RAW"}; 669 int socktypeset[] = {SOCK_DGRAM, SOCK_STREAM, SOCK_RAW}; 670 const char *socktypename; 671 int i, sock, socktype; |
|
653 | 672 |
654 test_ip_multicast_if(); 655 test_ip_multicast_vif(); | 673 test_ip_hdrincl(); |
656 | 674 |
657 /* 658 * Test the multicast TTL exactly as we would the regular TTL, only 659 * expect a different default. 660 */ 661 test_ip_uchar(IP_MULTICAST_TTL, "IP_MULTICAST_TTL", 1); | 675 for (i = 0; i < sizeof(socktypeset)/sizeof(int); i++) { 676 socktype = socktypeset[i]; 677 socktypename = socktypenameset[i]; |
662 | 678 |
663 /* 664 * The multicast loopback flag can be tested using our boolean 665 * tester, but only because the FreeBSD API is a bit more flexible 666 * than earlir APIs and will accept an int as well as a u_char. 667 * Loopback is enabled by default. 668 */ 669 test_ip_boolean(IP_MULTICAST_LOOP, "IP_MULTICAST_LOOP", 1, 670 BOOLEAN_ANYONE); | 679 /* 680 * If we can't acquire root privilege, we can't open raw 681 * sockets, so don't actually try. 682 */ 683 if (getuid() != 0 && socktype == SOCK_RAW) 684 continue; |
671 | 685 |
672 test_ip_multicast_membership(); 673} | 686 /* 687 * XXXRW: On 5.3, this seems not to work for SOCK_RAW. 688 */ 689 sock = get_socket(socktype, priv); 690 if (sock == -1) 691 err(-1, "get_socket(%s, %d) for test_ip_uchar(IP_TOS)", 692 socktypename, priv); 693 test_ip_uchar(sock, socktypename, IP_TOS, "IP_TOS", 0); 694 close(sock); |
674 | 695 |
675static void 676testsuite(void) 677{ | 696 sock = get_socket(socktype, priv); 697 if (sock == -1) 698 err(-1, "get_socket(%s %d) for test_ip_uchar(IP_TTL)", 699 socktypename, priv); 700 test_ip_uchar(sock, socktypename, IP_TTL, "IP_TTL", 64); 701 close(sock); |
678 | 702 |
679 test_ip_hdrincl(); | 703 sock = get_socket(socktype, priv); 704 if (sock == -1) 705 err(-1, "get_socket(%s, %d) for test_ip_boolean" 706 "(IP_RECVOPTS)", socktypename, priv); 707 test_ip_boolean(sock, socktypename, IP_RECVOPTS, 708 "IP_RECVOPTS", 0, BOOLEAN_ANYONE); 709 close(sock); |
680 | 710 |
681 test_ip_uchar(IP_TOS, "IP_TOS", 0); 682 test_ip_uchar(IP_TTL, "IP_TTL", 64); | 711 sock = get_socket(socktype, priv); 712 if (sock == -1) 713 err(-1, "get_socket(%s, %d) for test_ip_boolean" 714 "(IP_RECVRETOPTS)", socktypename, priv); 715 test_ip_boolean(sock, socktypename, IP_RECVRETOPTS, 716 "IP_RECVRETOPTS", 0, BOOLEAN_ANYONE); 717 close(sock); |
683 | 718 |
684 test_ip_boolean(IP_RECVOPTS, "IP_RECVOPTS", 0, BOOLEAN_ANYONE); 685 test_ip_boolean(IP_RECVRETOPTS, "IP_RECVRETOPTS", 0, BOOLEAN_ANYONE); 686 test_ip_boolean(IP_RECVDSTADDR, "IP_RECVDSTADDR", 0, BOOLEAN_ANYONE); 687 test_ip_boolean(IP_RECVTTL, "IP_RECVTTL", 0, BOOLEAN_ANYONE); 688 test_ip_boolean(IP_RECVIF, "IP_RECVIF", 0, BOOLEAN_ANYONE); 689 test_ip_boolean(IP_FAITH, "IP_FAITH", 0, BOOLEAN_ANYONE); 690 test_ip_boolean(IP_ONESBCAST, "IP_ONESBCAST", 0, BOOLEAN_ANYONE); | 719 sock = get_socket(socktype, priv); 720 if (sock == -1) 721 err(-1, "get_socket(%s, %d) for test_ip_boolean" 722 "(IP_RECVDSTADDR)", socktypename, priv); 723 test_ip_boolean(sock, socktypename, IP_RECVDSTADDR, 724 "IP_RECVDSTADDR", 0, BOOLEAN_ANYONE); 725 close(sock); |
691 | 726 |
692 /* 693 * XXX: Still need to test: 694 * IP_PORTRANGE 695 * IP_IPSEC_POLICY? 696 */ | 727 sock = get_socket(socktype, priv); 728 if (sock == -1) 729 err(-1, "get_socket(%s, %d) for test_ip_boolean" 730 "(IP_RECVTTL)", socktypename, priv); 731 test_ip_boolean(sock, socktypename, IP_RECVTTL, "IP_RECVTTL", 732 0, BOOLEAN_ANYONE); 733 close(sock); |
697 | 734 |
698 test_ip_multicast(); | 735 sock = get_socket(socktype, priv); 736 if (sock == -1) 737 err(-1, "get_socket(%s, %d) for test_ip_boolean" 738 "(IP_RECVIF)", socktypename, priv); 739 test_ip_boolean(sock, socktypename, IP_RECVIF, "IP_RECVIF", 740 0, BOOLEAN_ANYONE); 741 close(sock); |
699 | 742 |
700 test_ip_options(); | 743 sock = get_socket(socktype, priv); 744 if (sock == -1) 745 err(-1, "get_socket(%s, %d) for test_ip_boolean" 746 "(IP_FAITH)", socktypename, priv); 747 test_ip_boolean(sock, socktypename, IP_FAITH, "IP_FAITH", 0, 748 BOOLEAN_ANYONE); 749 close(sock); 750 751 sock = get_socket(socktype, priv); 752 if (sock == -1) 753 err(-1, "get_socket(%s, %d) for test_ip_boolean" 754 "(IP_ONESBCAST)", socktypename, priv); 755 test_ip_boolean(sock, socktypename, IP_ONESBCAST, 756 "IP_ONESBCAST", 0, BOOLEAN_ANYONE); 757 close(sock); 758 759 /* 760 * Test the multicast TTL exactly as we would the regular 761 * TTL, only expect a different default. 762 */ 763 sock = get_socket(socktype, priv); 764 if (sock == -1) 765 err(-1, "get_socket(%s, %d) for IP_MULTICAST_TTL", 766 socktypename, priv); 767 test_ip_uchar(sock, socktypename, IP_MULTICAST_TTL, 768 "IP_MULTICAST_TTL", 1); 769 close(sock); 770 771 /* 772 * The multicast loopback flag can be tested using our 773 * boolean tester, but only because the FreeBSD API is a bit 774 * more flexible than earlir APIs and will accept an int as 775 * well as a u_char. Loopback is enabled by default. 776 */ 777 sock = get_socket(socktype, priv); 778 if (sock == -1) 779 err(-1, "get_socket(%s, %d) for IP_MULTICAST_LOOP", 780 socktypename, priv); 781 test_ip_boolean(sock, socktypename, IP_MULTICAST_LOOP, 782 "IP_MULTICAST_LOOP", 1, BOOLEAN_ANYONE); 783 close(sock); 784 785 sock = get_socket(socktype, priv); 786 if (sock == -1) 787 err(-1, "get_socket(%s, %d) for test_ip_options", 788 socktypename, priv); 789 //test_ip_options(sock, socktypename); 790 close(sock); 791 792 test_ip_multicast_if(0, NULL); 793 test_ip_multicast_vif(0, NULL); 794 test_ip_multicast_membership(0, NULL); 795 /* 796 * XXX: Still need to test: 797 * IP_PORTRANGE 798 * IP_IPSEC_POLICY? 799 */ 800 } |
701} 702 703/* 704 * Very simply exercise that we can get and set each option. If we're running 705 * as root, run it also as nobody. If not as root, complain about that. 706 */ 707int 708main(int argc, char *argv[]) 709{ 710 711 if (geteuid() != 0) { | 801} 802 803/* 804 * Very simply exercise that we can get and set each option. If we're running 805 * as root, run it also as nobody. If not as root, complain about that. 806 */ 807int 808main(int argc, char *argv[]) 809{ 810 811 if (geteuid() != 0) { |
712 warnx("Not running as root, can't run as-root tests"); | 812 warnx("Not running as root, can't run tests as root"); |
713 fprintf(stderr, "\n"); | 813 fprintf(stderr, "\n"); |
714 fprintf(stderr, "Running tests with uid %d\n", geteuid()); 715 testsuite(); 716 fprintf(stderr, "PASS\n"); | 814 fprintf(stderr, 815 "Running tests with uid %d sock uid %d\n", geteuid(), 816 geteuid()); 817 testsuite(PRIV_ASIS); |
717 } else { | 818 } else { |
718 fprintf(stderr, "Running tests with uid 0\n"); 719 testsuite(); 720 if (setuid(65534) != 0) 721 err(-1, "setuid(65534)"); 722 fprintf(stderr, "Running tests with uid 65535\n"); 723 testsuite(); 724 fprintf(stderr, "PASS\n"); | 819 fprintf(stderr, 820 "Running tests with ruid %d euid %d sock uid 0\n", 821 getuid(), geteuid()); 822 testsuite(PRIV_ASIS); 823 if (seteuid(65534) != 0) 824 err(-1, "seteuid(65534)"); 825 fprintf(stderr, 826 "Running tests with ruid %d euid %d sock uid 0\n", 827 getuid(), geteuid()); 828 testsuite(PRIV_GETROOT); 829 fprintf(stderr, 830 "Running tests with ruid %d euid %d sock uid 65534\n", 831 getuid(), geteuid()); 832 testsuite(PRIV_ASIS); |
725 } | 833 } |
834 fprintf(stderr, "PASS\n"); |
|
726 exit(0); 727} | 835 exit(0); 836} |