Home | History | Annotate | Download | only in func_tests
      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 (at) 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 
     73 char *TCID = __FILE__;
     74 int TST_TOTAL = 10;
     75 int TST_CNT = 0;
     76 
     77 int
     78 main(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