1f08c3bdfSopenharmony_ci/* SCTP kernel Implementation 2f08c3bdfSopenharmony_ci * (C) Copyright IBM Corp. 2002, 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 * Copyright (c) 2001 La Monte H.P. Yarroll 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * The SCTP implementation is free software; 10f08c3bdfSopenharmony_ci * you can redistribute it and/or modify it under the terms of 11f08c3bdfSopenharmony_ci * the GNU General Public License as published by 12f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2, or (at your option) 13f08c3bdfSopenharmony_ci * any later version. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * The SCTP implementation is distributed in the hope that it 16f08c3bdfSopenharmony_ci * will be useful, but WITHOUT ANY WARRANTY; without even the implied 17f08c3bdfSopenharmony_ci * ************************ 18f08c3bdfSopenharmony_ci * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19f08c3bdfSopenharmony_ci * See the GNU General Public License for more details. 20f08c3bdfSopenharmony_ci * 21f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 22f08c3bdfSopenharmony_ci * along with GNU CC; see the file COPYING. If not, write to 23f08c3bdfSopenharmony_ci * the Free Software Foundation, 59 Temple Place - Suite 330, 24f08c3bdfSopenharmony_ci * Boston, MA 02111-1307, USA. 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * Please send any bug reports or fixes you make to the 27f08c3bdfSopenharmony_ci * email address(es): 28f08c3bdfSopenharmony_ci * lksctp developers <lksctp-developers@lists.sourceforge.net> 29f08c3bdfSopenharmony_ci * 30f08c3bdfSopenharmony_ci * Or submit a bug report through the following website: 31f08c3bdfSopenharmony_ci * http://www.sf.net/projects/lksctp 32f08c3bdfSopenharmony_ci * 33f08c3bdfSopenharmony_ci * Any bugs reported to us we will try to fix... any fixes shared will 34f08c3bdfSopenharmony_ci * be incorporated into the next SCTP release. 35f08c3bdfSopenharmony_ci * 36f08c3bdfSopenharmony_ci * Written or modified by: 37f08c3bdfSopenharmony_ci * La Monte H.P. Yarroll <piggy@acm.org> 38f08c3bdfSopenharmony_ci * Karl Knutson <karl@athena.chicago.il.us> 39f08c3bdfSopenharmony_ci * Jon Grimm <jgrimm@us.ibm.com> 40f08c3bdfSopenharmony_ci * Sridhar Samudrala <sri@us.ibm.com> 41f08c3bdfSopenharmony_ci * Daisy Chang <daisyc@us.ibm.com> 42f08c3bdfSopenharmony_ci */ 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci/* This is a functional test to verify binding a socket with INADDRY_ANY 45f08c3bdfSopenharmony_ci * address and send messages. 46f08c3bdfSopenharmony_ci */ 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_ci#include <stdio.h> 49f08c3bdfSopenharmony_ci#include <unistd.h> 50f08c3bdfSopenharmony_ci#include <string.h> 51f08c3bdfSopenharmony_ci#include <stdlib.h> 52f08c3bdfSopenharmony_ci#include <sys/types.h> 53f08c3bdfSopenharmony_ci#include <sys/socket.h> 54f08c3bdfSopenharmony_ci#include <sys/uio.h> 55f08c3bdfSopenharmony_ci#include <netinet/in.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 = 2; 63f08c3bdfSopenharmony_ciint TST_CNT = 0; 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_ciint 66f08c3bdfSopenharmony_cimain(void) 67f08c3bdfSopenharmony_ci{ 68f08c3bdfSopenharmony_ci int sk1, sk2; 69f08c3bdfSopenharmony_ci sockaddr_storage_t loop; 70f08c3bdfSopenharmony_ci sockaddr_storage_t anyaddr; 71f08c3bdfSopenharmony_ci struct msghdr outmessage; 72f08c3bdfSopenharmony_ci char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; 73f08c3bdfSopenharmony_ci char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 74f08c3bdfSopenharmony_ci struct cmsghdr *cmsg; 75f08c3bdfSopenharmony_ci struct sctp_sndrcvinfo *sinfo; 76f08c3bdfSopenharmony_ci struct iovec out_iov; 77f08c3bdfSopenharmony_ci struct iovec iov; 78f08c3bdfSopenharmony_ci struct msghdr inmessage; 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; 83f08c3bdfSopenharmony_ci int pf_class; 84f08c3bdfSopenharmony_ci uint32_t ppid; 85f08c3bdfSopenharmony_ci uint32_t stream; 86f08c3bdfSopenharmony_ci socklen_t namelen; 87f08c3bdfSopenharmony_ci 88f08c3bdfSopenharmony_ci if (tst_check_driver("sctp")) 89f08c3bdfSopenharmony_ci tst_brkm(TCONF, tst_exit, "sctp driver not available"); 90f08c3bdfSopenharmony_ci 91f08c3bdfSopenharmony_ci /* Rather than fflush() throughout the code, set stdout to 92f08c3bdfSopenharmony_ci * be unbuffered. 93f08c3bdfSopenharmony_ci */ 94f08c3bdfSopenharmony_ci setvbuf(stdout, NULL, _IONBF, 0); 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_ci /* Set some basic values which depend on the address family. */ 97f08c3bdfSopenharmony_ci#if TEST_V6 98f08c3bdfSopenharmony_ci pf_class = PF_INET6; 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_ci loop.v6.sin6_family = AF_INET6; 101f08c3bdfSopenharmony_ci loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_LOOPBACK_INIT; 102f08c3bdfSopenharmony_ci loop.v6.sin6_port = 0; 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci anyaddr.v6.sin6_family = AF_INET6; 105f08c3bdfSopenharmony_ci anyaddr.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT; 106f08c3bdfSopenharmony_ci anyaddr.v6.sin6_port = 0; 107f08c3bdfSopenharmony_ci#else 108f08c3bdfSopenharmony_ci pf_class = PF_INET; 109f08c3bdfSopenharmony_ci 110f08c3bdfSopenharmony_ci loop.v4.sin_family = AF_INET; 111f08c3bdfSopenharmony_ci loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; 112f08c3bdfSopenharmony_ci loop.v4.sin_port = 0; 113f08c3bdfSopenharmony_ci 114f08c3bdfSopenharmony_ci anyaddr.v4.sin_family = AF_INET; 115f08c3bdfSopenharmony_ci anyaddr.v4.sin_addr.s_addr = INADDR_ANY; 116f08c3bdfSopenharmony_ci anyaddr.v4.sin_port = 0; 117f08c3bdfSopenharmony_ci#endif /* TEST_V6 */ 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ci /* Create the two endpoints which will talk to each other. */ 120f08c3bdfSopenharmony_ci sk1 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); 121f08c3bdfSopenharmony_ci sk2 = test_socket(pf_class, SOCK_SEQPACKET, IPPROTO_SCTP); 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci /* Enable ASSOC_CHANGE and SNDRCVINFO notifications. */ 124f08c3bdfSopenharmony_ci test_enable_assoc_change(sk1); 125f08c3bdfSopenharmony_ci test_enable_assoc_change(sk2); 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci /* Bind these sockets to the test ports. */ 128f08c3bdfSopenharmony_ci test_bind(sk1, &loop.sa, sizeof(loop)); 129f08c3bdfSopenharmony_ci test_bind(sk2, &anyaddr.sa, sizeof(anyaddr)); 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci tst_resm(TPASS, "bind INADDR_ANY address"); 132f08c3bdfSopenharmony_ci 133f08c3bdfSopenharmony_ci /* Mark sk2 as being able to accept new associations */ 134f08c3bdfSopenharmony_ci test_listen(sk2, 1); 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci /* Now use getsockaname() to retrieve the ephmeral ports. */ 137f08c3bdfSopenharmony_ci namelen = sizeof(loop); 138f08c3bdfSopenharmony_ci error = getsockname(sk1, &loop.sa, &namelen); 139f08c3bdfSopenharmony_ci if (error != 0) 140f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno)); 141f08c3bdfSopenharmony_ci 142f08c3bdfSopenharmony_ci namelen = sizeof(anyaddr); 143f08c3bdfSopenharmony_ci error = getsockname(sk2, &anyaddr.sa, &namelen); 144f08c3bdfSopenharmony_ci if (error != 0) 145f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno)); 146f08c3bdfSopenharmony_ci 147f08c3bdfSopenharmony_ci#if TEST_V6 148f08c3bdfSopenharmony_ci loop.v6.sin6_port = anyaddr.v6.sin6_port; 149f08c3bdfSopenharmony_ci#else 150f08c3bdfSopenharmony_ci loop.v4.sin_port = anyaddr.v4.sin_port; 151f08c3bdfSopenharmony_ci#endif 152f08c3bdfSopenharmony_ci 153f08c3bdfSopenharmony_ci /* Send the first message. This will create the association. */ 154f08c3bdfSopenharmony_ci outmessage.msg_name = &loop; 155f08c3bdfSopenharmony_ci outmessage.msg_namelen = sizeof(loop); 156f08c3bdfSopenharmony_ci outmessage.msg_iov = &out_iov; 157f08c3bdfSopenharmony_ci outmessage.msg_iovlen = 1; 158f08c3bdfSopenharmony_ci outmessage.msg_control = outcmsg; 159f08c3bdfSopenharmony_ci outmessage.msg_controllen = sizeof(outcmsg); 160f08c3bdfSopenharmony_ci outmessage.msg_flags = 0; 161f08c3bdfSopenharmony_ci cmsg = CMSG_FIRSTHDR(&outmessage); 162f08c3bdfSopenharmony_ci cmsg->cmsg_level = IPPROTO_SCTP; 163f08c3bdfSopenharmony_ci cmsg->cmsg_type = SCTP_SNDRCV; 164f08c3bdfSopenharmony_ci cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 165f08c3bdfSopenharmony_ci outmessage.msg_controllen = cmsg->cmsg_len; 166f08c3bdfSopenharmony_ci sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 167f08c3bdfSopenharmony_ci memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); 168f08c3bdfSopenharmony_ci ppid = rand(); /* Choose an arbitrary value. */ 169f08c3bdfSopenharmony_ci stream = 1; 170f08c3bdfSopenharmony_ci sinfo->sinfo_ppid = ppid; 171f08c3bdfSopenharmony_ci sinfo->sinfo_stream = stream; 172f08c3bdfSopenharmony_ci outmessage.msg_iov->iov_base = message; 173f08c3bdfSopenharmony_ci outmessage.msg_iov->iov_len = strlen(message) + 1; 174f08c3bdfSopenharmony_ci test_sendmsg(sk1, &outmessage, 0, strlen(message)+1); 175f08c3bdfSopenharmony_ci 176f08c3bdfSopenharmony_ci /* Initialize inmessage for all receives. */ 177f08c3bdfSopenharmony_ci memset(&inmessage, 0, sizeof(inmessage)); 178f08c3bdfSopenharmony_ci iov.iov_base = test_malloc(REALLY_BIG); 179f08c3bdfSopenharmony_ci iov.iov_len = REALLY_BIG; 180f08c3bdfSopenharmony_ci inmessage.msg_iov = &iov; 181f08c3bdfSopenharmony_ci inmessage.msg_iovlen = 1; 182f08c3bdfSopenharmony_ci inmessage.msg_control = incmsg; 183f08c3bdfSopenharmony_ci 184f08c3bdfSopenharmony_ci /* Get the communication up message on sk2. */ 185f08c3bdfSopenharmony_ci inmessage.msg_controllen = sizeof(incmsg); 186f08c3bdfSopenharmony_ci error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 187f08c3bdfSopenharmony_ci test_check_msg_notification(&inmessage, error, 188f08c3bdfSopenharmony_ci sizeof(struct sctp_assoc_change), 189f08c3bdfSopenharmony_ci SCTP_ASSOC_CHANGE, SCTP_COMM_UP); 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ci /* Get the communication up message on sk1. */ 192f08c3bdfSopenharmony_ci inmessage.msg_controllen = sizeof(incmsg); 193f08c3bdfSopenharmony_ci error = test_recvmsg(sk1, &inmessage, MSG_WAITALL); 194f08c3bdfSopenharmony_ci test_check_msg_notification(&inmessage, error, 195f08c3bdfSopenharmony_ci sizeof(struct sctp_assoc_change), 196f08c3bdfSopenharmony_ci SCTP_ASSOC_CHANGE, SCTP_COMM_UP); 197f08c3bdfSopenharmony_ci 198f08c3bdfSopenharmony_ci /* Get the first message which was sent. */ 199f08c3bdfSopenharmony_ci inmessage.msg_controllen = sizeof(incmsg); 200f08c3bdfSopenharmony_ci error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 201f08c3bdfSopenharmony_ci test_check_msg_data(&inmessage, error, strlen(message) + 1, 202f08c3bdfSopenharmony_ci MSG_EOR, stream, ppid); 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci /* Send 2 messages. */ 205f08c3bdfSopenharmony_ci outmessage.msg_name = &loop; 206f08c3bdfSopenharmony_ci outmessage.msg_namelen = sizeof(loop); 207f08c3bdfSopenharmony_ci outmessage.msg_controllen = sizeof(outcmsg); 208f08c3bdfSopenharmony_ci outmessage.msg_flags = 0; 209f08c3bdfSopenharmony_ci cmsg = CMSG_FIRSTHDR(&outmessage); 210f08c3bdfSopenharmony_ci cmsg->cmsg_level = IPPROTO_SCTP; 211f08c3bdfSopenharmony_ci cmsg->cmsg_type = SCTP_SNDRCV; 212f08c3bdfSopenharmony_ci cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 213f08c3bdfSopenharmony_ci outmessage.msg_controllen = cmsg->cmsg_len; 214f08c3bdfSopenharmony_ci sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 215f08c3bdfSopenharmony_ci memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); 216f08c3bdfSopenharmony_ci ppid++; 217f08c3bdfSopenharmony_ci stream++; 218f08c3bdfSopenharmony_ci sinfo->sinfo_ppid = ppid; 219f08c3bdfSopenharmony_ci sinfo->sinfo_stream = stream; 220f08c3bdfSopenharmony_ci outmessage.msg_iov->iov_base = telephone; 221f08c3bdfSopenharmony_ci outmessage.msg_iov->iov_len = strlen(telephone) + 1; 222f08c3bdfSopenharmony_ci test_sendmsg(sk1, &outmessage, 0, strlen(telephone)+1); 223f08c3bdfSopenharmony_ci 224f08c3bdfSopenharmony_ci outmessage.msg_iov->iov_base = telephone_resp; 225f08c3bdfSopenharmony_ci outmessage.msg_iov->iov_len = strlen(telephone_resp) + 1; 226f08c3bdfSopenharmony_ci test_sendmsg(sk1, &outmessage, 0, strlen(telephone_resp)+1); 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci /* Get those two messages. */ 229f08c3bdfSopenharmony_ci inmessage.msg_controllen = sizeof(incmsg); 230f08c3bdfSopenharmony_ci error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 231f08c3bdfSopenharmony_ci test_check_msg_data(&inmessage, error, strlen(telephone) + 1, 232f08c3bdfSopenharmony_ci MSG_EOR, stream, ppid); 233f08c3bdfSopenharmony_ci 234f08c3bdfSopenharmony_ci inmessage.msg_controllen = sizeof(incmsg); 235f08c3bdfSopenharmony_ci error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 236f08c3bdfSopenharmony_ci test_check_msg_data(&inmessage, error, strlen(telephone_resp) + 1, 237f08c3bdfSopenharmony_ci MSG_EOR, stream, ppid); 238f08c3bdfSopenharmony_ci 239f08c3bdfSopenharmony_ci /* Shut down the link. */ 240f08c3bdfSopenharmony_ci close(sk1); 241f08c3bdfSopenharmony_ci 242f08c3bdfSopenharmony_ci /* Get the shutdown complete notification. */ 243f08c3bdfSopenharmony_ci inmessage.msg_controllen = sizeof(incmsg); 244f08c3bdfSopenharmony_ci error = test_recvmsg(sk2, &inmessage, MSG_WAITALL); 245f08c3bdfSopenharmony_ci test_check_msg_notification(&inmessage, error, 246f08c3bdfSopenharmony_ci sizeof(struct sctp_assoc_change), 247f08c3bdfSopenharmony_ci SCTP_ASSOC_CHANGE, SCTP_SHUTDOWN_COMP); 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci close(sk2); 250f08c3bdfSopenharmony_ci 251f08c3bdfSopenharmony_ci tst_resm(TPASS, "send msgs from a socket with INADDR_ANY bind address"); 252f08c3bdfSopenharmony_ci 253f08c3bdfSopenharmony_ci /* Indicate successful completion. */ 254f08c3bdfSopenharmony_ci return 0; 255f08c3bdfSopenharmony_ci} 256