1f08c3bdfSopenharmony_ci/* SCTP kernel Implementation
2f08c3bdfSopenharmony_ci * (C) Copyright IBM Corp. 2001, 2003
3f08c3bdfSopenharmony_ci * Copyright (c) 1999-2000 Cisco, Inc.
4f08c3bdfSopenharmony_ci * Copyright (c) 1999-2001 Motorola, Inc.
5f08c3bdfSopenharmony_ci * Copyright (c) 2001 Intel Corp.
6f08c3bdfSopenharmony_ci * Copyright (c) 2001 Nokia, Inc.
7f08c3bdfSopenharmony_ci *
8f08c3bdfSopenharmony_ci * The SCTP implementation is free software;
9f08c3bdfSopenharmony_ci * you can redistribute it and/or modify it under the terms of
10f08c3bdfSopenharmony_ci * the GNU General Public License as published by
11f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2, or (at your option)
12f08c3bdfSopenharmony_ci * any later version.
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * The SCTP implementation is distributed in the hope that it
15f08c3bdfSopenharmony_ci * will be useful, but WITHOUT ANY WARRANTY; without even the implied
16f08c3bdfSopenharmony_ci *                 ************************
17f08c3bdfSopenharmony_ci * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18f08c3bdfSopenharmony_ci * See the GNU General Public License for more details.
19f08c3bdfSopenharmony_ci *
20f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License
21f08c3bdfSopenharmony_ci * along with GNU CC; see the file COPYING.  If not, write to
22f08c3bdfSopenharmony_ci * the Free Software Foundation, 59 Temple Place - Suite 330,
23f08c3bdfSopenharmony_ci * Boston, MA 02111-1307, USA.
24f08c3bdfSopenharmony_ci *
25f08c3bdfSopenharmony_ci * Please send any bug reports or fixes you make to the
26f08c3bdfSopenharmony_ci * email address(es):
27f08c3bdfSopenharmony_ci *    lksctp developers <lksctp-developers@lists.sourceforge.net>
28f08c3bdfSopenharmony_ci *
29f08c3bdfSopenharmony_ci * Or submit a bug report through the following website:
30f08c3bdfSopenharmony_ci *    http://www.sf.net/projects/lksctp
31f08c3bdfSopenharmony_ci *
32f08c3bdfSopenharmony_ci * Any bugs reported to us we will try to fix... any fixes shared will
33f08c3bdfSopenharmony_ci * be incorporated into the next SCTP release.
34f08c3bdfSopenharmony_ci *
35f08c3bdfSopenharmony_ci * Written or modified by:
36f08c3bdfSopenharmony_ci *    La Monte H.P. Yarroll <piggy@acm.org>
37f08c3bdfSopenharmony_ci *    Karl Knutson <karl@athena.chicago.il.us>
38f08c3bdfSopenharmony_ci *    Hui Huang <hui.huang@nokia.com>
39f08c3bdfSopenharmony_ci *    Jon Grimm <jgrimm@us.ibm.com>
40f08c3bdfSopenharmony_ci *    Sridhar Samudrala <samudrala@us.ibm.com>
41f08c3bdfSopenharmony_ci */
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_ci/* This is a basic functional test for the SCTP kernel
44f08c3bdfSopenharmony_ci * implementation state machine.
45f08c3bdfSopenharmony_ci */
46f08c3bdfSopenharmony_ci
47f08c3bdfSopenharmony_ci#include <stdio.h>
48f08c3bdfSopenharmony_ci#include <unistd.h>
49f08c3bdfSopenharmony_ci#include <stdlib.h>
50f08c3bdfSopenharmony_ci#include <string.h>
51f08c3bdfSopenharmony_ci#include <sys/types.h>
52f08c3bdfSopenharmony_ci#include <sys/socket.h>
53f08c3bdfSopenharmony_ci#include <sys/uio.h>
54f08c3bdfSopenharmony_ci#include <netinet/in.h>
55f08c3bdfSopenharmony_ci#include <sys/errno.h>
56f08c3bdfSopenharmony_ci#include <errno.h>
57f08c3bdfSopenharmony_ci#include <netinet/sctp.h>
58f08c3bdfSopenharmony_ci#include <sctputil.h>
59f08c3bdfSopenharmony_ci#include "tst_kernel.h"
60f08c3bdfSopenharmony_ci
61f08c3bdfSopenharmony_cichar *TCID = __FILE__;
62f08c3bdfSopenharmony_ciint TST_TOTAL = 15;
63f08c3bdfSopenharmony_ciint TST_CNT = 0;
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ciint main(void)
66f08c3bdfSopenharmony_ci{
67f08c3bdfSopenharmony_ci        int sk1, sk2;
68f08c3bdfSopenharmony_ci        sockaddr_storage_t loop1;
69f08c3bdfSopenharmony_ci        sockaddr_storage_t loop2;
70f08c3bdfSopenharmony_ci	sockaddr_storage_t msgname;
71f08c3bdfSopenharmony_ci        struct iovec iov;
72f08c3bdfSopenharmony_ci        struct msghdr inmessage;
73f08c3bdfSopenharmony_ci	struct msghdr outmessage;
74f08c3bdfSopenharmony_ci	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
75f08c3bdfSopenharmony_ci	char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
76f08c3bdfSopenharmony_ci	struct cmsghdr *cmsg;
77f08c3bdfSopenharmony_ci	struct sctp_sndrcvinfo *sinfo;
78f08c3bdfSopenharmony_ci        struct iovec out_iov;
79f08c3bdfSopenharmony_ci        char *message = "hello, world!\n";
80f08c3bdfSopenharmony_ci        char *telephone = "Watson, come here!  I need you!\n";
81f08c3bdfSopenharmony_ci        char *telephone_resp = "I already brought your coffee...\n";
82f08c3bdfSopenharmony_ci        int error, bytes_sent;
83f08c3bdfSopenharmony_ci	int pf_class;
84f08c3bdfSopenharmony_ci	uint32_t ppid;
85f08c3bdfSopenharmony_ci	uint32_t stream;
86f08c3bdfSopenharmony_ci	sctp_assoc_t associd1, associd2;
87f08c3bdfSopenharmony_ci	struct sctp_assoc_change *sac;
88f08c3bdfSopenharmony_ci	char *big_buffer;
89f08c3bdfSopenharmony_ci	struct sockaddr *laddrs, *paddrs;
90f08c3bdfSopenharmony_ci	int n_laddrs, n_paddrs, i;
91f08c3bdfSopenharmony_ci	struct sockaddr *sa_addr;
92f08c3bdfSopenharmony_ci	struct sockaddr_in *in_addr;
93f08c3bdfSopenharmony_ci	struct sockaddr_in6 *in6_addr;
94f08c3bdfSopenharmony_ci	void *addr_buf;
95f08c3bdfSopenharmony_ci
96f08c3bdfSopenharmony_ci	if (tst_check_driver("sctp"))
97f08c3bdfSopenharmony_ci		tst_brkm(TCONF, tst_exit, "sctp driver not available");
98f08c3bdfSopenharmony_ci
99f08c3bdfSopenharmony_ci        /* Rather than fflush() throughout the code, set stdout to
100f08c3bdfSopenharmony_ci	 * be unbuffered.
101f08c3bdfSopenharmony_ci	 */
102f08c3bdfSopenharmony_ci	setvbuf(stdout, NULL, _IONBF, 0);
103f08c3bdfSopenharmony_ci
104f08c3bdfSopenharmony_ci	/* Set some basic values which depend on the address family. */
105f08c3bdfSopenharmony_ci#if TEST_V6
106f08c3bdfSopenharmony_ci	pf_class = PF_INET6;
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_ci        loop1.v6.sin6_family = AF_INET6;
109f08c3bdfSopenharmony_ci        loop1.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT;
110f08c3bdfSopenharmony_ci        loop1.v6.sin6_port = htons(SCTP_TESTPORT_1);
111f08c3bdfSopenharmony_ci
112f08c3bdfSopenharmony_ci        loop2.v6.sin6_family = AF_INET6;
113f08c3bdfSopenharmony_ci        loop2.v6.sin6_addr = in6addr_loopback;
114f08c3bdfSopenharmony_ci        loop2.v6.sin6_port = htons(SCTP_TESTPORT_2);
115f08c3bdfSopenharmony_ci#else
116f08c3bdfSopenharmony_ci	pf_class = PF_INET;
117f08c3bdfSopenharmony_ci
118f08c3bdfSopenharmony_ci        loop1.v4.sin_family = AF_INET;
119f08c3bdfSopenharmony_ci        loop1.v4.sin_addr.s_addr = INADDR_ANY;
120f08c3bdfSopenharmony_ci        loop1.v4.sin_port = htons(SCTP_TESTPORT_1);
121f08c3bdfSopenharmony_ci
122f08c3bdfSopenharmony_ci        loop2.v4.sin_family = AF_INET;
123f08c3bdfSopenharmony_ci        loop2.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK;
124f08c3bdfSopenharmony_ci        loop2.v4.sin_port = htons(SCTP_TESTPORT_2);
125f08c3bdfSopenharmony_ci#endif /* TEST_V6 */
126f08c3bdfSopenharmony_ci
127f08c3bdfSopenharmony_ci        /* Create the two endpoints which will talk to each other.  */
128f08c3bdfSopenharmony_ci        sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
129f08c3bdfSopenharmony_ci        sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP);
130f08c3bdfSopenharmony_ci
131f08c3bdfSopenharmony_ci	tst_resm(TPASS, "socket");
132f08c3bdfSopenharmony_ci
133f08c3bdfSopenharmony_ci        /* Bind these sockets to the test ports.  */
134f08c3bdfSopenharmony_ci        test_bind(sk1, &loop1.sa, sizeof(loop1));
135f08c3bdfSopenharmony_ci        test_bind(sk2, &loop2.sa, sizeof(loop2));
136f08c3bdfSopenharmony_ci
137f08c3bdfSopenharmony_ci	tst_resm(TPASS, "bind");
138f08c3bdfSopenharmony_ci
139f08c3bdfSopenharmony_ci	/* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */
140f08c3bdfSopenharmony_ci	test_enable_assoc_change(sk1);
141f08c3bdfSopenharmony_ci	test_enable_assoc_change(sk2);
142f08c3bdfSopenharmony_ci
143f08c3bdfSopenharmony_ci        /* Initialize inmessage for all receives. */
144f08c3bdfSopenharmony_ci	big_buffer = test_malloc(REALLY_BIG);
145f08c3bdfSopenharmony_ci	memset(&inmessage, 0, sizeof(inmessage));
146f08c3bdfSopenharmony_ci        iov.iov_base = big_buffer;
147f08c3bdfSopenharmony_ci        iov.iov_len = REALLY_BIG;
148f08c3bdfSopenharmony_ci        inmessage.msg_iov = &iov;
149f08c3bdfSopenharmony_ci        inmessage.msg_iovlen = 1;
150f08c3bdfSopenharmony_ci        inmessage.msg_control = incmsg;
151f08c3bdfSopenharmony_ci	inmessage.msg_name = &msgname;
152f08c3bdfSopenharmony_ci
153f08c3bdfSopenharmony_ci        /* Try to read on socket 2.  This should fail since we are
154f08c3bdfSopenharmony_ci	 * neither listening, nor established.
155f08c3bdfSopenharmony_ci	 */
156f08c3bdfSopenharmony_ci        inmessage.msg_controllen = sizeof(incmsg);
157f08c3bdfSopenharmony_ci        error = recvmsg(sk2, &inmessage, MSG_WAITALL);
158f08c3bdfSopenharmony_ci        if (error > 0)
159f08c3bdfSopenharmony_ci                tst_brkm(TBROK, tst_exit, "recvmsg on a socket neither "
160f08c3bdfSopenharmony_ci			 "listening nor established error: %d", error);
161f08c3bdfSopenharmony_ci
162f08c3bdfSopenharmony_ci	tst_resm(TPASS, "recvmsg on a socket neither listening nor "
163f08c3bdfSopenharmony_ci		 "established");
164f08c3bdfSopenharmony_ci
165f08c3bdfSopenharmony_ci       /* Mark sk2 as being able to accept new associations.  */
166f08c3bdfSopenharmony_ci	error = test_listen(sk2, 1);
167f08c3bdfSopenharmony_ci
168f08c3bdfSopenharmony_ci	tst_resm(TPASS, "listen");
169f08c3bdfSopenharmony_ci
170f08c3bdfSopenharmony_ci        /* Send the first message.  This will create the association.  */
171f08c3bdfSopenharmony_ci        outmessage.msg_name = &loop2;
172f08c3bdfSopenharmony_ci        outmessage.msg_namelen = sizeof(loop2);
173f08c3bdfSopenharmony_ci        outmessage.msg_iov = &out_iov;
174f08c3bdfSopenharmony_ci        outmessage.msg_iovlen = 1;
175f08c3bdfSopenharmony_ci        outmessage.msg_control = outcmsg;
176f08c3bdfSopenharmony_ci        outmessage.msg_controllen = sizeof(outcmsg);
177f08c3bdfSopenharmony_ci        outmessage.msg_flags = 0;
178f08c3bdfSopenharmony_ci	cmsg = CMSG_FIRSTHDR(&outmessage);
179f08c3bdfSopenharmony_ci	cmsg->cmsg_level = IPPROTO_SCTP;
180f08c3bdfSopenharmony_ci	cmsg->cmsg_type = SCTP_SNDRCV;
181f08c3bdfSopenharmony_ci	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
182f08c3bdfSopenharmony_ci	outmessage.msg_controllen = cmsg->cmsg_len;
183f08c3bdfSopenharmony_ci	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
184f08c3bdfSopenharmony_ci	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
185f08c3bdfSopenharmony_ci	ppid = rand(); /* Choose an arbitrary value. */
186f08c3bdfSopenharmony_ci	stream = 1;
187f08c3bdfSopenharmony_ci	sinfo->sinfo_ppid = ppid;
188f08c3bdfSopenharmony_ci	sinfo->sinfo_stream = stream;
189f08c3bdfSopenharmony_ci        outmessage.msg_iov->iov_base = message;
190f08c3bdfSopenharmony_ci        outmessage.msg_iov->iov_len = strlen(message) + 1;
191f08c3bdfSopenharmony_ci        test_sendmsg(sk1, &outmessage, 0, strlen(message)+1);
192f08c3bdfSopenharmony_ci
193f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sendmsg with a valid msg_name");
194f08c3bdfSopenharmony_ci
195f08c3bdfSopenharmony_ci        /* Get the communication up message on sk2.  */
196f08c3bdfSopenharmony_ci        inmessage.msg_controllen = sizeof(incmsg);
197f08c3bdfSopenharmony_ci	inmessage.msg_namelen = sizeof(msgname);
198f08c3bdfSopenharmony_ci        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
199f08c3bdfSopenharmony_ci	test_check_msg_notification(&inmessage, error,
200f08c3bdfSopenharmony_ci				    sizeof(struct sctp_assoc_change),
201f08c3bdfSopenharmony_ci				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
202f08c3bdfSopenharmony_ci#if TEST_V6
203f08c3bdfSopenharmony_ci
204f08c3bdfSopenharmony_ci	if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
205f08c3bdfSopenharmony_ci		DUMP_CORE;
206f08c3bdfSopenharmony_ci	}
207f08c3bdfSopenharmony_ci	if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
208f08c3bdfSopenharmony_ci		DUMP_CORE;
209f08c3bdfSopenharmony_ci	}
210f08c3bdfSopenharmony_ci
211f08c3bdfSopenharmony_ci	if (msgname.v6.sin6_family != AF_INET6) {
212f08c3bdfSopenharmony_ci		DUMP_CORE;
213f08c3bdfSopenharmony_ci	}
214f08c3bdfSopenharmony_ci
215f08c3bdfSopenharmony_ci	if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback,
216f08c3bdfSopenharmony_ci		   sizeof(msgname.v6.sin6_addr))) {
217f08c3bdfSopenharmony_ci		DUMP_CORE;
218f08c3bdfSopenharmony_ci	}
219f08c3bdfSopenharmony_ci#else
220f08c3bdfSopenharmony_ci	if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
221f08c3bdfSopenharmony_ci		DUMP_CORE;
222f08c3bdfSopenharmony_ci	}
223f08c3bdfSopenharmony_ci	if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
224f08c3bdfSopenharmony_ci		DUMP_CORE;
225f08c3bdfSopenharmony_ci	}
226f08c3bdfSopenharmony_ci
227f08c3bdfSopenharmony_ci	if (msgname.v4.sin_family != AF_INET) {
228f08c3bdfSopenharmony_ci		DUMP_CORE;
229f08c3bdfSopenharmony_ci	}
230f08c3bdfSopenharmony_ci	if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
231f08c3bdfSopenharmony_ci		DUMP_CORE;
232f08c3bdfSopenharmony_ci	}
233f08c3bdfSopenharmony_ci#endif
234f08c3bdfSopenharmony_ci	sac = (struct sctp_assoc_change *)iov.iov_base;
235f08c3bdfSopenharmony_ci	associd2 = sac->sac_assoc_id;
236f08c3bdfSopenharmony_ci
237f08c3bdfSopenharmony_ci        /* Get the communication up message on sk1.  */
238f08c3bdfSopenharmony_ci	iov.iov_base = big_buffer;
239f08c3bdfSopenharmony_ci        iov.iov_len = REALLY_BIG;
240f08c3bdfSopenharmony_ci        inmessage.msg_control = incmsg;
241f08c3bdfSopenharmony_ci        inmessage.msg_controllen = sizeof(incmsg);
242f08c3bdfSopenharmony_ci        error = test_recvmsg(sk1, &inmessage, MSG_WAITALL);
243f08c3bdfSopenharmony_ci	test_check_msg_notification(&inmessage, error,
244f08c3bdfSopenharmony_ci				    sizeof(struct sctp_assoc_change),
245f08c3bdfSopenharmony_ci				    SCTP_ASSOC_CHANGE, SCTP_COMM_UP);
246f08c3bdfSopenharmony_ci	sac = (struct sctp_assoc_change *)iov.iov_base;
247f08c3bdfSopenharmony_ci	associd1 = sac->sac_assoc_id;
248f08c3bdfSopenharmony_ci
249f08c3bdfSopenharmony_ci	tst_resm(TPASS, "recvmsg COMM_UP notifications");
250f08c3bdfSopenharmony_ci
251f08c3bdfSopenharmony_ci        /* Get the first message which was sent.  */
252f08c3bdfSopenharmony_ci        inmessage.msg_controllen = sizeof(incmsg);
253f08c3bdfSopenharmony_ci	inmessage.msg_namelen = sizeof(msgname);
254f08c3bdfSopenharmony_ci	memset(&msgname, 0, sizeof(msgname));
255f08c3bdfSopenharmony_ci        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
256f08c3bdfSopenharmony_ci        test_check_msg_data(&inmessage, error, strlen(message) + 1,
257f08c3bdfSopenharmony_ci			    MSG_EOR, stream, ppid);
258f08c3bdfSopenharmony_ci#if TEST_V6
259f08c3bdfSopenharmony_ci
260f08c3bdfSopenharmony_ci	if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
261f08c3bdfSopenharmony_ci		DUMP_CORE;
262f08c3bdfSopenharmony_ci	}
263f08c3bdfSopenharmony_ci	if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
264f08c3bdfSopenharmony_ci		DUMP_CORE;
265f08c3bdfSopenharmony_ci	}
266f08c3bdfSopenharmony_ci
267f08c3bdfSopenharmony_ci	if (msgname.v6.sin6_family != AF_INET6) {
268f08c3bdfSopenharmony_ci		DUMP_CORE;
269f08c3bdfSopenharmony_ci	}
270f08c3bdfSopenharmony_ci
271f08c3bdfSopenharmony_ci	if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback,
272f08c3bdfSopenharmony_ci		   sizeof(msgname.v6.sin6_addr))) {
273f08c3bdfSopenharmony_ci		DUMP_CORE;
274f08c3bdfSopenharmony_ci	}
275f08c3bdfSopenharmony_ci#else
276f08c3bdfSopenharmony_ci	if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
277f08c3bdfSopenharmony_ci		DUMP_CORE;
278f08c3bdfSopenharmony_ci	}
279f08c3bdfSopenharmony_ci	if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
280f08c3bdfSopenharmony_ci		DUMP_CORE;
281f08c3bdfSopenharmony_ci	}
282f08c3bdfSopenharmony_ci	if (msgname.v4.sin_family != AF_INET) {
283f08c3bdfSopenharmony_ci		DUMP_CORE;
284f08c3bdfSopenharmony_ci	}
285f08c3bdfSopenharmony_ci	if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
286f08c3bdfSopenharmony_ci		DUMP_CORE;
287f08c3bdfSopenharmony_ci	}
288f08c3bdfSopenharmony_ci#endif
289f08c3bdfSopenharmony_ci
290f08c3bdfSopenharmony_ci	/* Try to send a message with NULL msg_name and associd, should fail */
291f08c3bdfSopenharmony_ci        outmessage.msg_controllen = sizeof(outcmsg);
292f08c3bdfSopenharmony_ci        outmessage.msg_flags = 0;
293f08c3bdfSopenharmony_ci	cmsg = CMSG_FIRSTHDR(&outmessage);
294f08c3bdfSopenharmony_ci	cmsg->cmsg_level = IPPROTO_SCTP;
295f08c3bdfSopenharmony_ci	cmsg->cmsg_type = SCTP_SNDRCV;
296f08c3bdfSopenharmony_ci	cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
297f08c3bdfSopenharmony_ci	outmessage.msg_controllen = cmsg->cmsg_len;
298f08c3bdfSopenharmony_ci	sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
299f08c3bdfSopenharmony_ci	memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));
300f08c3bdfSopenharmony_ci	ppid++;
301f08c3bdfSopenharmony_ci	stream++;
302f08c3bdfSopenharmony_ci	sinfo->sinfo_ppid = ppid;
303f08c3bdfSopenharmony_ci	sinfo->sinfo_stream = stream;
304f08c3bdfSopenharmony_ci	outmessage.msg_iov->iov_base = telephone;
305f08c3bdfSopenharmony_ci        outmessage.msg_iov->iov_len = strlen(telephone) + 1;
306f08c3bdfSopenharmony_ci	outmessage.msg_name = NULL;
307f08c3bdfSopenharmony_ci	outmessage.msg_namelen = 0;
308f08c3bdfSopenharmony_ci	bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL);
309f08c3bdfSopenharmony_ci	if ((bytes_sent > 0) || (EPIPE != errno))
310f08c3bdfSopenharmony_ci		tst_brkm(TBROK, tst_exit, "sendmsg with NULL associd and "
311f08c3bdfSopenharmony_ci			 "NULL msg_name error:%d errno:%d", error, errno);
312f08c3bdfSopenharmony_ci
313f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sendmsg with NULL associd and NULL msg_name");
314f08c3bdfSopenharmony_ci
315f08c3bdfSopenharmony_ci	/* Fill in a incorrect assoc_id, which should cause an error. */
316f08c3bdfSopenharmony_ci	sinfo->sinfo_assoc_id = associd2;
317f08c3bdfSopenharmony_ci	bytes_sent = sendmsg(sk1, &outmessage, MSG_NOSIGNAL);
318f08c3bdfSopenharmony_ci	if ((bytes_sent > 0) || (EPIPE != errno))
319f08c3bdfSopenharmony_ci		tst_brkm(TBROK, tst_exit, "sendmsg with incorrect associd "
320f08c3bdfSopenharmony_ci			 "error:%d errno:%d", error, errno);
321f08c3bdfSopenharmony_ci
322f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sendmsg with incorrect associd");
323f08c3bdfSopenharmony_ci
324f08c3bdfSopenharmony_ci	/* Fill in a correct assoc_id and get back to the normal testing. */
325f08c3bdfSopenharmony_ci	sinfo->sinfo_assoc_id = associd1;
326f08c3bdfSopenharmony_ci        /* Send two more messages, to cause a second SACK.  */
327f08c3bdfSopenharmony_ci	test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1);
328f08c3bdfSopenharmony_ci
329f08c3bdfSopenharmony_ci	outmessage.msg_name = &loop2;
330f08c3bdfSopenharmony_ci	outmessage.msg_namelen = sizeof(loop2);
331f08c3bdfSopenharmony_ci	outmessage.msg_iov->iov_base = telephone_resp;
332f08c3bdfSopenharmony_ci        outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1;
333f08c3bdfSopenharmony_ci	test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1);
334f08c3bdfSopenharmony_ci
335f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sendmsg with valid associd");
336f08c3bdfSopenharmony_ci
337f08c3bdfSopenharmony_ci        /* Get those two messages.  */
338f08c3bdfSopenharmony_ci	inmessage.msg_controllen = sizeof(incmsg);
339f08c3bdfSopenharmony_ci        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
340f08c3bdfSopenharmony_ci        test_check_msg_data(&inmessage, error, strlen(telephone) + 1,
341f08c3bdfSopenharmony_ci			    MSG_EOR, stream, ppid);
342f08c3bdfSopenharmony_ci
343f08c3bdfSopenharmony_ci	inmessage.msg_controllen = sizeof(incmsg);
344f08c3bdfSopenharmony_ci        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
345f08c3bdfSopenharmony_ci        test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1,
346f08c3bdfSopenharmony_ci			    MSG_EOR, stream, ppid);
347f08c3bdfSopenharmony_ci
348f08c3bdfSopenharmony_ci	tst_resm(TPASS, "recvmsg");
349f08c3bdfSopenharmony_ci
350f08c3bdfSopenharmony_ci	n_laddrs = sctp_getladdrs(sk1, associd1, &laddrs);
351f08c3bdfSopenharmony_ci	if (n_laddrs <= 0)
352f08c3bdfSopenharmony_ci                tst_brkm(TBROK, tst_exit, "sctp_getladdrs: %s",
353f08c3bdfSopenharmony_ci			 strerror(errno));
354f08c3bdfSopenharmony_ci
355f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sctp_getladdrs");
356f08c3bdfSopenharmony_ci
357f08c3bdfSopenharmony_ci	addr_buf = (void *)laddrs;
358f08c3bdfSopenharmony_ci	for (i = 0; i < n_laddrs; i++) {
359f08c3bdfSopenharmony_ci		sa_addr = (struct sockaddr *)addr_buf;
360f08c3bdfSopenharmony_ci		if (AF_INET == sa_addr->sa_family) {
361f08c3bdfSopenharmony_ci			in_addr = (struct sockaddr_in *)sa_addr;
362f08c3bdfSopenharmony_ci			tst_resm(TINFO, "LOCAL ADDR %d.%d.%d.%d PORT %d",
363f08c3bdfSopenharmony_ci				 NIPQUAD(in_addr->sin_addr),
364f08c3bdfSopenharmony_ci				 ntohs(in_addr->sin_port));
365f08c3bdfSopenharmony_ci			addr_buf += sizeof(struct sockaddr_in);
366f08c3bdfSopenharmony_ci		} else {
367f08c3bdfSopenharmony_ci			in6_addr = (struct sockaddr_in6 *)sa_addr;
368f08c3bdfSopenharmony_ci			tst_resm(TINFO,
369f08c3bdfSopenharmony_ci		 "LOCAL ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d",
370f08c3bdfSopenharmony_ci			       NIP6(in6_addr->sin6_addr),
371f08c3bdfSopenharmony_ci			       ntohs(in6_addr->sin6_port));
372f08c3bdfSopenharmony_ci			addr_buf += sizeof(struct sockaddr_in6);
373f08c3bdfSopenharmony_ci		}
374f08c3bdfSopenharmony_ci	}
375f08c3bdfSopenharmony_ci
376f08c3bdfSopenharmony_ci	sctp_freeladdrs(laddrs);
377f08c3bdfSopenharmony_ci
378f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sctp_freeladdrs");
379f08c3bdfSopenharmony_ci
380f08c3bdfSopenharmony_ci	n_paddrs = sctp_getpaddrs(sk1, associd1, &paddrs);
381f08c3bdfSopenharmony_ci	if (n_paddrs <= 0)
382f08c3bdfSopenharmony_ci                tst_brkm(TBROK, tst_exit, "sctp_getpaddrs: %s",
383f08c3bdfSopenharmony_ci			 strerror(errno));
384f08c3bdfSopenharmony_ci
385f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sctp_getpaddrs");
386f08c3bdfSopenharmony_ci
387f08c3bdfSopenharmony_ci	addr_buf = (void *)paddrs;
388f08c3bdfSopenharmony_ci	for (i = 0; i < n_paddrs; i++) {
389f08c3bdfSopenharmony_ci		sa_addr = (struct sockaddr *)addr_buf;
390f08c3bdfSopenharmony_ci		if (AF_INET == sa_addr->sa_family) {
391f08c3bdfSopenharmony_ci			in_addr = (struct sockaddr_in *)sa_addr;
392f08c3bdfSopenharmony_ci			tst_resm(TINFO, "PEER ADDR %d.%d.%d.%d PORT %d",
393f08c3bdfSopenharmony_ci				 NIPQUAD(in_addr->sin_addr),
394f08c3bdfSopenharmony_ci				 ntohs(in_addr->sin_port));
395f08c3bdfSopenharmony_ci			addr_buf += sizeof(struct sockaddr_in);
396f08c3bdfSopenharmony_ci		} else {
397f08c3bdfSopenharmony_ci			in6_addr = (struct sockaddr_in6 *)sa_addr;
398f08c3bdfSopenharmony_ci			tst_resm(TINFO,
399f08c3bdfSopenharmony_ci		 "PEER ADDR %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x PORT %d",
400f08c3bdfSopenharmony_ci			       NIP6(in6_addr->sin6_addr),
401f08c3bdfSopenharmony_ci			       ntohs(in6_addr->sin6_port));
402f08c3bdfSopenharmony_ci			addr_buf += sizeof(struct sockaddr_in6);
403f08c3bdfSopenharmony_ci		}
404f08c3bdfSopenharmony_ci	}
405f08c3bdfSopenharmony_ci
406f08c3bdfSopenharmony_ci	sctp_freepaddrs(paddrs);
407f08c3bdfSopenharmony_ci
408f08c3bdfSopenharmony_ci	tst_resm(TPASS, "sctp_freepaddrs");
409f08c3bdfSopenharmony_ci
410f08c3bdfSopenharmony_ci        /* Shut down the link.  */
411f08c3bdfSopenharmony_ci        close(sk1);
412f08c3bdfSopenharmony_ci
413f08c3bdfSopenharmony_ci        /* Get the shutdown complete notification. */
414f08c3bdfSopenharmony_ci	inmessage.msg_controllen = sizeof(incmsg);
415f08c3bdfSopenharmony_ci	inmessage.msg_namelen = sizeof(msgname);
416f08c3bdfSopenharmony_ci	memset(&msgname, 0, sizeof(msgname));
417f08c3bdfSopenharmony_ci        error = test_recvmsg(sk2, &inmessage, MSG_WAITALL);
418f08c3bdfSopenharmony_ci	test_check_msg_notification(&inmessage, error,
419f08c3bdfSopenharmony_ci				    sizeof(struct sctp_assoc_change),
420f08c3bdfSopenharmony_ci				    SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP);
421f08c3bdfSopenharmony_ci#if TEST_V6
422f08c3bdfSopenharmony_ci
423f08c3bdfSopenharmony_ci	if (inmessage.msg_namelen != sizeof(struct sockaddr_in6)) {
424f08c3bdfSopenharmony_ci		DUMP_CORE;
425f08c3bdfSopenharmony_ci	}
426f08c3bdfSopenharmony_ci	if (msgname.v6.sin6_port != htons(SCTP_TESTPORT_1)) {
427f08c3bdfSopenharmony_ci		DUMP_CORE;
428f08c3bdfSopenharmony_ci	}
429f08c3bdfSopenharmony_ci
430f08c3bdfSopenharmony_ci	if (msgname.v6.sin6_family != AF_INET6) {
431f08c3bdfSopenharmony_ci		DUMP_CORE;
432f08c3bdfSopenharmony_ci	}
433f08c3bdfSopenharmony_ci
434f08c3bdfSopenharmony_ci	if (memcmp(&msgname.v6.sin6_addr, &in6addr_loopback,
435f08c3bdfSopenharmony_ci		   sizeof(msgname.v6.sin6_addr))) {
436f08c3bdfSopenharmony_ci		DUMP_CORE;
437f08c3bdfSopenharmony_ci	}
438f08c3bdfSopenharmony_ci#else
439f08c3bdfSopenharmony_ci	if (inmessage.msg_namelen != sizeof(struct sockaddr_in)) {
440f08c3bdfSopenharmony_ci		DUMP_CORE;
441f08c3bdfSopenharmony_ci	}
442f08c3bdfSopenharmony_ci	if (msgname.v4.sin_port != htons(SCTP_TESTPORT_1)) {
443f08c3bdfSopenharmony_ci		DUMP_CORE;
444f08c3bdfSopenharmony_ci	}
445f08c3bdfSopenharmony_ci
446f08c3bdfSopenharmony_ci	if (msgname.v4.sin_family != AF_INET) {
447f08c3bdfSopenharmony_ci		DUMP_CORE;
448f08c3bdfSopenharmony_ci	}
449f08c3bdfSopenharmony_ci	if (msgname.v4.sin_addr.s_addr != SCTP_IP_LOOPBACK) {
450f08c3bdfSopenharmony_ci		DUMP_CORE;
451f08c3bdfSopenharmony_ci	}
452f08c3bdfSopenharmony_ci#endif
453f08c3bdfSopenharmony_ci
454f08c3bdfSopenharmony_ci	tst_resm(TPASS, "recvmsg SHUTDOWN_COMP notification");
455f08c3bdfSopenharmony_ci
456f08c3bdfSopenharmony_ci        close(sk2);
457f08c3bdfSopenharmony_ci
458f08c3bdfSopenharmony_ci        /* Indicate successful completion.  */
459f08c3bdfSopenharmony_ci       	return 0;
460f08c3bdfSopenharmony_ci}
461