1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 6f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 7f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 8f08c3bdfSopenharmony_ci * (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 17f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci/* 21f08c3bdfSopenharmony_ci * Test Name: sockioctl01 22f08c3bdfSopenharmony_ci * 23f08c3bdfSopenharmony_ci * Test Description: 24f08c3bdfSopenharmony_ci * Verify that ioctl() on sockets returns the proper errno for various 25f08c3bdfSopenharmony_ci * failure cases 26f08c3bdfSopenharmony_ci */ 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci#include <stdio.h> 29f08c3bdfSopenharmony_ci#include <unistd.h> 30f08c3bdfSopenharmony_ci#include <errno.h> 31f08c3bdfSopenharmony_ci#include <fcntl.h> 32f08c3bdfSopenharmony_ci 33f08c3bdfSopenharmony_ci#include <sys/types.h> 34f08c3bdfSopenharmony_ci#include <sys/socket.h> 35f08c3bdfSopenharmony_ci#include <sys/signal.h> 36f08c3bdfSopenharmony_ci#include <sys/ioctl.h> 37f08c3bdfSopenharmony_ci#include <sys/stat.h> 38f08c3bdfSopenharmony_ci 39f08c3bdfSopenharmony_ci#include <netinet/in.h> 40f08c3bdfSopenharmony_ci#include <net/if.h> 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci#include "test.h" 43f08c3bdfSopenharmony_ci#include "safe_macros.h" 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_cichar *TCID = "sockioctl01"; 46f08c3bdfSopenharmony_ciint testno; 47f08c3bdfSopenharmony_ci 48f08c3bdfSopenharmony_cistatic int s; /* socket descriptor */ 49f08c3bdfSopenharmony_cistatic struct sockaddr_in sin0, fsin1; 50f08c3bdfSopenharmony_cistatic struct ifconf ifc; 51f08c3bdfSopenharmony_cistatic struct ifreq ifr; 52f08c3bdfSopenharmony_cistatic int sinlen; 53f08c3bdfSopenharmony_cistatic int optval; 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_cistatic struct ifreq buf[200]; 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_cistatic void setup(void); 58f08c3bdfSopenharmony_cistatic void setup0(void); 59f08c3bdfSopenharmony_cistatic void setup1(void); 60f08c3bdfSopenharmony_cistatic void setup2(void); 61f08c3bdfSopenharmony_cistatic void setup3(void); 62f08c3bdfSopenharmony_ci 63f08c3bdfSopenharmony_cistatic void cleanup(void); 64f08c3bdfSopenharmony_cistatic void cleanup0(void); 65f08c3bdfSopenharmony_cistatic void cleanup1(void); 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_cistruct test_case_t { 68f08c3bdfSopenharmony_ci int domain; /* PF_INET, PF_UNIX, ... */ 69f08c3bdfSopenharmony_ci int type; /* SOCK_STREAM, SOCK_DGRAM ... */ 70f08c3bdfSopenharmony_ci int proto; /* protocol number (usually 0 = default) */ 71f08c3bdfSopenharmony_ci int cmd; /* IPPROTO_* */ 72f08c3bdfSopenharmony_ci void *arg; 73f08c3bdfSopenharmony_ci struct sockaddr *sin; 74f08c3bdfSopenharmony_ci int salen; 75f08c3bdfSopenharmony_ci int retval; /* syscall return value */ 76f08c3bdfSopenharmony_ci int experrno; /* expected errno */ 77f08c3bdfSopenharmony_ci void (*setup) (void); 78f08c3bdfSopenharmony_ci void (*cleanup) (void); 79f08c3bdfSopenharmony_ci char *desc; 80f08c3bdfSopenharmony_ci} tdat[] = { 81f08c3bdfSopenharmony_ci { 82f08c3bdfSopenharmony_ci PF_INET, SOCK_STREAM, 0, SIOCATMARK, &optval, 83f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), -1, 84f08c3bdfSopenharmony_ci EBADF, setup0, cleanup0, "bad file descriptor"} 85f08c3bdfSopenharmony_ci , { 86f08c3bdfSopenharmony_ci PF_INET, SOCK_STREAM, 0, SIOCATMARK, &optval, 87f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), -1, 88f08c3bdfSopenharmony_ci EINVAL, setup0, cleanup0, "not a socket"} 89f08c3bdfSopenharmony_ci , 90f08c3bdfSopenharmony_ci#if !defined(UCLINUX) 91f08c3bdfSopenharmony_ci { 92f08c3bdfSopenharmony_ci PF_INET, SOCK_STREAM, 0, SIOCATMARK, 0, 93f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), -1, 94f08c3bdfSopenharmony_ci EFAULT, setup1, cleanup1, "invalid option buffer"} 95f08c3bdfSopenharmony_ci , 96f08c3bdfSopenharmony_ci#endif 97f08c3bdfSopenharmony_ci { 98f08c3bdfSopenharmony_ci PF_INET, SOCK_DGRAM, 0, SIOCATMARK, &optval, 99f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), -1, 100f08c3bdfSopenharmony_ci EINVAL, setup1, cleanup1, "ATMARK on UDP"} 101f08c3bdfSopenharmony_ci , { 102f08c3bdfSopenharmony_ci PF_INET, SOCK_DGRAM, 0, SIOCGIFCONF, &ifc, 103f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), 0, 104f08c3bdfSopenharmony_ci 0, setup2, cleanup1, "SIOCGIFCONF"} 105f08c3bdfSopenharmony_ci , { 106f08c3bdfSopenharmony_ci PF_INET, SOCK_DGRAM, 0, SIOCGIFFLAGS, &ifr, 107f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), 0, 108f08c3bdfSopenharmony_ci 0, setup3, cleanup1, "SIOCGIFFLAGS"} 109f08c3bdfSopenharmony_ci , { 110f08c3bdfSopenharmony_ci PF_INET, SOCK_DGRAM, 0, SIOCGIFFLAGS, 0, 111f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), -1, 112f08c3bdfSopenharmony_ci EFAULT, setup3, cleanup1, "SIOCGIFFLAGS with invalid ifr"} 113f08c3bdfSopenharmony_ci , { 114f08c3bdfSopenharmony_ci PF_INET, SOCK_DGRAM, 0, SIOCSIFFLAGS, 0, 115f08c3bdfSopenharmony_ci (struct sockaddr *)&fsin1, sizeof(fsin1), -1, 116f08c3bdfSopenharmony_ci EFAULT, setup3, cleanup1, "SIOCSIFFLAGS with invalid ifr"} 117f08c3bdfSopenharmony_ci,}; 118f08c3bdfSopenharmony_ci 119f08c3bdfSopenharmony_ciint TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]); 120f08c3bdfSopenharmony_ci 121f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 122f08c3bdfSopenharmony_ci{ 123f08c3bdfSopenharmony_ci int lc; 124f08c3bdfSopenharmony_ci 125f08c3bdfSopenharmony_ci tst_parse_opts(argc, argv, NULL, NULL); 126f08c3bdfSopenharmony_ci 127f08c3bdfSopenharmony_ci setup(); 128f08c3bdfSopenharmony_ci 129f08c3bdfSopenharmony_ci for (lc = 0; TEST_LOOPING(lc); ++lc) { 130f08c3bdfSopenharmony_ci tst_count = 0; 131f08c3bdfSopenharmony_ci for (testno = 0; testno < TST_TOTAL; ++testno) { 132f08c3bdfSopenharmony_ci tdat[testno].setup(); 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci TEST(ioctl(s, tdat[testno].cmd, tdat[testno].arg)); 135f08c3bdfSopenharmony_ci if (TEST_RETURN != tdat[testno].retval || 136f08c3bdfSopenharmony_ci (TEST_RETURN < 0 && 137f08c3bdfSopenharmony_ci TEST_ERRNO != tdat[testno].experrno)) { 138f08c3bdfSopenharmony_ci tst_resm(TFAIL, "%s ; returned" 139f08c3bdfSopenharmony_ci " %ld (expected %d), errno %d (expected" 140f08c3bdfSopenharmony_ci " %d)", tdat[testno].desc, 141f08c3bdfSopenharmony_ci TEST_RETURN, tdat[testno].retval, 142f08c3bdfSopenharmony_ci TEST_ERRNO, tdat[testno].experrno); 143f08c3bdfSopenharmony_ci } else { 144f08c3bdfSopenharmony_ci tst_resm(TPASS, "%s successful", 145f08c3bdfSopenharmony_ci tdat[testno].desc); 146f08c3bdfSopenharmony_ci } 147f08c3bdfSopenharmony_ci tdat[testno].cleanup(); 148f08c3bdfSopenharmony_ci } 149f08c3bdfSopenharmony_ci } 150f08c3bdfSopenharmony_ci 151f08c3bdfSopenharmony_ci cleanup(); 152f08c3bdfSopenharmony_ci tst_exit(); 153f08c3bdfSopenharmony_ci} 154f08c3bdfSopenharmony_ci 155f08c3bdfSopenharmony_cistatic void setup(void) 156f08c3bdfSopenharmony_ci{ 157f08c3bdfSopenharmony_ci TEST_PAUSE; 158f08c3bdfSopenharmony_ci 159f08c3bdfSopenharmony_ci sin0.sin_family = AF_INET; 160f08c3bdfSopenharmony_ci sin0.sin_port = 0; 161f08c3bdfSopenharmony_ci sin0.sin_addr.s_addr = INADDR_ANY; 162f08c3bdfSopenharmony_ci 163f08c3bdfSopenharmony_ci tst_tmpdir(); 164f08c3bdfSopenharmony_ci} 165f08c3bdfSopenharmony_ci 166f08c3bdfSopenharmony_cistatic void cleanup(void) 167f08c3bdfSopenharmony_ci{ 168f08c3bdfSopenharmony_ci tst_rmdir(); 169f08c3bdfSopenharmony_ci} 170f08c3bdfSopenharmony_ci 171f08c3bdfSopenharmony_cistatic void setup0(void) 172f08c3bdfSopenharmony_ci{ 173f08c3bdfSopenharmony_ci if (tdat[testno].experrno == EBADF) { 174f08c3bdfSopenharmony_ci s = 1025; /* anything not an open file */ 175f08c3bdfSopenharmony_ci } else { 176f08c3bdfSopenharmony_ci unlink("test"); 177f08c3bdfSopenharmony_ci 178f08c3bdfSopenharmony_ci if ((mknod("test", S_IRWXU | S_IFIFO, 0)) == -1) { 179f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "Could not create test - " 180f08c3bdfSopenharmony_ci "errno: %s", strerror(errno)); 181f08c3bdfSopenharmony_ci } 182f08c3bdfSopenharmony_ci 183f08c3bdfSopenharmony_ci if ((s = open("test", O_RDWR)) == -1) { 184f08c3bdfSopenharmony_ci tst_brkm(TBROK, cleanup, "Could not open test - " 185f08c3bdfSopenharmony_ci "errno: %s", strerror(errno)); 186f08c3bdfSopenharmony_ci } 187f08c3bdfSopenharmony_ci 188f08c3bdfSopenharmony_ci /* 189f08c3bdfSopenharmony_ci * kernel commit 46ce341b2f176c2611f12ac390adf862e932eb02 190f08c3bdfSopenharmony_ci * changed -EINVAL to -ENOIOCTLCMD, so vfs_ioctl now 191f08c3bdfSopenharmony_ci * returns -ENOTTY. 192f08c3bdfSopenharmony_ci */ 193f08c3bdfSopenharmony_ci tdat[testno].experrno = ENOTTY; 194f08c3bdfSopenharmony_ci } 195f08c3bdfSopenharmony_ci} 196f08c3bdfSopenharmony_ci 197f08c3bdfSopenharmony_cistatic void cleanup0(void) 198f08c3bdfSopenharmony_ci{ 199f08c3bdfSopenharmony_ci if (tdat[testno].experrno != EBADF) { 200f08c3bdfSopenharmony_ci (void)close(s); 201f08c3bdfSopenharmony_ci s = -1; 202f08c3bdfSopenharmony_ci } 203f08c3bdfSopenharmony_ci} 204f08c3bdfSopenharmony_ci 205f08c3bdfSopenharmony_cistatic void setup1(void) 206f08c3bdfSopenharmony_ci{ 207f08c3bdfSopenharmony_ci s = SAFE_SOCKET(cleanup, tdat[testno].domain, tdat[testno].type, 208f08c3bdfSopenharmony_ci tdat[testno].proto); 209f08c3bdfSopenharmony_ci SAFE_BIND(cleanup, s, (struct sockaddr *)&sin0, sizeof(sin0)); 210f08c3bdfSopenharmony_ci sinlen = sizeof(fsin1); 211f08c3bdfSopenharmony_ci 212f08c3bdfSopenharmony_ci if (strncmp(tdat[testno].desc, "ATMARK on UDP", 14) == 0) 213f08c3bdfSopenharmony_ci tdat[testno].experrno = ENOTTY; 214f08c3bdfSopenharmony_ci} 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_cistatic void setup2(void) 217f08c3bdfSopenharmony_ci{ 218f08c3bdfSopenharmony_ci s = SAFE_SOCKET(cleanup, tdat[testno].domain, tdat[testno].type, 219f08c3bdfSopenharmony_ci tdat[testno].proto); 220f08c3bdfSopenharmony_ci ifc.ifc_len = sizeof(buf); 221f08c3bdfSopenharmony_ci ifc.ifc_buf = (char *)buf; 222f08c3bdfSopenharmony_ci} 223f08c3bdfSopenharmony_ci 224f08c3bdfSopenharmony_cistatic void setup3(void) 225f08c3bdfSopenharmony_ci{ 226f08c3bdfSopenharmony_ci setup2(); 227f08c3bdfSopenharmony_ci SAFE_IOCTL(cleanup, s, SIOCGIFCONF, &ifc); 228f08c3bdfSopenharmony_ci ifr = *(struct ifreq *)ifc.ifc_buf; 229f08c3bdfSopenharmony_ci} 230f08c3bdfSopenharmony_ci 231f08c3bdfSopenharmony_cistatic void cleanup1(void) 232f08c3bdfSopenharmony_ci{ 233f08c3bdfSopenharmony_ci (void)close(s); 234f08c3bdfSopenharmony_ci s = -1; 235f08c3bdfSopenharmony_ci} 236