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 sendmsg() call for 1-1 style sockets 6 * 7 * TEST1: Bad socket descriptor 8 * TEST2: Invalid socket 9 * TEST3: On a listening socket 10 * TEST4: Invalid iovec pointer 11 * TEST5: Invalid iovec length 12 * TEST6: Invalid msghdr pointer 13 * TEST7: Invalid sinfo flags 14 * TEST8: SCTP_EOF flag set 15 * TEST9: SCTP_ABORT flag set 16 * TEST10: On a closed association 17 * 18 * TEST11: Sending data from server socket to client socket 19 * TEST12: Sending data from client socket to server socket 20 * TEST13: Sending data from unconnected client to server 21 * TEST14: Sending a message on SHUT_RD socket 22 * 23 * The SCTP implementation is free software; 24 * you can redistribute it and/or modify it under the terms of 25 * the GNU General Public License as published by 26 * the Free Software Foundation; either version 2, or (at your option) 27 * any later version. 28 * 29 * The SCTP implementation is distributed in the hope that it 30 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 31 * ************************ 32 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 33 * See the GNU General Public License for more details. 34 * 35 * You should have received a copy of the GNU General Public License 36 * along with GNU CC; see the file COPYING. If not, write to 37 * the Free Software Foundation, 59 Temple Place - Suite 330, 38 * Boston, MA 02111-1307, USA. 39 * 40 * Please send any bug reports or fixes you make to the 41 * email address(es): 42 * lksctp developers <lksctp-developers@lists.sourceforge.net> 43 * 44 * Or submit a bug report through the following website: 45 * http://www.sf.net/projects/lksctp 46 * 47 * Any bugs reported given to us we will try to fix... any fixes shared will 48 * be incorporated into the next SCTP release 49 * 50 */ 51 52#include <stdio.h> 53#include <unistd.h> 54#include <fcntl.h> 55#include <stdlib.h> 56#include <string.h> 57#include <sys/types.h> 58#include <sys/socket.h> 59#include <netinet/in.h> /* for sockaddr_in */ 60#include <arpa/inet.h> 61#include <errno.h> 62#include <netinet/sctp.h> 63#include <sys/uio.h> 64#include <linux/socket.h> 65#include <sctputil.h> 66 67char *TCID = __FILE__; 68int TST_TOTAL = 14; 69int TST_CNT = 0; 70 71int 72main(int argc, char *argv[]) 73{ 74 socklen_t len; 75 int msg_count; 76 int sk,sk1,pf_class,lstn_sk,acpt_sk,acpt1_sk, flag; 77 struct msghdr outmessage; 78 char *message = "hello, world!\n"; 79 struct sctp_sndrcvinfo *sinfo; 80 int count; 81 char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; 82 struct cmsghdr *cmsg; 83 struct iovec out_iov; 84 struct msghdr inmessage; 85 char * buffer_rcv; 86 struct sockaddr_in conn_addr,lstn_addr,svr_addr; 87 struct iovec iov_rcv; 88 char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))]; 89 int fd, err_no = 0; 90 char filename[21]; 91 92 /* Rather than fflush() throughout the code, set stdout to 93 * be unbuffered. 94 */ 95 setvbuf(stdout, NULL, _IONBF, 0); 96 setvbuf(stderr, NULL, _IONBF, 0); 97 98 pf_class = PF_INET; 99 100 sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 101 102 sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 103 104 lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 105 106 conn_addr.sin_family = AF_INET; 107 conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; 108 conn_addr.sin_port = htons(SCTP_TESTPORT_1); 109 110 lstn_addr.sin_family = AF_INET; 111 lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; 112 lstn_addr.sin_port = htons(SCTP_TESTPORT_1); 113 114 /*Binding the listen socket*/ 115 test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); 116 117 /*Listening the socket*/ 118 test_listen(lstn_sk, 10); 119 120 len = sizeof(struct sockaddr_in); 121 122 test_connect(sk, (struct sockaddr *) &conn_addr, len); 123 124 acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); 125 126 memset(&outmessage, 0, sizeof(outmessage)); 127 outmessage.msg_name = &conn_addr; 128 outmessage.msg_namelen = sizeof(conn_addr); 129 outmessage.msg_iov = &out_iov; 130 outmessage.msg_iovlen = 1; 131 outmessage.msg_control = outcmsg; 132 outmessage.msg_controllen = sizeof(outcmsg); 133 outmessage.msg_flags = 0; 134 135 cmsg = CMSG_FIRSTHDR(&outmessage); 136 cmsg->cmsg_level = IPPROTO_SCTP; 137 cmsg->cmsg_type = SCTP_SNDRCV; 138 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 139 outmessage.msg_controllen = cmsg->cmsg_len; 140 sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 141 memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); 142 143 outmessage.msg_iov->iov_base = message; 144 outmessage.msg_iov->iov_len = strlen(message) + 1; 145 146 flag = MSG_NOSIGNAL; 147 /*sendmsg () TEST1: Bad socket descriptor, EBADF Expected error*/ 148 count = sendmsg(-1, &outmessage, flag); 149 if (count != -1 || errno != EBADF) 150 tst_brkm(TBROK, tst_exit, "sendmsg with a bad socket " 151 "descriptor count:%d, errno:%d", count, errno); 152 153 tst_resm(TPASS, "sendmsg() with a bad socket descriptor - EBADF"); 154 155 /*sendmsg () TEST2: Invalid socket, ENOTSOCK Expected error*/ 156 strcpy(filename, "/tmp/sctptest.XXXXXX"); 157 fd = mkstemp(filename); 158 if (fd == -1) 159 tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s", 160 filename, strerror(errno)); 161 count = sendmsg(fd, &outmessage, flag); 162 if (count == -1) 163 err_no = errno; 164 close(fd); 165 unlink(filename); 166 if (count != -1 || err_no != ENOTSOCK) 167 tst_brkm(TBROK, tst_exit, "sendmsg with invalid socket " 168 "count:%d, errno:%d", count, err_no); 169 170 tst_resm(TPASS, "sendmsg() with invalid socket - ENOTSOCK"); 171 172 /*sendmsg () TEST3: sendmsg on listening socket, EPIPE Expected error*/ 173 count = sendmsg(lstn_sk, &outmessage, flag); 174 if (count != -1 || errno != EPIPE) 175 tst_brkm(TBROK, tst_exit, "sendmsg on a listening socket " 176 "count:%d, errno:%d", count, errno); 177 178 tst_resm(TPASS, "sendmsg() on a listening socket - EPIPE"); 179 180 /*sendmsg () TEST4: Invalid iovec pointer EFAULT, Expected error*/ 181 outmessage.msg_iov = (struct iovec *)-1; 182 count = sendmsg(sk, &outmessage, flag); 183 if (count != -1 || errno != EFAULT) 184 tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec " 185 "pointer count:%d, errno:%d", count, errno); 186 187 tst_resm(TPASS, "sendmsg() with invalid iovec ptr - EFAULT"); 188 189 outmessage.msg_iov = &out_iov; 190 191 /*sendmsg () TEST5: Invalid iovec count EINVAL, Expected error*/ 192 outmessage.msg_iovlen = 0; 193 count = sendmsg(sk, &outmessage, flag); 194 if (count != -1 || errno != EINVAL) 195 tst_brkm(TBROK, tst_exit, "sendmsg with invalid iovec " 196 "length count:%d, errno:%d", count, errno); 197 198 tst_resm(TPASS, "sendmsg() with invalid iovec length - EINVAL"); 199 200 outmessage.msg_iovlen = 1; 201 202 /*sendmsg () TEST6: Invalid msghdr pointer EFAULT, Expected error*/ 203 count = sendmsg(sk, (struct msghdr *)-1, flag); 204 if (count != -1 || errno != EFAULT) 205 tst_brkm(TBROK, tst_exit, "sendmsg with invalid msghdr " 206 "pointer count:%d, errno:%d", count, errno); 207 208 tst_resm(TPASS, "sendmsg() with invalid msghdr ptr - EFAULT"); 209 210 /*sendmsg () TEST7: Invalid sinfo flag EINVAL, Expected error*/ 211 sinfo->sinfo_flags = 999; 212 count = sendmsg(sk, &outmessage, -1); 213 if (count != -1 || errno != EINVAL) 214 tst_brkm(TBROK, tst_exit, "sendmsg with invalid sinfo " 215 "flags count:%d, errno:%d", count, errno); 216 217 tst_resm(TPASS, "sendmsg() with invalid sinfo flags - EINVAL"); 218 219 /*sendmsg () TEST8: SCTP_EOF flag EINVAL, Expected error*/ 220 sinfo->sinfo_flags = SCTP_EOF; 221 count = sendmsg(sk, &outmessage, flag); 222 if (count != -1 || errno != EINVAL) 223 tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_EOF flag " 224 "count:%d, errno:%d", count, errno); 225 226 tst_resm(TPASS, "sendmsg() with SCTP_EOF flag - EINVAL"); 227 228 /*sendmsg () TEST9: SCTP_ABORT flag EINVAL, Expected error*/ 229 sinfo->sinfo_flags = SCTP_ABORT; 230 count = sendmsg(sk, &outmessage, flag); 231 if (count != -1 || errno != EINVAL) 232 tst_brkm(TBROK, tst_exit, "sendmsg with SCTP_ABORT flag " 233 "count:%d, errno:%d", count, errno); 234 235 tst_resm(TPASS, "sendmsg() with SCTP_ABORT flag - EINVAL"); 236 237 sinfo->sinfo_flags = 0; 238 239 test_connect(sk1, (struct sockaddr *) &lstn_addr, len); 240 241 test_sendmsg(sk1, &outmessage, flag, strlen(message)+1); 242 243 close(sk1); 244 acpt1_sk = test_accept(lstn_sk, (struct sockaddr *)&conn_addr, &len); 245 246 /*sendmsg () TEST10:sendmsg on closed association, EPIPE Expected error*/ 247 count = sendmsg(acpt1_sk, &outmessage, flag); 248 if (count != -1 || errno != EPIPE) 249 tst_brkm(TBROK, tst_exit, "sendmsg on a closed association " 250 "count:%d, errno:%d", count, errno); 251 252 tst_resm(TPASS, "sendmsg() on a closed association - EPIPE"); 253 254 close(acpt1_sk); 255 close(sk); 256 close(lstn_sk); 257 close(acpt_sk); 258 259 sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 260 261 lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 262 263 conn_addr.sin_family = AF_INET; 264 conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; 265 conn_addr.sin_port = htons(SCTP_TESTPORT_1); 266 267 lstn_addr.sin_family = AF_INET; 268 lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK; 269 lstn_addr.sin_port = htons(SCTP_TESTPORT_1); 270 271 /*Binding the listen socket*/ 272 test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr)); 273 274 /*Listening the socket*/ 275 test_listen(lstn_sk, 10); 276 277 len = sizeof(struct sockaddr_in); 278 flag = MSG_NOSIGNAL; 279 280 test_connect(sk, (struct sockaddr *) &conn_addr, len); 281 282 acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); 283 284 memset(&outmessage, 0, sizeof(outmessage)); 285 outmessage.msg_name = &svr_addr; 286 outmessage.msg_namelen = sizeof(svr_addr); 287 outmessage.msg_iov = &out_iov; 288 outmessage.msg_iovlen = 1; 289 outmessage.msg_control = outcmsg; 290 outmessage.msg_controllen = sizeof(outcmsg); 291 outmessage.msg_flags = 0; 292 293 cmsg = CMSG_FIRSTHDR(&outmessage); 294 cmsg->cmsg_level = IPPROTO_SCTP; 295 cmsg->cmsg_type = SCTP_SNDRCV; 296 cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); 297 outmessage.msg_controllen = cmsg->cmsg_len; 298 sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 299 memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo)); 300 301 outmessage.msg_iov->iov_base = message; 302 outmessage.msg_iov->iov_len = strlen(message) + 1; 303 304 memset(&inmessage, 0, sizeof(inmessage)); 305 buffer_rcv = malloc(REALLY_BIG); 306 307 iov_rcv.iov_base = buffer_rcv; 308 iov_rcv.iov_len = REALLY_BIG; 309 inmessage.msg_iov = &iov_rcv; 310 inmessage.msg_iovlen = 1; 311 inmessage.msg_control = incmsg; 312 inmessage.msg_controllen = sizeof(incmsg); 313 314 msg_count = strlen(message) + 1; 315 316 /*sendmsg() TEST11: Sending data from server socket to client socket*/ 317 count = sendmsg(acpt_sk, &outmessage, flag); 318 if (count != msg_count) 319 tst_brkm(TBROK, tst_exit, "sendmsg from accept socket to " 320 "client count:%d, errno:%d", count, errno); 321 322 tst_resm(TPASS, "sendmsg() from accept socket to client - SUCCESS"); 323 324 count = test_recvmsg(sk, &inmessage, flag); 325 test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); 326 327 outmessage.msg_name = &conn_addr; 328 outmessage.msg_namelen = sizeof(conn_addr); 329 /*sendmsg() TEST12: Sending data from client socket to server socket*/ 330 count = sendmsg(sk, &outmessage, flag); 331 if (count != msg_count) 332 tst_brkm(TBROK, tst_exit, "sendmsg from client to server " 333 "count:%d, errno:%d", count, errno); 334 335 tst_resm(TPASS, "sendmsg() from client to server - SUCCESS"); 336 337 count = test_recvmsg(acpt_sk, &inmessage, flag); 338 test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); 339 340 outmessage.msg_name = &conn_addr; 341 outmessage.msg_namelen = sizeof(conn_addr); 342 close(sk); 343 close(acpt_sk); 344 sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP); 345 346 /*sendmsg() TEST13: Sending data from unconnected client socket to 347 server socket*/ 348 count = sendmsg(sk1, &outmessage, flag); 349 if (count != msg_count) 350 tst_brkm(TBROK, tst_exit, "sendmsg from unconnected client to " 351 "server count:%d, errno:%d", count, errno); 352 353 tst_resm(TPASS, "sendmsg() from unconnected clt to server - SUCCESS"); 354 355 acpt_sk = test_accept(lstn_sk, (struct sockaddr *)&svr_addr, &len); 356 357 count = test_recvmsg(acpt_sk, &inmessage, flag); 358 test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); 359 360 test_shutdown(sk1, SHUT_RD); 361 362 /*sendmsg() TEST14: Sending a message on SHUT_RD socket*/ 363 count = sendmsg(sk1, &outmessage, flag); 364 if (count != msg_count) 365 tst_brkm(TBROK, tst_exit, "sendmsg on a SHUT_RD socket " 366 "count:%d, errno:%d", count, errno); 367 368 tst_resm(TPASS, "sendmsg() on a SHUT_RD socket - SUCCESS"); 369 370 count = test_recvmsg(acpt_sk, &inmessage, flag); 371 test_check_msg_data(&inmessage, count, msg_count, MSG_EOR, 0, 0); 372 373 close(sk1); 374 close(lstn_sk); 375 close(acpt_sk); 376 return 0; 377} 378