Deleted Added
full compact
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}