1/* SCTP kernel Implementation 2 * Copyright (c) 2003 Hewlett-Packard Development Company, L.P 3 * (C) Copyright IBM Corp. 2004 4 * 5 * This file has test cases to test the sctp_getladdrs (), sctp_freealddrs (), 6 * sctp_getpaddrs (), sctp_freeapaddrs () for 1-1 style sockets 7 * 8 * sctp_getladdrs () Tests: 9 * ----------------------- 10 * TEST1: Bad socket descriptor 11 * TEST2: Invalid socket 12 * TEST3: Socket of different protocol 13 * TEST4: Getting the local addresses 14 * 15 * sctp_freealddrs () Tests: 16 * ------------------------ 17 * TEST5: Freeing the local address 18 * 19 * sctp_getpaddrs () Tests: 20 * ----------------------- 21 * TEST6: Bad socket descriptor 22 * TEST7: Invalid socket 23 * TEST8: Socket of different protocol 24 * TEST9: Getting the peers addresses 25 * 26 * sctp_freeapddrs () Tests: 27 * ------------------------ 28 * TEST10: Freeing the peer's address 29 * 30 * The SCTP implementation is free software; 31 * you can redistribute it and/or modify it under the terms of 32 * the GNU General Public License as published by 33 * the Free Software Foundation; either version 2, or (at your option) 34 * any later version. 35 * 36 * The SCTP implementation is distributed in the hope that it 37 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 38 * ************************ 39 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 40 * See the GNU General Public License for more details. 41 * 42 * You should have received a copy of the GNU General Public License 43 * along with GNU CC; see the file COPYING. If not, write to 44 * the Free Software Foundation, 59 Temple Place - Suite 330, 45 * Boston, MA 02111-1307, USA. 46 * 47 * Please send any bug reports or fixes you make to the 48 * email address(es): 49 * lksctp developers <lksctp-developers@lists.sourceforge.net> 50 * 51 * Or submit a bug report through the following website: 52 * http://www.sf.net/projects/lksctp 53 * 54 * Any bugs reported given to us we will try to fix... any fixes shared will 55 * be incorporated into the next SCTP release. 56 * 57 */ 58 59#include <stdio.h> 60#include <unistd.h> 61#include <fcntl.h> 62#include <stdlib.h> 63#include <string.h> 64#include <sys/types.h> 65#include <sys/socket.h> 66#include <netinet/in.h> /* for sockaddr_in */ 67#include <arpa/inet.h> 68#include <errno.h> 69#include <netinet/sctp.h> 70#include <sys/uio.h> 71#include <sctputil.h> 72 73char *TCID = __FILE__; 74int TST_TOTAL = 10; 75int TST_CNT = 0; 76 77int 78main(int argc, char *argv[]) 79{ 80 int error; 81 socklen_t len; 82 int lstn_sk,clnt_sk,acpt_sk,pf_class,sk1; 83 struct msghdr outmessage; 84 struct msghdr inmessage; 85 char *message = "hello, world!\n"; 86 struct iovec iov_rcv; 87 struct sctp_sndrcvinfo *sinfo; 88 int msg_count; 89 char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 90 struct cmsghdr *cmsg; 91 struct iovec out_iov; 92 char * buffer_rcv; 93 char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; 94 struct sockaddr *laddrs, *paddrs; 95 int fd, err_no = 0; 96 char filename[21]; 97 98 struct sockaddr_in conn_addr,lstn_addr,acpt_addr; 99 struct sockaddr_in *addr; 100 101 /* Rather than fflush() throughout the code, set stdout to 102 * be unbuffered. 103 */ 104 setvbuf(stdout, NULL, _IONBF, 0); 105 setvbuf(stderr, NULL, _IONBF, 0); 106 107 pf_class = PF_INET; 108 109 /*Creating a regular socket*/ 110 clnt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 111 112 /*Creating a listen socket*/ 113 lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 114 115 conn_addr.sin_family = AF_INET; 116 conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; 117 conn_addr.sin_port = htons(SCTP_TESTPORT_1); 118 119 lstn_addr.sin_family = AF_INET; 120 lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; 121 lstn_addr.sin_port = htons(SCTP_TESTPORT_1); 122 123 /*Binding the listen socket*/ 124 test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); 125 126 /*Listening many sockets as we are calling too many connect here*/ 127 test_listen(lstn_sk, 1); 128 129 len = sizeof(struct sockaddr_in); 130 131 test_connect(clnt_sk, (struct sockaddr *) &conn_addr, len); 132 133 acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len); 134 135 memset(&inmessage, 0, sizeof(inmessage)); 136 buffer_rcv = malloc(REALLY_BIG); 137 138 iov_rcv.iov_base = buffer_rcv; 139 iov_rcv.iov_len = REALLY_BIG; 140 inmessage.msg_iov = &iov_rcv; 141 inmessage.msg_iovlen = 1; 142 inmessage.msg_control = incmsg; 143 inmessage.msg_controllen = sizeof(incmsg); 144 145 msg_count = strlen(message) + 1; 146 147 memset(&outmessage, 0, sizeof(outmessage)); 148 outmessage.msg_name = &lstn_addr; 149 outmessage.msg_namelen = sizeof(lstn_addr); 150 outmessage.msg_iov = &out_iov; 151 outmessage.msg_iovlen = 1; 152 outmessage.msg_control = outcmsg; 153 outmessage.msg_controllen = sizeof(outcmsg); 154 outmessage.msg_flags = 0; 155 156 cmsg = CMSG_FIRSTHDR(&outmessage); 157 cmsg->cmsg_level = IPPROTO_SCTP; 158 cmsg->cmsg_type = SCTP_SNDRCV; 159 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 160 outmessage.msg_controllen = cmsg->cmsg_len; 161 sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 162 memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); 163 164 outmessage.msg_iov->iov_base = message; 165 outmessage.msg_iov->iov_len = msg_count; 166 167 test_sendmsg(clnt_sk, &outmessage, MSG_NOSIGNAL, msg_count); 168 169 test_recvmsg(acpt_sk, &inmessage, MSG_NOSIGNAL); 170 171 /*sctp_getladdrs() TEST1: Bad socket descriptor, EBADF Expected error*/ 172 error = sctp_getladdrs(-1, 0, &laddrs); 173 if (error != -1 || errno != EBADF) 174 tst_brkm(TBROK, tst_exit, "sctp_getladdrs with a bad socket " 175 "descriptor error:%d, errno:%d", error, errno); 176 177 tst_resm(TPASS, "sctp_getladdrs() with a bad socket descriptor - " 178 "EBADF"); 179 180 /*sctp_getladdrs() TEST2: Invalid socket, ENOTSOCK Expected error*/ 181 strcpy(filename, "/tmp/sctptest.XXXXXX"); 182 fd = mkstemp(filename); 183 if (fd == -1) 184 tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s", 185 filename, strerror(errno)); 186 error = sctp_getladdrs(fd, 0, &laddrs); 187 if (error == -1) 188 err_no = errno; 189 close(fd); 190 unlink(filename); 191 if (error != -1 || err_no != ENOTSOCK) 192 tst_brkm(TBROK, tst_exit, "sctp_getladdrs with invalid socket " 193 "error:%d, errno:%d", error, err_no); 194 195 tst_resm(TPASS, "sctp_getladdrs() with invalid socket - ENOTSOCK"); 196 197 /*sctp_getladdrs() TEST3: socket of different protocol 198 EOPNOTSUPP Expected error*/ 199 sk1 = socket(pf_class, SOCK_STREAM, IPPROTO_IP); 200 error = sctp_getladdrs(sk1, 0, &laddrs); 201 if (error != -1 || errno != EOPNOTSUPP) 202 tst_brkm(TBROK, tst_exit, "sctp_getladdrs with socket of " 203 "different protocol error:%d, errno:%d", error, errno); 204 205 tst_resm(TPASS, "sctp_getladdrs() with socket of different protocol - " 206 "EOPNOTSUPP"); 207 208 /*sctp_getladdrs() TEST4: Getting the local addresses*/ 209 error = sctp_getladdrs(lstn_sk, 0, &laddrs); 210 if (error < 0) 211 tst_brkm(TBROK, tst_exit, "sctp_getladdrs with valid socket " 212 "error:%d, errno:%d", error, errno); 213 214 addr = (struct sockaddr_in *)laddrs; 215 if (addr->sin_port != lstn_addr.sin_port || 216 addr->sin_family != lstn_addr.sin_family || 217 addr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr) 218 tst_brkm(TBROK, tst_exit, "sctp_getladdrs comparision failed"); 219 220 tst_resm(TPASS, "sctp_getladdrs() - SUCCESS"); 221 222 /*sctp_freealddrs() TEST5: freeing the local address*/ 223 if ((sctp_freeladdrs(laddrs)) < 0) 224 tst_brkm(TBROK, tst_exit, "sctp_freeladdrs " 225 "error:%d, errno:%d", error, errno); 226 227 tst_resm(TPASS, "sctp_freeladdrs() - SUCCESS"); 228 229 /*sctp_getpaddrs() TEST6: Bad socket descriptor, EBADF Expected error*/ 230 error = sctp_getpaddrs(-1, 0, &paddrs); 231 if (error != -1 || errno != EBADF) 232 tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with a bad socket " 233 "descriptor error:%d, errno:%d", error, errno); 234 235 tst_resm(TPASS, "sctp_getpaddrs() with a bad socket descriptor - " 236 "EBADF"); 237 238 /*sctp_getpaddrs() TEST7: Invalid socket, ENOTSOCK Expected error*/ 239 strcpy(filename, "/tmp/sctptest.XXXXXX"); 240 fd = mkstemp(filename); 241 if (fd == -1) 242 tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s", 243 filename, strerror(errno)); 244 error = sctp_getpaddrs(fd, 0, &paddrs); 245 if (error == -1) 246 err_no = errno; 247 close(fd); 248 unlink(filename); 249 if (error != -1 || err_no != ENOTSOCK) 250 tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with invalid socket " 251 "error:%d, errno:%d", error, err_no); 252 253 tst_resm(TPASS, "sctp_getpaddrs() with invalid socket - ENOTSOCK"); 254 255 /*sctp_getpaddrs() TEST8: socket of different protocol 256 EOPNOTSUPP Expected error*/ 257 error = sctp_getpaddrs(sk1, 0, &laddrs); 258 if (error != -1 || errno != EOPNOTSUPP) 259 tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with socket of " 260 "different protocol error:%d, errno:%d", error, errno); 261 262 tst_resm(TPASS, "sctp_getpaddrs() with socket of different protocol - " 263 "EOPNOTSUPP"); 264 265 /*sctp_getpaddrs() TEST9: Getting the peer addresses*/ 266 error = sctp_getpaddrs(acpt_sk, 0, &paddrs); 267 if (error < 0) 268 tst_brkm(TBROK, tst_exit, "sctp_getpaddrs with valid socket " 269 "error:%d, errno:%d", error, errno); 270 271 addr = (struct sockaddr_in *)paddrs; 272 if (addr->sin_port != acpt_addr.sin_port || 273 addr->sin_family != acpt_addr.sin_family || 274 addr->sin_addr.s_addr != acpt_addr.sin_addr.s_addr) 275 tst_brkm(TBROK, tst_exit, "sctp_getpaddrs comparision failed"); 276 277 tst_resm(TPASS, "sctp_getpaddrs() - SUCCESS"); 278 279 /*sctp_freeapddrs() TEST10: freeing the peer address*/ 280 if ((sctp_freepaddrs(paddrs)) < 0) 281 tst_brkm(TBROK, tst_exit, "sctp_freepaddrs " 282 "error:%d, errno:%d", error, errno); 283 284 tst_resm(TPASS, "sctp_freepaddrs() - SUCCESS"); 285 286 close(clnt_sk); 287 288 return 0; 289} 290