1f08c3bdfSopenharmony_ci/* SCTP kernel Implementation 2f08c3bdfSopenharmony_ci * (C) Copyright IBM Corp. 2004 3f08c3bdfSopenharmony_ci * Copyright (c) 1999-2001 Motorola, Inc. 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * The SCTP implementation is free software; 6f08c3bdfSopenharmony_ci * you can redistribute it and/or modify it under the terms of 7f08c3bdfSopenharmony_ci * the GNU General Public License as published by 8f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2, or (at your option) 9f08c3bdfSopenharmony_ci * any later version. 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * The SCTP implementation is distributed in the hope that it 12f08c3bdfSopenharmony_ci * will be useful, but WITHOUT ANY WARRANTY; without even the implied 13f08c3bdfSopenharmony_ci * ************************ 14f08c3bdfSopenharmony_ci * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15f08c3bdfSopenharmony_ci * See the GNU General Public License for more details. 16f08c3bdfSopenharmony_ci * 17f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 18f08c3bdfSopenharmony_ci * along with GNU CC; see the file COPYING. If not, write to 19f08c3bdfSopenharmony_ci * the Free Software Foundation, 59 Temple Place - Suite 330, 20f08c3bdfSopenharmony_ci * Boston, MA 02111-1307, USA. 21f08c3bdfSopenharmony_ci * 22f08c3bdfSopenharmony_ci * Please send any bug reports or fixes you make to the 23f08c3bdfSopenharmony_ci * email address(es): 24f08c3bdfSopenharmony_ci * lksctp developers <lksctp-developers@lists.sourceforge.net> 25f08c3bdfSopenharmony_ci * 26f08c3bdfSopenharmony_ci * Or submit a bug report through the following website: 27f08c3bdfSopenharmony_ci * http://www.sf.net/projects/lksctp 28f08c3bdfSopenharmony_ci * 29f08c3bdfSopenharmony_ci * Any bugs reported given to us we will try to fix... any fixes shared will 30f08c3bdfSopenharmony_ci * be incorporated into the next SCTP release. 31f08c3bdfSopenharmony_ci * 32f08c3bdfSopenharmony_ci * Written or modified by: 33f08c3bdfSopenharmony_ci * Sridhar Samudrala <sri@us.ibm.com> 34f08c3bdfSopenharmony_ci */ 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci/* This is a kernel test to verify getsockname() and getpeername() interfaces 37f08c3bdfSopenharmony_ci * for single-homed one-to-one style sockets. 38f08c3bdfSopenharmony_ci */ 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci#include <stdio.h> 41f08c3bdfSopenharmony_ci#include <unistd.h> 42f08c3bdfSopenharmony_ci#include <stdlib.h> 43f08c3bdfSopenharmony_ci#include <string.h> 44f08c3bdfSopenharmony_ci#include <fcntl.h> 45f08c3bdfSopenharmony_ci#include <sys/types.h> 46f08c3bdfSopenharmony_ci#include <sys/socket.h> 47f08c3bdfSopenharmony_ci#include <sys/uio.h> 48f08c3bdfSopenharmony_ci#include <netinet/in.h> 49f08c3bdfSopenharmony_ci#include <errno.h> 50f08c3bdfSopenharmony_ci#include <netinet/sctp.h> 51f08c3bdfSopenharmony_ci#include <sctputil.h> 52f08c3bdfSopenharmony_ci#include "tst_kernel.h" 53f08c3bdfSopenharmony_ci 54f08c3bdfSopenharmony_cichar *TCID = __FILE__; 55f08c3bdfSopenharmony_ciint TST_TOTAL = 13; 56f08c3bdfSopenharmony_ciint TST_CNT = 0; 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci#define MAX_CLIENTS 10 59f08c3bdfSopenharmony_ci 60f08c3bdfSopenharmony_ciint 61f08c3bdfSopenharmony_cimain(void) 62f08c3bdfSopenharmony_ci{ 63f08c3bdfSopenharmony_ci int clt_sk, svr_sk, accept_sk; 64f08c3bdfSopenharmony_ci sockaddr_storage_t svr_loop, accept_loop; 65f08c3bdfSopenharmony_ci sockaddr_storage_t svr_local_addr, svr_peer_addr; 66f08c3bdfSopenharmony_ci sockaddr_storage_t clt_local_addr, clt_peer_addr; 67f08c3bdfSopenharmony_ci socklen_t len; 68f08c3bdfSopenharmony_ci int error; 69f08c3bdfSopenharmony_ci int pf_class; 70f08c3bdfSopenharmony_ci int fd, err_no = 0; 71f08c3bdfSopenharmony_ci char filename[21]; 72f08c3bdfSopenharmony_ci 73f08c3bdfSopenharmony_ci if (tst_check_driver("sctp")) 74f08c3bdfSopenharmony_ci tst_brkm(TCONF, tst_exit, "sctp driver not available"); 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_ci /* Rather than fflush() throughout the code, set stdout to 77f08c3bdfSopenharmony_ci * be unbuffered. 78f08c3bdfSopenharmony_ci */ 79f08c3bdfSopenharmony_ci setvbuf(stdout, NULL, _IONBF, 0); 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_ci /* Initialize the server and client addresses. */ 82f08c3bdfSopenharmony_ci#if TEST_V6 83f08c3bdfSopenharmony_ci pf_class = PF_INET6; 84f08c3bdfSopenharmony_ci svr_loop.v6.sin6_family = AF_INET6; 85f08c3bdfSopenharmony_ci svr_loop.v6.sin6_addr = (struct in6_addr)SCTP_IN6ADDR_ANY_INIT; 86f08c3bdfSopenharmony_ci svr_loop.v6.sin6_port = htons(SCTP_TESTPORT_1); 87f08c3bdfSopenharmony_ci#else 88f08c3bdfSopenharmony_ci pf_class = PF_INET; 89f08c3bdfSopenharmony_ci svr_loop.v4.sin_family = AF_INET; 90f08c3bdfSopenharmony_ci svr_loop.v4.sin_addr.s_addr = INADDR_ANY; 91f08c3bdfSopenharmony_ci svr_loop.v4.sin_port = htons(SCTP_TESTPORT_1); 92f08c3bdfSopenharmony_ci#endif 93f08c3bdfSopenharmony_ci 94f08c3bdfSopenharmony_ci /* Create and bind the listening server socket. */ 95f08c3bdfSopenharmony_ci svr_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 96f08c3bdfSopenharmony_ci test_bind(svr_sk, &svr_loop.sa, sizeof(svr_loop)); 97f08c3bdfSopenharmony_ci 98f08c3bdfSopenharmony_ci memset(&svr_local_addr, 0, sizeof(svr_local_addr)); 99f08c3bdfSopenharmony_ci len = sizeof(svr_local_addr); 100f08c3bdfSopenharmony_ci /* Verify that getsockname() on an unconnected socket works fine. */ 101f08c3bdfSopenharmony_ci error = getsockname(svr_sk, (struct sockaddr *)&svr_local_addr, &len); 102f08c3bdfSopenharmony_ci if (0 != error) 103f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname: %s", strerror(errno)); 104f08c3bdfSopenharmony_ci 105f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname on an unconnected socket"); 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_ci memset(&svr_peer_addr, 0, sizeof(svr_peer_addr)); 108f08c3bdfSopenharmony_ci len = sizeof(svr_peer_addr); 109f08c3bdfSopenharmony_ci /* Verify that getpeername() on an unconnected socket fails. */ 110f08c3bdfSopenharmony_ci error = getpeername(svr_sk, (struct sockaddr *)&svr_peer_addr, &len); 111f08c3bdfSopenharmony_ci if ((-1 != error) || (ENOTCONN != errno)) 112f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getpeername on an unconnected " 113f08c3bdfSopenharmony_ci "socket error:%d, errno:%d", error, errno); 114f08c3bdfSopenharmony_ci 115f08c3bdfSopenharmony_ci tst_resm(TPASS, "getpeername on an unconnected socket"); 116f08c3bdfSopenharmony_ci 117f08c3bdfSopenharmony_ci /* Mark svr_sk as being able to accept new associations. */ 118f08c3bdfSopenharmony_ci test_listen(svr_sk, 5); 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci /* Create the client socket. */ 121f08c3bdfSopenharmony_ci clt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 122f08c3bdfSopenharmony_ci 123f08c3bdfSopenharmony_ci /* Do a blocking connect from clt_sk to svr_sk */ 124f08c3bdfSopenharmony_ci#if TEST_V6 125f08c3bdfSopenharmony_ci svr_loop.v6.sin6_addr = in6addr_loopback; 126f08c3bdfSopenharmony_ci#else 127f08c3bdfSopenharmony_ci svr_loop.v4.sin_addr.s_addr = SCTP_IP_LOOPBACK; 128f08c3bdfSopenharmony_ci#endif 129f08c3bdfSopenharmony_ci test_connect(clt_sk, &svr_loop.sa, sizeof(svr_loop)); 130f08c3bdfSopenharmony_ci 131f08c3bdfSopenharmony_ci memset(&clt_local_addr, 0, sizeof(clt_local_addr)); 132f08c3bdfSopenharmony_ci len = sizeof(clt_local_addr); 133f08c3bdfSopenharmony_ci /* Get the client's local address. */ 134f08c3bdfSopenharmony_ci error = getsockname(clt_sk, (struct sockaddr *)&clt_local_addr, &len); 135f08c3bdfSopenharmony_ci if (0 != error) 136f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname on a connected client " 137f08c3bdfSopenharmony_ci "socket: %s", strerror(errno)); 138f08c3bdfSopenharmony_ci 139f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname on a connected client socket"); 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_ci memset(&clt_peer_addr, 0, sizeof(clt_peer_addr)); 142f08c3bdfSopenharmony_ci len = sizeof(clt_peer_addr); 143f08c3bdfSopenharmony_ci /* Get the client's peer address. */ 144f08c3bdfSopenharmony_ci error = getpeername(clt_sk, (struct sockaddr *)&clt_peer_addr, &len); 145f08c3bdfSopenharmony_ci if (0 != error) 146f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getpeername on a connected client " 147f08c3bdfSopenharmony_ci "socket: %s", strerror(errno)); 148f08c3bdfSopenharmony_ci 149f08c3bdfSopenharmony_ci tst_resm(TPASS, "getpeername on a connected client socket"); 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci /* Extract the association on the listening socket as a new socket. */ 152f08c3bdfSopenharmony_ci len = sizeof(accept_loop); 153f08c3bdfSopenharmony_ci accept_sk = test_accept(svr_sk, &accept_loop.sa, &len); 154f08c3bdfSopenharmony_ci 155f08c3bdfSopenharmony_ci memset(&svr_local_addr, 0, sizeof(svr_local_addr)); 156f08c3bdfSopenharmony_ci len = sizeof(svr_local_addr); 157f08c3bdfSopenharmony_ci /* Get the server's local address. */ 158f08c3bdfSopenharmony_ci error = getsockname(accept_sk, (struct sockaddr *)&svr_local_addr, 159f08c3bdfSopenharmony_ci &len); 160f08c3bdfSopenharmony_ci if (0 != error) 161f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname on a connected server " 162f08c3bdfSopenharmony_ci "socket: %s", strerror(errno)); 163f08c3bdfSopenharmony_ci 164f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname on a connected server socket"); 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_ci memset(&svr_peer_addr, 0, sizeof(svr_peer_addr)); 167f08c3bdfSopenharmony_ci len = sizeof(svr_peer_addr); 168f08c3bdfSopenharmony_ci /* Get the server's peer address. */ 169f08c3bdfSopenharmony_ci error = getpeername(accept_sk, (struct sockaddr *)&svr_peer_addr, 170f08c3bdfSopenharmony_ci &len); 171f08c3bdfSopenharmony_ci if (0 != error) 172f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getpeername on a connected server " 173f08c3bdfSopenharmony_ci "socket: %s", strerror(errno)); 174f08c3bdfSopenharmony_ci 175f08c3bdfSopenharmony_ci tst_resm(TPASS, "getpeername on a connected server socket"); 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci if (svr_local_addr.v4.sin_port != clt_peer_addr.v4.sin_port) 178f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Server's local port(%d) doesn't " 179f08c3bdfSopenharmony_ci "match Client's peer port(%d)\n", 180f08c3bdfSopenharmony_ci svr_local_addr.v4.sin_port, clt_peer_addr.v4.sin_port); 181f08c3bdfSopenharmony_ci 182f08c3bdfSopenharmony_ci if (svr_peer_addr.v4.sin_port != clt_local_addr.v4.sin_port) 183f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Server's peer port(%d) doesn't " 184f08c3bdfSopenharmony_ci "match Client's local port(%d)\n", 185f08c3bdfSopenharmony_ci svr_peer_addr.v4.sin_port, clt_local_addr.v4.sin_port); 186f08c3bdfSopenharmony_ci#if TEST_V6 187f08c3bdfSopenharmony_ci if (memcmp(&svr_local_addr, &clt_peer_addr, len) != 0) 188f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Server's local address and client's " 189f08c3bdfSopenharmony_ci "peer addresses do not match\n"); 190f08c3bdfSopenharmony_ci 191f08c3bdfSopenharmony_ci if (memcmp(&svr_peer_addr, &clt_local_addr, len) != 0) 192f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Server's peer address and client's " 193f08c3bdfSopenharmony_ci "local addresses do not match\n"); 194f08c3bdfSopenharmony_ci#else 195f08c3bdfSopenharmony_ci if (svr_local_addr.v4.sin_addr.s_addr != 196f08c3bdfSopenharmony_ci clt_peer_addr.v4.sin_addr.s_addr) 197f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Server's local address and client's " 198f08c3bdfSopenharmony_ci "peer addresses do not match\n"); 199f08c3bdfSopenharmony_ci if (svr_peer_addr.v4.sin_addr.s_addr != 200f08c3bdfSopenharmony_ci clt_local_addr.v4.sin_addr.s_addr) 201f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Server's peer address and client's " 202f08c3bdfSopenharmony_ci "local addresses do not match\n"); 203f08c3bdfSopenharmony_ci#endif 204f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname/getpeername server/client match"); 205f08c3bdfSopenharmony_ci 206f08c3bdfSopenharmony_ci memset(&clt_local_addr, 0, sizeof(clt_local_addr)); 207f08c3bdfSopenharmony_ci len = sizeof(clt_local_addr); 208f08c3bdfSopenharmony_ci /*getsockname(): Bad socket descriptor, EBADF expected error*/ 209f08c3bdfSopenharmony_ci error = getsockname(-1, (struct sockaddr *)&clt_local_addr, &len); 210f08c3bdfSopenharmony_ci if (error != -1 || errno != EBADF) 211f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname on a bad socket " 212f08c3bdfSopenharmony_ci "descriptor. error:%d errno:%d", error, errno); 213f08c3bdfSopenharmony_ci 214f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname on a bad socket descriptor - EBADF"); 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci /*getsockname(): Invalid socket, ENOTSOCK expected error*/ 217f08c3bdfSopenharmony_ci strcpy(filename, "/tmp/sctptest.XXXXXX"); 218f08c3bdfSopenharmony_ci fd = mkstemp(filename); 219f08c3bdfSopenharmony_ci if (fd == -1) 220f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s", 221f08c3bdfSopenharmony_ci filename, strerror(errno)); 222f08c3bdfSopenharmony_ci error = getsockname(fd, (struct sockaddr *)&clt_local_addr, &len); 223f08c3bdfSopenharmony_ci if (error == -1) 224f08c3bdfSopenharmony_ci err_no = errno; 225f08c3bdfSopenharmony_ci close(fd); 226f08c3bdfSopenharmony_ci unlink(filename); 227f08c3bdfSopenharmony_ci if (error != -1 || err_no != ENOTSOCK) 228f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname on an invalid socket " 229f08c3bdfSopenharmony_ci "error:%d errno:%d", error, err_no); 230f08c3bdfSopenharmony_ci 231f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname on an invalid socket - ENOTSOCK"); 232f08c3bdfSopenharmony_ci 233f08c3bdfSopenharmony_ci /*getsockname(): Invalid structure, EFAULT expected error*/ 234f08c3bdfSopenharmony_ci error = getsockname(clt_sk, (struct sockaddr *)-1, &len); 235f08c3bdfSopenharmony_ci if (error != -1 || errno != EFAULT) 236f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getsockname with invalid buffer " 237f08c3bdfSopenharmony_ci "error:%d errno:%d", error, errno); 238f08c3bdfSopenharmony_ci 239f08c3bdfSopenharmony_ci tst_resm(TPASS, "getsockname with invalid buffer - EFAULT"); 240f08c3bdfSopenharmony_ci 241f08c3bdfSopenharmony_ci memset(&clt_peer_addr, 0, sizeof(clt_peer_addr)); 242f08c3bdfSopenharmony_ci len = sizeof(clt_peer_addr); 243f08c3bdfSopenharmony_ci /*getpeername(): Bad socket descriptor, EBADF expected error*/ 244f08c3bdfSopenharmony_ci error = getpeername(-1, (struct sockaddr *)&clt_local_addr, &len); 245f08c3bdfSopenharmony_ci if (error != -1 || errno != EBADF) 246f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getpeername on a bad socket " 247f08c3bdfSopenharmony_ci "descriptor. error:%d errno:%d", error, errno); 248f08c3bdfSopenharmony_ci 249f08c3bdfSopenharmony_ci tst_resm(TPASS, "getpeername on a bad socket descriptor - EBADF"); 250f08c3bdfSopenharmony_ci 251f08c3bdfSopenharmony_ci /*getpeername(): Invalid socket, ENOTSOCK expected error*/ 252f08c3bdfSopenharmony_ci strcpy(filename, "/tmp/sctptest.XXXXXX"); 253f08c3bdfSopenharmony_ci fd = mkstemp(filename); 254f08c3bdfSopenharmony_ci if (fd == -1) 255f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s", 256f08c3bdfSopenharmony_ci filename, strerror(errno)); 257f08c3bdfSopenharmony_ci error = getpeername(fd, (struct sockaddr *)&clt_local_addr, &len); 258f08c3bdfSopenharmony_ci if (error == -1) 259f08c3bdfSopenharmony_ci err_no = errno; 260f08c3bdfSopenharmony_ci close(fd); 261f08c3bdfSopenharmony_ci unlink(filename); 262f08c3bdfSopenharmony_ci if (error != -1 || err_no != ENOTSOCK) 263f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getpeername on an invalid socket " 264f08c3bdfSopenharmony_ci "error:%d errno:%d", error, err_no); 265f08c3bdfSopenharmony_ci 266f08c3bdfSopenharmony_ci tst_resm(TPASS, "getpeername on an invalid socket - ENOTSOCK"); 267f08c3bdfSopenharmony_ci 268f08c3bdfSopenharmony_ci /*getpeername(): Invalid structure, EFAULT expected error*/ 269f08c3bdfSopenharmony_ci error = getpeername(clt_sk, (struct sockaddr *)-1, &len); 270f08c3bdfSopenharmony_ci if (error != -1 || errno != EFAULT) 271f08c3bdfSopenharmony_ci tst_brkm(TBROK, tst_exit, "getpeername with invalid buffer " 272f08c3bdfSopenharmony_ci "error:%d errno:%d", error, errno); 273f08c3bdfSopenharmony_ci 274f08c3bdfSopenharmony_ci tst_resm(TPASS, "getpeername with invalid buffer - EFAULT"); 275f08c3bdfSopenharmony_ci 276f08c3bdfSopenharmony_ci close(clt_sk); 277f08c3bdfSopenharmony_ci close(svr_sk); 278f08c3bdfSopenharmony_ci close(accept_sk); 279f08c3bdfSopenharmony_ci 280f08c3bdfSopenharmony_ci /* Indicate successful completion. */ 281f08c3bdfSopenharmony_ci return 0; 282f08c3bdfSopenharmony_ci} 283