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