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