1 /* SCTP kernel Implementation
2 * (C) Copyright IBM Corp. 2001, 2004
3 * Copyright (c) 1999-2000 Cisco, Inc.
4 * Copyright (c) 1999-2001 Motorola, Inc.
5 * Copyright (c) 2001 Intel Corp.
6 * Copyright (c) 2001 Nokia, Inc.
7 *
8 * The SCTP implementation is free software;
9 * you can redistribute it and/or modify it under the terms of
10 * the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * The SCTP implementation is distributed in the hope that it
15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16 * ************************
17 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 * See the GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with GNU CC; see the file COPYING. If not, write to
22 * the Free Software Foundation, 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
24 *
25 * Please send any bug reports or fixes you make to the
26 * email address(es):
27 * lksctp developers <lksctp-developers@lists.sourceforge.net>
28 *
29 * Or submit a bug report through the following website:
30 * http://www.sf.net/projects/lksctp
31 *
32 * Any bugs reported to us we will try to fix... any fixes shared will
33 * be incorporated into the next SCTP release.
34 *
35 * Written or modified by:
36 * La Monte H.P. Yarroll <piggy@acm.org>
37 * Karl Knutson <karl@athena.chicago.il.us>
38 * Hui Huang <hui.huang@nokia.com>
39 * Jon Grimm <jgrimm@us.ibm.com>
40 * Sridhar Samudrala <samudrala@us.ibm.com>
41 */
42
43 /* This is a functional test to verify the various SCTP level socket
44 * options that can be used to get information about existing SCTP
45 * associations and to configure certain parameters.
46 */
47
48 #include <stdio.h>
49 #include <unistd.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <sys/uio.h>
55 #include <sys/errno.h>
56 #include <netinet/in.h>
57 #include <netinet/sctp.h>
58 #include <sctputil.h>
59 #include "tst_kernel.h"
60
61 char *TCID = __FILE__;
62 int TST_TOTAL = 29;
63 int TST_CNT = 0;
64
65 int
main(void)66 main(void)
67 {
68 int udp_svr_sk, udp_clt_sk, tcp_svr_sk, tcp_clt_sk;
69 int accept_sk, peeloff_sk;
70 sockaddr_storage_t udp_svr_loop, udp_clt_loop;
71 sockaddr_storage_t tcp_svr_loop, tcp_clt_loop;
72 struct iovec iov;
73 struct msghdr inmessage;
74 struct msghdr outmessage;
75 char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
76 char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
77 struct cmsghdr *cmsg;
78 struct sctp_sndrcvinfo *sinfo;
79 struct iovec out_iov;
80 char *message = "hello, world!\n";
81 int error;
82 int pf_class;
83 uint32_t ppid;
84 uint32_t stream;
85 sctp_assoc_t udp_svr_associd, udp_clt_associd;
86 struct sctp_assoc_change *sac;
87 char *big_buffer;
88 struct sctp_event_subscribe subscribe;
89 struct sctp_initmsg initmsg;
90 struct sctp_paddrparams paddrparams;
91 struct sctp_sndrcvinfo set_udp_sk_dflt_param, get_udp_sk_dflt_param;
92 struct sctp_sndrcvinfo set_tcp_sk_dflt_param, get_tcp_sk_dflt_param;
93 struct sctp_sndrcvinfo set_udp_assoc_dflt_param;
94 struct sctp_sndrcvinfo get_udp_assoc_dflt_param;
95 struct sctp_sndrcvinfo set_tcp_assoc_dflt_param;
96 struct sctp_sndrcvinfo get_tcp_assoc_dflt_param;
97 struct sctp_sndrcvinfo get_peeloff_assoc_dflt_param;
98 struct sctp_sndrcvinfo get_accept_assoc_dflt_param;
99 struct sctp_paddrinfo pinfo;
100 int dflt_pathmaxrxt;
101 socklen_t optlen, addrlen;
102 struct sctp_status status;
103 struct sctp_assoc_value value;
104
105 if (tst_check_driver("sctp"))
106 tst_brkm(TCONF, tst_exit, "sctp driver not available");
107
108 /* Rather than fflush() throughout the code, set stdout to
109 * be unbuffered.
110 */
111 setvbuf(stdout, NULL, _IONBF, 0);
112
113 /* Set some basic values which depend on the address family. */
114 #if TEST_V6
115 pf_class = PF_INET6;
116
117 udp_svr_loop.v6.sin6_family = AF_INET6;
118 udp_svr_loop.v6.sin6_addr = in6addr_loopback;
119 udp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1);
120
121 udp_clt_loop.v6.sin6_family = AF_INET6;
122 udp_clt_loop.v6.sin6_addr = in6addr_loopback;
123 udp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+1);
124
125 tcp_svr_loop.v6.sin6_family = AF_INET6;
126 tcp_svr_loop.v6.sin6_addr = in6addr_loopback;
127 tcp_svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+2);
128
129 tcp_clt_loop.v6.sin6_family = AF_INET6;
130 tcp_clt_loop.v6.sin6_addr = in6addr_loopback;
131 tcp_clt_loop.v6.sin6_port = htons(SCTP_TESTPORT_1+3);
132 #else
133 pf_class = PF_INET;
134
135 udp_svr_loop.v4.sin_family = AF_INET;
136 udp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
137 udp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1);
138
139 udp_clt_loop.v4.sin_family = AF_INET;
140 udp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
141 udp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_1+1);
142
143 tcp_svr_loop.v4.sin_family = AF_INET;
144 tcp_svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
145 tcp_svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1+2);
146
147 tcp_clt_loop.v4.sin_family = AF_INET;
148 tcp_clt_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
149 tcp_clt_loop.v4.sin_port = htons(SCTP_TESTPORT_2+3);
150 #endif /* TEST_V6 */
151
152 /* Create the two endpoints which will talk to each other. */
153 udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
154 udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
155
156 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
157 test_enable_assoc_change(udp_svr_sk);
158 test_enable_assoc_change(udp_clt_sk);
159
160 /* Bind these sockets to the test ports. */
161 test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
162 test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
163
164 /* Mark udp_svr_sk as being able to accept new associations. */
165 test_listen(udp_svr_sk, 1);
166
167 /* TEST #1: SCTP_STATUS socket option. */
168 /* Make sure that SCTP_STATUS getsockopt on a socket with no
169 * association fails.
170 */
171 optlen = sizeof(struct sctp_status);
172 memset(&status, 0, optlen);
173 error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status,
174 &optlen);
175 if ((error != -1) && (errno != EINVAL))
176 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) on a "
177 "socket with no assoc error:%d errno:%d",
178 error, errno);
179
180 tst_resm(TPASS, "getsockopt(SCTP_STATUS) on a socket with no assoc");
181
182 /* Send the first message. This will create the association. */
183 outmessage.msg_name = &udp_svr_loop;
184 outmessage.msg_namelen = sizeof(udp_svr_loop);
185 outmessage.msg_iov = &out_iov;
186 outmessage.msg_iovlen = 1;
187 outmessage.msg_control = outcmsg;
188 outmessage.msg_controllen = sizeof(outcmsg);
189 outmessage.msg_flags = 0;
190 cmsg = CMSG_FIRSTHDR(&outmessage);
191 cmsg->cmsg_level = IPPROTO_SCTP;
192 cmsg->cmsg_type = SCTP_SNDRCV;
193 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
194 outmessage.msg_controllen = cmsg->cmsg_len;
195 sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
196 memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
197 ppid = rand(); /* Choose an arbitrary value. */
198 stream = 1;
199 sinfo->sinfo_ppid = ppid;
200 sinfo->sinfo_stream = stream;
201 outmessage.msg_iov->iov_base = message;
202 outmessage.msg_iov->iov_len = strlen(message) + 1;
203 test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
204
205 /* Initialize inmessage for all receives. */
206 big_buffer = test_malloc(REALLY_BIG);
207 memset(&inmessage, 0, sizeof(inmessage));
208 iov.iov_base = big_buffer;
209 iov.iov_len = REALLY_BIG;
210 inmessage.msg_iov = &iov;
211 inmessage.msg_iovlen = 1;
212 inmessage.msg_control = incmsg;
213
214 /* Get the communication up message on udp_svr_sk. */
215 inmessage.msg_controllen = sizeof(incmsg);
216 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
217 test_check_msg_notification(&inmessage, error,
218 sizeof(struct sctp_assoc_change),
219 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
220 sac = (struct sctp_assoc_change *)iov.iov_base;
221 udp_svr_associd = sac->sac_assoc_id;
222
223 /* Get the communication up message on udp_clt_sk. */
224 inmessage.msg_controllen = sizeof(incmsg);
225 error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
226 test_check_msg_notification(&inmessage, error,
227 sizeof(struct sctp_assoc_change),
228 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
229 sac = (struct sctp_assoc_change *)iov.iov_base;
230 udp_clt_associd = sac->sac_assoc_id;
231
232 /* Get the first message which was sent. */
233 inmessage.msg_controllen = sizeof(incmsg);
234 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
235 test_check_msg_data(&inmessage, error, strlen(message) + 1,
236 MSG_EOR, stream, ppid);
237
238 /* Get SCTP_STATUS for udp_clt_sk's given association. */
239 optlen = sizeof(struct sctp_status);
240 memset(&status, 0, optlen);
241 status.sstat_assoc_id = udp_clt_associd;
242 test_getsockopt(udp_clt_sk, SCTP_STATUS, &status, &optlen);
243
244 tst_resm(TPASS, "getsockopt(SCTP_STATUS)");
245
246 /* Make sure that SCTP_STATUS getsockopt with invalid associd fails. */
247 optlen = sizeof(struct sctp_status);
248 memset(&status, 0, optlen);
249 status.sstat_assoc_id = udp_svr_associd;
250 error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_STATUS, &status,
251 &optlen);
252 if ((error != -1) && (errno != EINVAL))
253 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with "
254 "associd error: %d errno:%d", error, errno);
255
256 tst_resm(TPASS, "getsockopt(SCTP_STATUS) with invalid associd");
257
258 /* Make sure that SCTP_STATUS getsockopt with NULL associd fails. */
259 optlen = sizeof(struct sctp_status);
260 memset(&status, 0, optlen);
261 status.sstat_assoc_id = 0;
262 error = getsockopt(udp_svr_sk, SOL_SCTP, SCTP_STATUS, &status,
263 &optlen);
264 if ((error != -1) && (errno != EINVAL))
265 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_STATUS) with "
266 "NULL associd error: %d errno:%d", error, errno);
267
268 tst_resm(TPASS, "getsockopt(SCTP_STATUS) with NULL associd");
269
270 /* Shut down the link. */
271 close(udp_clt_sk);
272
273 /* Get the shutdown complete notification. */
274 inmessage.msg_controllen = sizeof(incmsg);
275 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
276 test_check_msg_notification(&inmessage, error,
277 sizeof(struct sctp_assoc_change),
278 SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
279
280 error = 0;
281 close(udp_svr_sk);
282
283 /* TEST #2: SCTP_EVENTS socket option and SCTP_SHUTDOWN_EVENT
284 * notification.
285 */
286 /* Create the two endpoints which will talk to each other. */
287 udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
288 udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
289
290 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
291 test_enable_assoc_change(udp_svr_sk);
292 test_enable_assoc_change(udp_clt_sk);
293
294 /* Bind these sockets to the test ports. */
295 test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
296 test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
297
298 /* Mark udp_svr_sk as being able to accept new associations. */
299 test_listen(udp_svr_sk, 1);
300
301 /* Get the default events that are enabled on udp_svr_sk. */
302 optlen = sizeof(subscribe);
303 test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen);
304
305 /* Get the default events that are enabled on udp_clt_sk. */
306 optlen = sizeof(subscribe);
307 test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen);
308
309 tst_resm(TPASS, "getsockopt(SCTP_EVENTS)");
310
311 /* Disable all the events on udp_svr_sk and udp_clt_sk. */
312 memset(&subscribe, 0, sizeof(struct sctp_event_subscribe));
313 test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe,
314 sizeof(subscribe));
315 test_setsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe,
316 sizeof(subscribe));
317
318 tst_resm(TPASS, "setsockopt(SCTP_EVENTS)");
319
320 /* Get the updated list of enabled events on udp_svr_sk and
321 * udp_clt_sk.
322 */
323 optlen = sizeof(subscribe);
324 test_getsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe, &optlen);
325 optlen = sizeof(subscribe);
326 test_getsockopt(udp_clt_sk, SCTP_EVENTS, &subscribe, &optlen);
327
328 /* Send a message. This will create the association. */
329 outmessage.msg_iov->iov_base = message;
330 outmessage.msg_iov->iov_len = strlen(message) + 1;
331 test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
332
333 /* Get the message which was sent. */
334 inmessage.msg_controllen = sizeof(incmsg);
335 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
336 test_check_msg_data(&inmessage, error, strlen(message) + 1,
337 MSG_EOR, 0, 0);
338 /* Verify that we received the msg without any ancillary data. */
339 if (inmessage.msg_controllen != 0)
340 tst_brkm(TBROK, tst_exit, "Receive unexpected ancillary data");
341
342 /* Enable SCTP_SHUTDOWN_EVENTs on udp_svr_sk. */
343 memset(&subscribe, 0, sizeof(struct sctp_event_subscribe));
344 subscribe.sctp_shutdown_event = 1;
345 test_setsockopt(udp_svr_sk, SCTP_EVENTS, &subscribe,
346 sizeof(subscribe));
347
348 error = 0;
349 /* Shut down the link. */
350 close(udp_clt_sk);
351
352 /* Get the SHUTDOWN_EVENT notification on udp_svr_sk. */
353 inmessage.msg_controllen = sizeof(incmsg);
354 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
355 test_check_msg_notification(&inmessage, error,
356 sizeof(struct sctp_shutdown_event),
357 SCTP_SHUTDOWN_EVENT, 0);
358
359 tst_resm(TPASS, "setsockopt(SCTP_EVENTS) - SCTP_SHUTDOWN_EVENT");
360
361 close(udp_svr_sk);
362
363 /* TEST #3: whether sctp_opt_info equals */
364 /* Create the two endpoints which will talk to each other. */
365 udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
366 udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
367
368 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
369 test_enable_assoc_change(udp_svr_sk);
370 test_enable_assoc_change(udp_clt_sk);
371
372 /* Bind these sockets to the test ports. */
373 test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
374 test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
375
376 /* Mark udp_svr_sk as being able to accept new associations. */
377 test_listen(udp_svr_sk, 1);
378
379 /* Send the first message. This will create the association. */
380 outmessage.msg_name = &udp_svr_loop;
381 outmessage.msg_namelen = sizeof(udp_svr_loop);
382 outmessage.msg_iov = &out_iov;
383 outmessage.msg_iovlen = 1;
384 outmessage.msg_control = outcmsg;
385 outmessage.msg_controllen = sizeof(outcmsg);
386 outmessage.msg_flags = 0;
387 cmsg = CMSG_FIRSTHDR(&outmessage);
388 cmsg->cmsg_level = IPPROTO_SCTP;
389 cmsg->cmsg_type = SCTP_SNDRCV;
390 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
391 outmessage.msg_controllen = cmsg->cmsg_len;
392 sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
393 memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
394 ppid = rand(); /* Choose an arbitrary value. */
395 stream = 1;
396 sinfo->sinfo_ppid = ppid;
397 sinfo->sinfo_stream = stream;
398 outmessage.msg_iov->iov_base = message;
399 outmessage.msg_iov->iov_len = strlen(message) + 1;
400 test_sendmsg(udp_clt_sk, &outmessage, 0, strlen(message)+1);
401
402 /* Get the communication up message on udp_clt_sk. */
403 inmessage.msg_controllen = sizeof(incmsg);
404 error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
405 test_check_msg_notification(&inmessage, error,
406 sizeof(struct sctp_assoc_change),
407 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
408 sac = (struct sctp_assoc_change *)iov.iov_base;
409 udp_clt_associd = sac->sac_assoc_id;
410
411 /* Compare the SCTP_STATUS result between sctp_opt_info and
412 * getsockopt
413 */
414 {
415 struct sctp_status status1, status2;
416
417 memset(&status1, 0, sizeof(status1));
418 memset(&status2, 0, sizeof(status2));
419 optlen = sizeof(struct sctp_status);
420
421 /* Test SCTP_STATUS for udp_clt_sk's given association. */
422 error = sctp_opt_info(udp_clt_sk,udp_clt_associd,SCTP_STATUS,
423 (char *)&status1, &optlen);
424 if (error != 0)
425 tst_brkm(TBROK, tst_exit,
426 "sctp_opt_info(SCTP_STATUS): %s",
427 strerror(errno));
428
429 status2.sstat_assoc_id = udp_clt_associd;
430 error = getsockopt(udp_clt_sk, IPPROTO_SCTP, SCTP_STATUS,
431 (char *)&status2, &optlen);
432 if (error != 0)
433 tst_brkm(TBROK, tst_exit,
434 "getsockopt(SCTP_STATUS): %s",
435 strerror(errno));
436 if (strncmp((char *)&status1, (char *)&status2, optlen))
437 tst_brkm(TBROK, tst_exit, "sctp_opt_info(SCTP_STAUS) "
438 "doesn't match getsockopt(SCTP_STATUS)");
439
440 tst_resm(TPASS, "sctp_opt_info(SCTP_STATUS)");
441 }
442 error = 0;
443 /* Shut down the link. */
444 close(udp_svr_sk);
445 close(udp_clt_sk);
446
447 /* TEST #4: SCTP_INITMSG socket option. */
448 /* Create a socket. */
449 udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
450
451 /* Bind this socket to the test port. */
452 test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
453
454 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
455 test_enable_assoc_change(udp_svr_sk);
456
457 /* Get the default parameters for association initialization. */
458 optlen = sizeof(initmsg);
459 test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen);
460
461 tst_resm(TPASS, "getsockopt(SCTP_INITMSG)");
462
463 /* Change the parameters for association initialization. */
464 initmsg.sinit_num_ostreams = 5;
465 initmsg.sinit_max_instreams = 5;
466 initmsg.sinit_max_attempts = 3;
467 initmsg.sinit_max_init_timeo = 30;
468 test_setsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, sizeof(initmsg));
469
470 tst_resm(TPASS, "setsockopt(SCTP_INITMSG)");
471
472 /* Get the updated parameters for association initialization. */
473 optlen = sizeof(initmsg);
474 test_getsockopt(udp_svr_sk, SCTP_INITMSG, &initmsg, &optlen);
475
476 close(udp_svr_sk);
477
478 /* TEST #5: SCTP_PEER_ADDR_PARAMS socket option. */
479 /* Create a socket. */
480 udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
481
482 /* Get the default parameters for this endpoint */
483 optlen = sizeof(paddrparams);
484 memset(&paddrparams, 0, sizeof(paddrparams));
485 paddrparams.spp_address.ss_family = AF_INET;
486 test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
487 &optlen);
488
489 dflt_pathmaxrxt = paddrparams.spp_pathmaxrxt;
490 tst_resm(TPASS, "getsockopt(SCTP_PEER_ADDR_PARAMS)");
491
492 /* Change the default parameters for this endpoint (socket) */
493 paddrparams.spp_hbinterval = 1000;
494 paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
495 paddrparams.spp_sackdelay = 100;
496 test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
497 sizeof(paddrparams));
498
499 paddrparams.spp_pathmaxrxt = 0;
500
501 /* Get the updated default parameters for this endpoint. */
502 optlen = sizeof(paddrparams);
503 test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
504 &optlen);
505 if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt+1)
506 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
507 "mismatch");
508
509 value.assoc_id = 0;
510 optlen = sizeof(value);
511 test_getsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value,
512 &optlen);
513 if (value.assoc_value != 100)
514 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DELAYED_ACK_TIME) "
515 "mismatch");
516
517 value.assoc_id = 0;
518 value.assoc_value = 250;
519 test_setsockopt(udp_svr_sk, SCTP_DELAYED_ACK_TIME, &value,
520 sizeof(value));
521 optlen = sizeof(paddrparams);
522 test_getsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
523 &optlen);
524 if (paddrparams.spp_sackdelay != 250)
525 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
526 "mismatch");
527
528 tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME)");
529
530
531 /* Ensure that prior defaults are preserved for a new endpoint */
532 udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
533 optlen = sizeof(paddrparams);
534 memset(&paddrparams, 0, sizeof(paddrparams));
535 paddrparams.spp_address.ss_family = AF_INET;
536 test_getsockopt(udp_clt_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
537 &optlen);
538 if (paddrparams.spp_pathmaxrxt != dflt_pathmaxrxt)
539 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_PEER_ADDR_PARAMS) "
540 "mismatch");
541
542
543 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS)");
544
545 /* Invalid assoc id */
546 paddrparams.spp_assoc_id = 1234;
547 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
548 &paddrparams,
549 sizeof(paddrparams));
550 if ((-1 != error) || (EINVAL != errno))
551 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
552 "invalid associd error:%d, errno:%d\n",
553 error, errno);
554
555 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
556 "- one-to-many style invalid associd");
557
558 test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
559 test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
560
561 test_listen(udp_svr_sk, 5);
562
563 test_enable_assoc_change(udp_svr_sk);
564 test_enable_assoc_change(udp_clt_sk);
565
566 /* Do a connect on a UDP-style socket and establish an association. */
567 test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
568
569 /* Receive the COMM_UP notifications and get the associd's */
570 inmessage.msg_controllen = sizeof(incmsg);
571 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
572 test_check_msg_notification(&inmessage, error,
573 sizeof(struct sctp_assoc_change),
574 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
575 sac = (struct sctp_assoc_change *)iov.iov_base;
576
577 paddrparams.spp_assoc_id = sac->sac_assoc_id;
578 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
579 paddrparams.spp_hbinterval = 1000;
580 paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
581 test_setsockopt(udp_svr_sk, SCTP_PEER_ADDR_PARAMS, &paddrparams,
582 sizeof(paddrparams));
583 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) - "
584 "one-to-many style valid associd valid address");
585
586 paddrparams.spp_assoc_id = sac->sac_assoc_id;
587 memcpy(&paddrparams.spp_address, &udp_svr_loop, sizeof(udp_svr_loop));
588 paddrparams.spp_hbinterval = 1000;
589 paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
590
591 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
592 &paddrparams,
593 sizeof(paddrparams));
594 if ((-1 != error) || (EINVAL != errno))
595 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
596 "invalid transport error:%d, errno:%d\n",
597 error, errno);
598
599 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
600 "- one-to-many style invalid transport");
601
602 paddrparams.spp_assoc_id = sac->sac_assoc_id;
603 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
604 paddrparams.spp_hbinterval = 1000;
605 paddrparams.spp_pathmaxrxt = dflt_pathmaxrxt+1;
606
607 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
608 &paddrparams,
609 sizeof(paddrparams) - 1);
610 if ((-1 != error) || (EINVAL != errno))
611 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
612 "invalid parameter length error:%d, errno:%d\n",
613 error, errno);
614
615 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
616 "- one-to-many style invalid parameter length");
617
618 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME,
619 &value,
620 sizeof(value) - 1);
621 if ((-1 != error) || (EINVAL != errno))
622 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
623 "invalid parameter length error:%d, errno:%d\n",
624 error, errno);
625
626 tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) "
627 "- one-to-many style invalid parameter length");
628
629 memset(&paddrparams, 0, sizeof(paddrparams));
630 paddrparams.spp_assoc_id = sac->sac_assoc_id;
631 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
632 paddrparams.spp_sackdelay = 501;
633
634 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
635 &paddrparams,
636 sizeof(paddrparams));
637 if ((-1 != error) || (EINVAL != errno))
638 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
639 "invalid sack delay error:%d, errno:%d\n",
640 error, errno);
641
642 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
643 "- one-to-many style invalid sack delay");
644
645 value.assoc_id = sac->sac_assoc_id;
646 value.assoc_value = 501;
647
648 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DELAYED_ACK_TIME,
649 &value,
650 sizeof(value));
651 if ((-1 != error) || (EINVAL != errno))
652 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DELAYED_ACK_TIME) "
653 "invalid sack delay error:%d, errno:%d\n",
654 error, errno);
655
656 tst_resm(TPASS, "setsockopt(SCTP_DELAYED_ACK_TIME) "
657 "- one-to-many style invalid sack delay");
658
659 memset(&paddrparams, 0, sizeof(paddrparams));
660 paddrparams.spp_assoc_id = sac->sac_assoc_id;
661 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
662 paddrparams.spp_pathmtu = 511;
663
664 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
665 &paddrparams,
666 sizeof(paddrparams));
667 if ((-1 != error) || (EINVAL != errno))
668 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
669 "invalid path MTU error:%d, errno:%d\n",
670 error, errno);
671
672 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
673 "- one-to-many style invalid path MTU");
674
675 memset(&paddrparams, 0, sizeof(paddrparams));
676 paddrparams.spp_assoc_id = sac->sac_assoc_id;
677 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
678 paddrparams.spp_flags = SPP_HB_ENABLE | SPP_HB_DISABLE;
679
680 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
681 &paddrparams,
682 sizeof(paddrparams));
683 if ((-1 != error) || (EINVAL != errno))
684 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
685 "invalid hb enable flags error:%d, errno:%d\n",
686 error, errno);
687
688 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
689 "- one-to-many style invalid hb enable flags");
690
691 memset(&paddrparams, 0, sizeof(paddrparams));
692 paddrparams.spp_assoc_id = sac->sac_assoc_id;
693 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
694 paddrparams.spp_flags = SPP_PMTUD_ENABLE | SPP_PMTUD_DISABLE;
695
696 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
697 &paddrparams,
698 sizeof(paddrparams));
699 if ((-1 != error) || (EINVAL != errno))
700 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
701 "invalid PMTU discovery enable flags error:%d, errno:%d\n",
702 error, errno);
703
704 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
705 "- one-to-many style invalid PMTU discovery enable flags");
706
707 memset(&paddrparams, 0, sizeof(paddrparams));
708 paddrparams.spp_assoc_id = sac->sac_assoc_id;
709 memcpy(&paddrparams.spp_address, &udp_clt_loop, sizeof(udp_clt_loop));
710 paddrparams.spp_flags = SPP_SACKDELAY_ENABLE | SPP_SACKDELAY_DISABLE;
711
712 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
713 &paddrparams,
714 sizeof(paddrparams));
715 if ((-1 != error) || (EINVAL != errno))
716 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
717 "invalid sack delay enable flags error:%d, errno:%d\n",
718 error, errno);
719
720 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
721 "- one-to-many style invalid sack delay enable flags");
722
723 memset(&paddrparams, 0, sizeof(paddrparams));
724 paddrparams.spp_flags = SPP_HB_DEMAND;
725
726 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_PEER_ADDR_PARAMS,
727 &paddrparams,
728 sizeof(paddrparams));
729 if ((-1 != error) || (EINVAL != errno))
730 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
731 "invalid hb demand error:%d, errno:%d\n",
732 error, errno);
733
734 tst_resm(TPASS, "setsockopt(SCTP_PEER_ADDR_PARAMS) "
735 "- one-to-many style invalid hb demand");
736
737 close(udp_svr_sk);
738 close(udp_clt_sk);
739
740
741 /* TEST #6: SCTP_DEFAULT_SEND_PARAM socket option. */
742 /* Create and bind 2 UDP-style sockets(udp_svr_sk, udp_clt_sk) and
743 * 2 TCP-style sockets. (tcp_svr_sk, tcp_clt_sk)
744 */
745 udp_svr_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
746 udp_clt_sk = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
747 tcp_svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
748 tcp_clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
749
750 /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
751 test_enable_assoc_change(udp_svr_sk);
752 test_enable_assoc_change(udp_clt_sk);
753 test_enable_assoc_change(tcp_svr_sk);
754 test_enable_assoc_change(tcp_clt_sk);
755
756 test_bind(udp_svr_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
757 test_bind(udp_clt_sk, &udp_clt_loop.sa, sizeof(udp_clt_loop));
758 test_bind(tcp_svr_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop));
759 test_bind(tcp_clt_sk, &tcp_clt_loop.sa, sizeof(tcp_clt_loop));
760
761 /* Mark udp_svr_sk and tcp_svr_sk as being able to accept new
762 * associations.
763 */
764 test_listen(udp_svr_sk, 5);
765 test_listen(tcp_svr_sk, 5);
766
767 /* Set default send parameters on the unconnected UDP-style sockets. */
768 memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
769 set_udp_sk_dflt_param.sinfo_ppid = 1000;
770 test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
771 &set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param));
772 memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
773 set_udp_sk_dflt_param.sinfo_ppid = 1000;
774 test_setsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
775 &set_udp_sk_dflt_param, sizeof(set_udp_sk_dflt_param));
776
777 tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
778 "one-to-many style socket");
779
780 /* Get default send parameters on the unconnected UDP-style socket. */
781 memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
782 optlen = sizeof(get_udp_sk_dflt_param);
783 test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
784 &get_udp_sk_dflt_param, &optlen);
785
786 /* Verify that the get param matches set param. */
787 if (set_udp_sk_dflt_param.sinfo_ppid !=
788 get_udp_sk_dflt_param.sinfo_ppid)
789 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
790 "mismatch.");
791
792 /* Get default send parameters on the unconnected UDP-style socket. */
793 memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
794 optlen = sizeof(get_udp_sk_dflt_param);
795 test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
796 &get_udp_sk_dflt_param, &optlen);
797
798 /* Verify that the get param matches set param. */
799 if (set_udp_sk_dflt_param.sinfo_ppid !=
800 get_udp_sk_dflt_param.sinfo_ppid)
801 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
802 "mismatch.");
803
804 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
805 "one-to-many style socket");
806
807 /* Verify that trying to set send params with an invalid assoc id
808 * on an UDP-style socket fails.
809 */
810 memset(&set_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
811 set_udp_sk_dflt_param.sinfo_ppid = 1000;
812 /* Invalid assoc id */
813 set_udp_sk_dflt_param.sinfo_assoc_id = 1234;
814 error = setsockopt(udp_clt_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM,
815 &set_udp_sk_dflt_param,
816 sizeof(set_udp_sk_dflt_param));
817 if ((-1 != error) || (EINVAL != errno))
818 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
819 "invalid associd error:%d, errno:%d\n",
820 error, errno);
821
822 tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
823 "- one-to-many style invalid associd");
824
825 /* Do a connect on a UDP-style socket and establish an association. */
826 test_connect(udp_clt_sk, &udp_svr_loop.sa, sizeof(udp_svr_loop));
827
828 /* Receive the COMM_UP notifications and get the associd's */
829 inmessage.msg_controllen = sizeof(incmsg);
830 error = test_recvmsg(udp_svr_sk, &inmessage, MSG_WAITALL);
831 test_check_msg_notification(&inmessage, error,
832 sizeof(struct sctp_assoc_change),
833 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
834 sac = (struct sctp_assoc_change *)iov.iov_base;
835 udp_svr_associd = sac->sac_assoc_id;
836
837 inmessage.msg_controllen = sizeof(incmsg);
838 error = test_recvmsg(udp_clt_sk, &inmessage, MSG_WAITALL);
839 test_check_msg_notification(&inmessage, error,
840 sizeof(struct sctp_assoc_change),
841 SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
842 sac = (struct sctp_assoc_change *)iov.iov_base;
843 udp_clt_associd = sac->sac_assoc_id;
844
845 /* Verify that trying to set send params with an assoc id not
846 * belonging to the socket on an UDP-style socket fails.
847 */
848 memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
849 set_udp_assoc_dflt_param.sinfo_ppid = 3000;
850 set_udp_assoc_dflt_param.sinfo_assoc_id = udp_clt_associd;
851 error = setsockopt(udp_svr_sk, SOL_SCTP, SCTP_DEFAULT_SEND_PARAM,
852 &set_udp_assoc_dflt_param,
853 sizeof(set_udp_assoc_dflt_param));
854 if ((-1 != error) || (EINVAL != errno))
855 tst_brkm(TBROK, tst_exit, "setsockopt(SCTP_DEFAULT_SEND_PARAM) "
856 "associd belonging to another socket "
857 "error:%d, errno:%d", error, errno);
858
859 tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
860 "one-to-many style associd belonging to another socket");
861
862 /* Set default send parameters of an association on the listening
863 * UDP-style socket with a valid associd.
864 */
865 memset(&set_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
866 set_udp_assoc_dflt_param.sinfo_ppid = 3000;
867 set_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd;
868 test_setsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
869 &set_udp_assoc_dflt_param,
870 sizeof(set_udp_assoc_dflt_param));
871
872 tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
873 "one-to-many style valid associd");
874
875 /* Get default send parameters of an association on the listening
876 * UDP-style socket with a valid associd.
877 */
878 memset(&get_udp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
879 get_udp_assoc_dflt_param.sinfo_assoc_id = udp_svr_associd ;
880 optlen = sizeof(get_udp_assoc_dflt_param);
881 test_getsockopt(udp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
882 &get_udp_assoc_dflt_param, &optlen);
883
884 /* Verify that the get param matches the set param. */
885 if (get_udp_assoc_dflt_param.sinfo_ppid !=
886 set_udp_assoc_dflt_param.sinfo_ppid)
887 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
888 "mismatch.");
889
890 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
891 "one-to-many style valid associd");
892
893 /* Get default send parameters of an association on the connected
894 * UDP-style socket with zero associd. This should return the
895 * socket wide default parameters.
896 */
897 memset(&get_udp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
898 get_udp_sk_dflt_param.sinfo_assoc_id = 0 ;
899 optlen = sizeof(get_udp_sk_dflt_param);
900 test_getsockopt(udp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
901 &get_udp_sk_dflt_param, &optlen);
902
903 /* Verify that the get param matches the socket-wide set param. */
904 if (get_udp_sk_dflt_param.sinfo_ppid !=
905 set_udp_sk_dflt_param.sinfo_ppid)
906 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
907 "mismatch.");
908
909 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
910 "one-to-many style zero associd");
911
912 peeloff_sk = test_sctp_peeloff(udp_svr_sk, udp_svr_associd);
913
914 /* Get default send parameters of an association on the peeled off
915 * UDP-style socket. This should return the association's default
916 * parameters.
917 */
918 memset(&get_peeloff_assoc_dflt_param, 0,
919 sizeof(struct sctp_sndrcvinfo));
920 get_peeloff_assoc_dflt_param.sinfo_assoc_id = 0 ;
921 optlen = sizeof(get_peeloff_assoc_dflt_param);
922 test_getsockopt(peeloff_sk, SCTP_DEFAULT_SEND_PARAM,
923 &get_peeloff_assoc_dflt_param, &optlen);
924
925 /* Verify that the get param matches the association's set param. */
926 if (get_peeloff_assoc_dflt_param.sinfo_ppid !=
927 set_udp_assoc_dflt_param.sinfo_ppid)
928 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
929 "mismatch.");
930
931 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
932 "one-to-many style peeled off socket");
933
934 /* Set default send parameters on the unconnected TCP-style sockets. */
935 memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
936 set_tcp_sk_dflt_param.sinfo_ppid = 2000;
937 /* Invalid assoc id, ignored on a TCP-style socket. */
938 set_tcp_sk_dflt_param.sinfo_assoc_id = 1234;
939 test_setsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
940 &set_tcp_sk_dflt_param,
941 sizeof(set_tcp_sk_dflt_param));
942
943 /* Set default send parameters on the unconnected TCP-style sockets. */
944 memset(&set_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
945 set_tcp_sk_dflt_param.sinfo_ppid = 2000;
946 /* Invalid assoc id, ignored on a TCP-style socket. */
947 set_tcp_sk_dflt_param.sinfo_assoc_id = 1234;
948 test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
949 &set_tcp_sk_dflt_param,
950 sizeof(set_tcp_sk_dflt_param));
951
952 tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
953 "one-to-one style socket");
954
955 /* Get default send parameters on the unconnected TCP-style socket. */
956 memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
957 optlen = sizeof(get_tcp_sk_dflt_param);
958 test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
959 &get_tcp_sk_dflt_param, &optlen);
960
961 /* Verify that the get param matches set param. */
962 if (set_tcp_sk_dflt_param.sinfo_ppid !=
963 get_tcp_sk_dflt_param.sinfo_ppid)
964 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
965 "mismatch.");
966
967 /* Get default send parameters on the unconnected TCP-style socket. */
968 memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
969 optlen = sizeof(get_tcp_sk_dflt_param);
970 test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
971 &get_tcp_sk_dflt_param, &optlen);
972
973 /* Verify that the get param matches set param. */
974 if (set_tcp_sk_dflt_param.sinfo_ppid !=
975 get_tcp_sk_dflt_param.sinfo_ppid)
976 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
977 "mismatch.");
978
979 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
980 "one-to-one style socket");
981
982 /* Do a connect on a TCP-style socket and establish an association. */
983 test_connect(tcp_clt_sk, &tcp_svr_loop.sa, sizeof(tcp_svr_loop));
984
985 /* Set default send parameters of an association on the connected
986 * TCP-style socket.
987 */
988 memset(&set_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
989 set_tcp_assoc_dflt_param.sinfo_ppid = 4000;
990 set_tcp_assoc_dflt_param.sinfo_assoc_id = 0;
991 test_setsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
992 &set_tcp_assoc_dflt_param,
993 sizeof(set_tcp_assoc_dflt_param));
994
995 tst_resm(TPASS, "setsockopt(SCTP_DEFAULT_SEND_PARAM) - "
996 "one-to-one style assoc");
997
998 /* Get default send parameters of an association on the connected
999 * TCP-style socket.
1000 */
1001 memset(&get_tcp_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
1002 optlen = sizeof(get_tcp_assoc_dflt_param);
1003 test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
1004 &get_tcp_assoc_dflt_param, &optlen);
1005
1006 if (set_tcp_assoc_dflt_param.sinfo_ppid !=
1007 get_tcp_assoc_dflt_param.sinfo_ppid)
1008 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
1009 "mismatch.");
1010
1011 /* Get default send parameters on the connected TCP-style socket. */
1012 memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
1013 optlen = sizeof(get_tcp_sk_dflt_param);
1014 test_getsockopt(tcp_clt_sk, SCTP_DEFAULT_SEND_PARAM,
1015 &get_tcp_sk_dflt_param, &optlen);
1016
1017 /* Verify that the get parameters returned matches the set param
1018 * set for the association, not the socket-wide param.
1019 */
1020 if ((get_tcp_sk_dflt_param.sinfo_ppid ==
1021 set_tcp_sk_dflt_param.sinfo_ppid) ||
1022 (get_tcp_sk_dflt_param.sinfo_ppid !=
1023 set_tcp_assoc_dflt_param.sinfo_ppid))
1024 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
1025 "mismatch.");
1026
1027 /* Get default send parameters on the listening TCP-style socket. */
1028 memset(&get_tcp_sk_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
1029 optlen = sizeof(get_tcp_sk_dflt_param);
1030 test_getsockopt(tcp_svr_sk, SCTP_DEFAULT_SEND_PARAM,
1031 &get_tcp_sk_dflt_param, &optlen);
1032
1033 /* Verify that the get parameters returned matches the socket-wide
1034 * set param.
1035 */
1036 if (get_tcp_sk_dflt_param.sinfo_ppid !=
1037 set_tcp_sk_dflt_param.sinfo_ppid)
1038 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
1039 "mismatch.");
1040
1041 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
1042 "one-to-one style assoc");
1043
1044 accept_sk = test_accept(tcp_svr_sk, NULL, &addrlen);
1045
1046 /* Get default send parameters of an association on the accepted
1047 * TCP-style socket.
1048 */
1049 memset(&get_accept_assoc_dflt_param, 0, sizeof(struct sctp_sndrcvinfo));
1050 optlen = sizeof(get_accept_assoc_dflt_param);
1051 test_getsockopt(accept_sk, SCTP_DEFAULT_SEND_PARAM,
1052 &get_accept_assoc_dflt_param, &optlen);
1053
1054 error = 0;
1055
1056 /* Verify that the get parameters returned matches the socket-wide
1057 * set param.
1058 */
1059 if (get_tcp_sk_dflt_param.sinfo_ppid !=
1060 set_tcp_sk_dflt_param.sinfo_ppid)
1061 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_DEFAULT_SEND_PARAM) "
1062 "mismatch.");
1063
1064 tst_resm(TPASS, "getsockopt(SCTP_DEFAULT_SEND_PARAM) - "
1065 "one-to-one style accepted socket");
1066
1067 /* TEST #7: SCTP_GET_PEER_ADDR_INFO socket option. */
1068 /* Try 0 associd and 0 addr */
1069 memset(&pinfo, 0, sizeof(pinfo));
1070 optlen = sizeof(pinfo);
1071 error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
1072 &pinfo, &optlen);
1073 if ((-1 != error) || (EINVAL != errno))
1074 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
1075 "null associd, null addr error:%d, errno:%d\n",
1076 error, errno);
1077
1078 tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
1079 "null associd and null addr");
1080
1081 /* Try valid associd, but 0 addr */
1082 memset(&pinfo, 0, sizeof(pinfo));
1083 optlen = sizeof(pinfo);
1084 pinfo.spinfo_assoc_id = udp_clt_associd;
1085 error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
1086 &pinfo, &optlen);
1087 if ((-1 != error) || (EINVAL != errno))
1088 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
1089 "valid associd, null addr error:%d, errno:%d\n",
1090 error, errno);
1091
1092 tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
1093 "valid associd and null addr");
1094
1095 /* Try valid associd, invalid addr */
1096 memset(&pinfo, 0, sizeof(pinfo));
1097 optlen = sizeof(pinfo);
1098 pinfo.spinfo_assoc_id = udp_clt_associd;
1099 memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop));
1100 error = getsockopt(udp_clt_sk, SOL_SCTP, SCTP_GET_PEER_ADDR_INFO,
1101 &pinfo, &optlen);
1102 if ((-1 != error) || (EINVAL != errno))
1103 tst_brkm(TBROK, tst_exit, "getsockopt(SCTP_GET_PEER_ADDR_INFO) "
1104 "valid associd, invalid addr error:%d, errno:%d\n",
1105 error, errno);
1106
1107 tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
1108 "valid associd and invalid addr");
1109
1110 /* Try valid associd, valid addr */
1111 memset(&pinfo, 0, sizeof(pinfo));
1112 optlen = sizeof(pinfo);
1113 pinfo.spinfo_assoc_id = udp_clt_associd;
1114 memcpy(&pinfo.spinfo_address, &udp_svr_loop, sizeof(udp_svr_loop));
1115 test_getsockopt(udp_clt_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen);
1116
1117 tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
1118 "valid associd and valid addr");
1119
1120 /* Try valid addr, peeled off socket */
1121 memset(&pinfo, 0, sizeof(pinfo));
1122 optlen = sizeof(pinfo);
1123 pinfo.spinfo_assoc_id = 0;
1124 memcpy(&pinfo.spinfo_address, &udp_clt_loop, sizeof(udp_clt_loop));
1125 test_getsockopt(peeloff_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo, &optlen);
1126
1127 tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
1128 "valid associd and valid addr peeled off socket");
1129
1130 /* Try valid addr, TCP-style accept socket */
1131 memset(&pinfo, 0, sizeof(pinfo));
1132 optlen = sizeof(pinfo);
1133 pinfo.spinfo_assoc_id = 0;
1134 memcpy(&pinfo.spinfo_address, &tcp_clt_loop, sizeof(tcp_clt_loop));
1135 error = test_getsockopt(accept_sk, SCTP_GET_PEER_ADDR_INFO, &pinfo,
1136 &optlen);
1137
1138 tst_resm(TPASS, "getsockopt(SCTP_GET_PEER_ADDR_INFO) - "
1139 "valid associd and valid addr accepted socket");
1140
1141 close(udp_svr_sk);
1142 close(udp_clt_sk);
1143 close(tcp_svr_sk);
1144 close(tcp_clt_sk);
1145 close(accept_sk);
1146 close(peeloff_sk);
1147
1148 /* Indicate successful completion. */
1149 return 0;
1150 }
1151