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
61char *TCID = __FILE__;
62int TST_TOTAL = 29;
63int TST_CNT = 0;
64
65int
66main(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