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 negative scenarios for getsockopt ()
      6  * setsockopt () call for 1-1 style sockets
      7  *
      8  * setsockopt () Tests:
      9  * -------------------
     10  * TEST1: setsockopt: Bad socket descriptor
     11  * TEST2: setsockopt: Invalid socket
     12  * TEST3: setsockopt: Invalid level
     13  * TEST4: setsockopt: Invalid option buffer
     14  * TEST5: setsockopt: Invalid option name
     15  * TEST6: getsockopt: Bad socket descriptor
     16  * TEST7: getsockopt: Invalid socket
     17  * TEST8: getsockopt: Invalid option buffer
     18  * TEST9: getsockopt: Invalid option name
     19  *
     20  * TEST10: getsockopt: SCTP_INITMSG
     21  * TEST11: setsockopt: SCTP_INITMSG
     22  * TEST12: setsockopt: SO_LINGER
     23  * TEST13: getsockopt: SO_LINGER
     24  * TEST14: getsockopt: SO_RCVBUF
     25  * TEST15: getsockopt: SCTP_STATUS
     26  * TEST16: setsockopt: SO_RCVBUF
     27  * TEST17: setsockopt: SO_SNDBUF
     28  * TEST18: getsockopt: SO_SNDBUF
     29  * TEST19: getsockopt: SCTP_PRIMARY_ADDR
     30  * TEST20: setsockopt: SCTP_PRIMARY_ADDR
     31  * TEST21: getsockopt: SCTP_ASSOCINFO
     32  * TEST22: setsockopt: SCTP_ASSOCINFO
     33  *
     34  * The SCTP implementation is free software;
     35  * you can redistribute it and/or modify it under the terms of
     36  * the GNU General Public License as published by
     37  * the Free Software Foundation; either version 2, or (at your option)
     38  * any later version.
     39  *
     40  * The SCTP implementation is distributed in the hope that it
     41  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
     42  *                 ************************
     43  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     44  * See the GNU General Public License for more details.
     45  *
     46  * You should have received a copy of the GNU General Public License
     47  * along with GNU CC; see the file COPYING.  If not, write to
     48  * the Free Software Foundation, 59 Temple Place - Suite 330,
     49  * Boston, MA 02111-1307, USA.
     50  *
     51  * Please send any bug reports or fixes you make to the
     52  * email address(es):
     53  *    lksctp developers <lksctp-developers (at) lists.sourceforge.net>
     54  *
     55  * Or submit a bug report through the following website:
     56  *    http://www.sf.net/projects/lksctp
     57  *
     58  * Any bugs reported given to us we will try to fix... any fixes shared will
     59  * be incorporated into the next SCTP release.
     60  *
     61  */
     62 
     63 #include <stdio.h>
     64 #include <unistd.h>
     65 #include <fcntl.h>
     66 #include <stdlib.h>
     67 #include <string.h>
     68 #include <sys/types.h>
     69 #include <sys/socket.h>
     70 #include <netinet/in.h>
     71 #include <errno.h>
     72 #include <netinet/sctp.h>
     73 #include <sys/uio.h>
     74 #include <sctputil.h>
     75 
     76 char *TCID = __FILE__;
     77 int TST_TOTAL = 22;
     78 int TST_CNT = 0;
     79 
     80 int
     81 main(void)
     82 {
     83 	int error;
     84 	socklen_t len;
     85 	int sk, sk1, sk2, acpt_sk, pf_class;
     86 	struct sctp_rtoinfo grtinfo;
     87 	struct sockaddr_in lstn_addr, conn_addr;
     88 	struct sctp_initmsg ginmsg; /*get the value for SCTP_INITMSG*/
     89 	struct sctp_initmsg sinmsg; /*set the value for SCTP_INITMSG*/
     90 	struct linger slinger; /*SO_LINGER structure*/
     91 	struct linger glinger; /*SO_LINGER structure*/
     92 	struct sockaddr_in addr;
     93 	struct sockaddr_in *gaddr;
     94 	struct sctp_status gstatus; /*SCTP_STATUS option*/
     95 	int rcvbuf_val_get, rcvbuf_val_set; /*get and set var for SO_RCVBUF*/
     96 	int sndbuf_val_get, sndbuf_val_set;/*get and set var for SO_SNDBUF*/
     97 	struct sctp_prim gprimaddr;/*SCTP_PRIMARY_ADDR get*/
     98 	struct sctp_prim sprimaddr;/*SCTP_PRIMARY_ADDR set*/
     99 	struct sctp_assocparams sassocparams;  /* SCTP_ASSOCPARAMS set */
    100 	struct sctp_assocparams gassocparams;  /* SCTP_ASSOCPARAMS get */
    101 	int fd, err_no = 0;
    102 	char filename[21];
    103 
    104 	/* Rather than fflush() throughout the code, set stdout to
    105          * be unbuffered.
    106          */
    107         setvbuf(stdout, NULL, _IONBF, 0);
    108         setvbuf(stderr, NULL, _IONBF, 0);
    109 
    110 	pf_class = PF_INET;
    111 
    112 	sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
    113 
    114 	/*setsockopt() TEST1: Bad socket descriptor EBADF, Expected error*/
    115         error = setsockopt(-1, IPPROTO_SCTP, 0, 0, 0);
    116 	if (error != -1 || errno != EBADF)
    117 		tst_brkm(TBROK, tst_exit, "setsockopt with a bad socket "
    118 			 "descriptor error:%d, errno:%d", error, errno);
    119 
    120 	tst_resm(TPASS, "setsockopt() with a bad socket descriptor - EBADF");
    121 
    122 	/*setsockopt() TEST2: Invalid socket ENOTSOCK, Expected error*/
    123 	strcpy(filename, "/tmp/sctptest.XXXXXX");
    124 	fd = mkstemp(filename);
    125 	if (fd == -1)
    126 		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
    127 				filename, strerror(errno));
    128 	error = setsockopt(fd, IPPROTO_SCTP, 0, 0, 0);
    129 	if (error == -1)
    130 		err_no = errno;
    131 	close(fd);
    132 	unlink(filename);
    133 	if (error != -1 || err_no != ENOTSOCK)
    134 		tst_brkm(TBROK, tst_exit, "setsockopt with an invalid socket "
    135 			 "error:%d, errno:%d", error, err_no);
    136 
    137 	tst_resm(TPASS, "setsockopt() with an invalid socket - ENOTSOCK");
    138 
    139 	/*setsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/
    140         error = setsockopt(sk, -1, SCTP_RTOINFO, 0, 0);
    141 	if (error != -1 || errno != ENOPROTOOPT)
    142 		tst_brkm(TBROK, tst_exit, "setsockopt with invalid level "
    143 			 "error:%d, errno:%d", error, errno);
    144 
    145 	tst_resm(TPASS, "setsockopt() with an invalid level - ENOPROTOOPT");
    146 
    147 	/*setsockopt() TEST4: Invalid option buffer EFAULT, Expected error*/
    148         error = setsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO,
    149 		(const struct sctp_rtoinfo *)-1, sizeof(struct sctp_rtoinfo));
    150 	if (error != -1 || errno != EFAULT)
    151 		tst_brkm(TBROK, tst_exit, "setsockopt with invalid option "
    152 			 "buffer error:%d, errno:%d", error, errno);
    153 
    154 	tst_resm(TPASS, "setsockopt() with invalid option buffer - EFAULT");
    155 
    156 	/*setsockopt() TEST5: Invalid option Name EOPNOTSUPP, Expected error*/
    157         error = setsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, 0, 0);
    158 	if (error != -1 || errno != EOPNOTSUPP)
    159 		tst_brkm(TBROK, tst_exit, "setsockopt with invalid option "
    160 			 "name error:%d, errno:%d", error, errno);
    161 
    162 	tst_resm(TPASS, "setsockopt() with invalid option name - EOPNOTSUPP");
    163 
    164 	/*getsockopt() TEST6: Bad socket descriptor EBADF, Expected error*/
    165         error = getsockopt(-1, IPPROTO_SCTP, 0, 0, 0);
    166 	if (error != -1 || errno != EBADF)
    167 		tst_brkm(TBROK, tst_exit, "getsockopt with a bad socket "
    168 			 "descriptor error:%d, errno:%d", error, errno);
    169 
    170 	tst_resm(TPASS, "getsockopt() with a bad socket descriptor - EBADF");
    171 
    172 	/*getsockopt() TEST7: Invalid socket ENOTSOCK, Expected error*/
    173 	strcpy(filename, "/tmp/sctptest.XXXXXX");
    174 	fd = mkstemp(filename);
    175 	if (fd == -1)
    176 		tst_brkm(TBROK, tst_exit, "Failed to mkstemp %s: %s",
    177 				filename, strerror(errno));
    178 	error = getsockopt(fd, IPPROTO_SCTP, 0, 0, 0);
    179 	if (error == -1)
    180 		err_no = errno;
    181 	close(fd);
    182 	unlink(filename);
    183 	if (error != -1 || err_no != ENOTSOCK)
    184 		tst_brkm(TBROK, tst_exit, "getsockopt with an invalid socket "
    185 			 "error:%d, errno:%d", error, err_no);
    186 
    187 	tst_resm(TPASS, "getsockopt() with an invalid socket - ENOTSOCK");
    188 #if 0
    189 	/*getsockopt() TEST3: Invalid level ENOPROTOOPT, Expected error*/
    190 	/*I have commented this test case because it is returning EOPNOTSUPP.
    191 	When I checked the code there also it is returning EOPNOTSUPP. As this
    192 	is not specific to TCP style, I do not want to do the code change*/
    193 
    194         error = getsockopt(sk, -1, SCTP_RTOINFO, 0, 0);
    195 	if (error != -1 || errno != ENOPROTOOPT)
    196 		tst_brkm(TBROK, tst_exit, "getsockopt with invalid level "
    197 			 "error:%d, errno:%d", error, errno);
    198 
    199 	tst_resm(TPASS, "getsockopt() with an invalid level - ENOPROTOOPT");
    200 #endif
    201 	len = sizeof(struct sctp_rtoinfo);
    202 
    203 	/*getsockopt() TEST8: Invalid option buffer EFAULT, Expected error*/
    204         error = getsockopt(sk, IPPROTO_SCTP, SCTP_RTOINFO,
    205 			   (struct sctp_rtoinfo *)-1, &len);
    206 	if (error != -1 || errno != EFAULT)
    207 		tst_brkm(TBROK, tst_exit, "getsockopt with invalid option "
    208 			 "buffer error:%d, errno:%d", error, errno);
    209 
    210 	tst_resm(TPASS, "getsockopt() with invalid option buffer - EFAULT");
    211 
    212 	/*getsockopt() TEST9: Invalid option Name EOPNOTSUPP, Expected error*/
    213         error = getsockopt(sk, IPPROTO_SCTP, SCTP_AUTOCLOSE, &grtinfo, &len);
    214 	if (error != -1 || errno != EOPNOTSUPP)
    215 		tst_brkm(TBROK, tst_exit, "getsockopt with invalid option "
    216 			 "name error:%d, errno:%d", error, errno);
    217 
    218 	tst_resm(TPASS, "getsockopt() with invalid option name - EOPNOTSUPP");
    219 
    220 	close(sk);
    221 
    222 	sk1 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
    223 	sk2 = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);
    224 
    225 	lstn_addr.sin_family = AF_INET;
    226         lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
    227         lstn_addr.sin_port = htons(SCTP_TESTPORT_1);
    228 
    229 	conn_addr.sin_family = AF_INET;
    230         conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
    231         conn_addr.sin_port = htons(SCTP_TESTPORT_1);
    232 
    233         len = sizeof(struct sctp_initmsg);
    234 
    235 	/* TEST10: Test cases for getsockopt SCTP_INITMSG */
    236 	test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len);
    237 
    238 	tst_resm(TPASS, "getsockopt() SCTP_INITMSG - SUCCESS");
    239 
    240 	sinmsg.sinit_num_ostreams = 5;
    241         sinmsg.sinit_max_instreams = 5;
    242         sinmsg.sinit_max_attempts = 3;
    243         sinmsg.sinit_max_init_timeo = 30;
    244 	/* TEST11: Test case for setsockopt SCTP_INITMSG */
    245 	test_setsockopt(sk1, SCTP_INITMSG, &sinmsg, sizeof(sinmsg));
    246 
    247 	test_getsockopt(sk1, SCTP_INITMSG, &ginmsg, &len);
    248 
    249 	if (sinmsg.sinit_num_ostreams != ginmsg.sinit_num_ostreams &&
    250 	    sinmsg.sinit_max_instreams != ginmsg.sinit_max_instreams &&
    251 	    sinmsg.sinit_max_attempts != ginmsg.sinit_max_attempts &&
    252 	    sinmsg.sinit_max_init_timeo != ginmsg.sinit_max_init_timeo)
    253 		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG "
    254 			 "compare failed");
    255 
    256 	tst_resm(TPASS, "setsockopt() SCTP_INITMSG - SUCCESS");
    257 
    258 	/*Now get the values on different endpoint*/
    259 	test_getsockopt(sk2, SCTP_INITMSG, &ginmsg, &len);
    260 
    261 	/*Comparison should not succeed here*/
    262 	if (sinmsg.sinit_num_ostreams == ginmsg.sinit_num_ostreams &&
    263 	    sinmsg.sinit_max_instreams == ginmsg.sinit_max_instreams &&
    264 	    sinmsg.sinit_max_attempts == ginmsg.sinit_max_attempts &&
    265 	    sinmsg.sinit_max_init_timeo == ginmsg.sinit_max_init_timeo)
    266 		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SCTP_INITMSG "
    267 			 "unexpected compare success");
    268 
    269 	/* SO_LINGER Test with l_onff = 0 and l_linger = 0 */
    270 	slinger.l_onoff = 0;
    271 	slinger.l_linger = 0;
    272 	test_bind(sk1, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));
    273 	test_listen(sk1, 10 );
    274 	len = sizeof(struct sockaddr_in);
    275 	test_connect(sk2, (struct sockaddr *) &conn_addr, len);
    276 
    277 	acpt_sk = test_accept(sk1, (struct sockaddr *)&addr, &len);
    278 
    279         len = sizeof(struct linger);
    280 	/* TEST12: Test case for setsockopt SO_LINGER */
    281 	error = setsockopt(sk2, SOL_SOCKET, SO_LINGER, &slinger, len);
    282 	if (error < 0)
    283 		tst_brkm(TBROK, tst_exit, "setsockopt SO_LINGER "
    284                          "error:%d, errno:%d", error, errno);
    285 
    286 	tst_resm(TPASS, "setsockopt() SO_LINGER - SUCCESS");
    287 
    288 	/* TEST13: Test case for getsockopt SO_LINGER */
    289 	error = getsockopt(sk2, SOL_SOCKET, SO_LINGER, &glinger, &len);
    290 	if (error < 0)
    291 		tst_brkm(TBROK, tst_exit, "getsockopt SO_LINGER "
    292                          "error:%d, errno:%d", error, errno);
    293 
    294 	tst_resm(TPASS, "getsockopt() SO_LINGER - SUCCESS");
    295 
    296 	if (slinger.l_onoff != glinger.l_onoff ||
    297 	    slinger.l_linger != glinger.l_linger)
    298 		tst_brkm(TBROK, tst_exit, "setsockopt/getsockopt SO_LINGER "
    299 			 "compare failed");
    300 
    301 	/*First gets the default SO_RCVBUF value and comapres with the
    302 	value obtained from SCTP_STATUS*/
    303 	len = sizeof(int);
    304 	/* TEST14: Test case for getsockopt SO_RCVBUF */
    305 	error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len);
    306 	if (error < 0)
    307 		tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF "
    308                          "error:%d, errno:%d", error, errno);
    309 
    310 	tst_resm(TPASS, "getsockopt() SO_RCVBUF - SUCCESS");
    311 
    312 	len = sizeof(struct sctp_status);
    313 	/* TEST15: Test case for getsockopt SCTP_STATUS */
    314 	error = getsockopt(sk2, IPPROTO_SCTP, SCTP_STATUS, &gstatus, &len);
    315 	if (error < 0)
    316 		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_STATUS "
    317                          "error:%d, errno:%d", error, errno);
    318 
    319 	tst_resm(TPASS, "getsockopt() SCTP_STATUS - SUCCESS");
    320 
    321 	/* Reducing the SO_RCVBUF value using setsockopt() */
    322 	/* Upstream has changed the MIN_RCVBUF (2048 + sizeof(struct sk_buff)) */
    323 	len = sizeof(int);
    324 	rcvbuf_val_set = 2048;
    325 	/* TEST16: Test case for setsockopt SO_RCVBUF */
    326 	error = setsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_set, len);
    327 	if (error < 0)
    328 		tst_brkm(TBROK, tst_exit, "setsockopt SO_RCVBUF "
    329                          "error:%d, errno:%d", error, errno);
    330 
    331 	tst_resm(TPASS, "setsockopt() SO_RCVBUF - SUCCESS");
    332 
    333 	error = getsockopt(sk2, SOL_SOCKET, SO_RCVBUF, &rcvbuf_val_get, &len);
    334 	if (error < 0)
    335 		tst_brkm(TBROK, tst_exit, "getsockopt SO_RCVBUF "
    336                          "error:%d, errno:%d", error, errno);
    337 
    338 	if ((2 * rcvbuf_val_set) != rcvbuf_val_get)
    339 		tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and "
    340 			 "got value differs Set Value=%d Get Value=%d",
    341 			 (2*rcvbuf_val_set), rcvbuf_val_get);
    342 
    343 	sndbuf_val_set = 5000;
    344 	/* TEST17: Test case for setsockopt SO_SNDBUF */
    345 	error = setsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_set, len);
    346 	if (error < 0)
    347 		tst_brkm(TBROK, tst_exit, "setsockopt SO_SNDBUF "
    348                          "error:%d, errno:%d", error, errno);
    349 
    350 	tst_resm(TPASS, "setsockopt() SO_SNDBUF - SUCCESS");
    351 
    352 	/* TEST18: Test case for getsockopt SO_SNDBUF */
    353 	error = getsockopt(sk2, SOL_SOCKET, SO_SNDBUF, &sndbuf_val_get, &len);
    354 	if (error < 0)
    355 		tst_brkm(TBROK, tst_exit, "getsockopt SO_SNDBUF "
    356                          "error:%d, errno:%d", error, errno);
    357 
    358 	tst_resm(TPASS, "getsockopt() SO_SNDBUF - SUCCESS");
    359 
    360 	if ((2 * sndbuf_val_set) != sndbuf_val_get)
    361 		tst_brkm(TBROK, tst_exit, "Comparison failed:Set value and "
    362 			 "got value differs Set Value=%d Get Value=%d\n",
    363 			 (2*sndbuf_val_set), sndbuf_val_get);
    364 
    365 
    366 	/* Getting the primary address using SCTP_PRIMARY_ADDR */
    367         len = sizeof(struct sctp_prim);
    368 	/* TEST19: Test case for getsockopt SCTP_PRIMARY_ADDR */
    369 	error = getsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &gprimaddr,
    370 			   &len);
    371 	if (error < 0)
    372 		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR "
    373                          "error:%d, errno:%d", error, errno);
    374 
    375 	tst_resm(TPASS, "getsockopt() SCTP_PRIMARY_ADDR - SUCCESS");
    376 
    377 	gaddr = (struct sockaddr_in *) &gprimaddr.ssp_addr;
    378 	if(htons(gaddr->sin_port) != lstn_addr.sin_port &&
    379 	   gaddr->sin_family != lstn_addr.sin_family &&
    380 	   gaddr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
    381 		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_PRIMARY_ADDR value "
    382 			 "mismatch");
    383 
    384 	memcpy(&sprimaddr, &gprimaddr, sizeof(struct sctp_prim));
    385 
    386 	/* TEST20: Test case for setsockopt SCTP_PRIMARY_ADDR */
    387 	error = setsockopt(sk2,IPPROTO_SCTP, SCTP_PRIMARY_ADDR, &sprimaddr,
    388 			   len);
    389 	if (error < 0)
    390 		tst_brkm(TBROK, tst_exit, "setsockopt SCTP_PRIMARY_ADDR "
    391                          "error:%d, errno:%d", error, errno);
    392 
    393 	tst_resm(TPASS, "setsockopt() SCTP_PRIMARY_ADDR - SUCCESS");
    394 
    395 	/* TEST21: Test case for getsockopt SCTP_PRIMARY_ADDR */
    396 	/* Getting the association info using SCTP_ASSOCINFO */
    397         len = sizeof(struct sctp_assocparams);
    398 	error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams,
    399 			   &len);
    400 	if (error < 0)
    401 		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO "
    402                          "error:%d, errno:%d", error, errno);
    403 
    404 	tst_resm(TPASS, "getsockopt() SCTP_ASSOCINFO - SUCCESS");
    405 
    406 	/* TEST21: Test case for setsockopt SCTP_ASSOCINFO */
    407 	memcpy(&sassocparams, &gassocparams, sizeof(struct sctp_assocparams));
    408 	sassocparams.sasoc_asocmaxrxt += 5;
    409 	sassocparams.sasoc_cookie_life += 10;
    410 
    411 	error = setsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &sassocparams,
    412 			   len);
    413 	if (error < 0)
    414 		tst_brkm(TBROK, tst_exit, "setsockopt SCTP_ASSOCINFO "
    415                          "error:%d, errno:%d", error, errno);
    416 
    417 	error = getsockopt(sk2, IPPROTO_SCTP, SCTP_ASSOCINFO, &gassocparams,
    418 			   &len);
    419 	if (error < 0)
    420 		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO "
    421                          "error:%d, errno:%d", error, errno);
    422 
    423 	if (sassocparams.sasoc_asocmaxrxt != gassocparams.sasoc_asocmaxrxt ||
    424 	    sassocparams.sasoc_cookie_life != gassocparams.sasoc_cookie_life)
    425 		tst_brkm(TBROK, tst_exit, "getsockopt SCTP_ASSOCINFO value "
    426 			 "mismatch");
    427 	tst_resm(TPASS, "setsockopt() SCTP_ASSOCINFO - SUCCESS");
    428 
    429 	close(sk2);
    430 	close(sk1);
    431 	close(acpt_sk);
    432 
    433 	return 0;
    434 }
    435