1*b29e1426SEnji Cooper /*- 2*b29e1426SEnji Cooper * Copyright (c) 2018 Enji Cooper. 3*b29e1426SEnji Cooper * All rights reserved. 4*b29e1426SEnji Cooper * 5*b29e1426SEnji Cooper * Redistribution and use in source and binary forms, with or without 6*b29e1426SEnji Cooper * modification, are permitted provided that the following conditions 7*b29e1426SEnji Cooper * are met: 8*b29e1426SEnji Cooper * 1. Redistributions of source code must retain the above copyright 9*b29e1426SEnji Cooper * notice, this list of conditions and the following disclaimer. 10*b29e1426SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright 11*b29e1426SEnji Cooper * notice, this list of conditions and the following disclaimer in the 12*b29e1426SEnji Cooper * documentation and/or other materials provided with the distribution. 13*b29e1426SEnji Cooper * 14*b29e1426SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*b29e1426SEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*b29e1426SEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*b29e1426SEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*b29e1426SEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*b29e1426SEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*b29e1426SEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*b29e1426SEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*b29e1426SEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*b29e1426SEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*b29e1426SEnji Cooper * SUCH DAMAGE. 25*b29e1426SEnji Cooper */ 26*b29e1426SEnji Cooper 27*b29e1426SEnji Cooper #include <sys/cdefs.h> 28*b29e1426SEnji Cooper __FBSDID("$FreeBSD$"); 29*b29e1426SEnji Cooper 30*b29e1426SEnji Cooper #include <sys/param.h> 31*b29e1426SEnji Cooper #include <sys/mman.h> 32*b29e1426SEnji Cooper #include <sys/socket.h> 33*b29e1426SEnji Cooper #include <sys/stat.h> 34*b29e1426SEnji Cooper #include <sys/sysctl.h> 35*b29e1426SEnji Cooper #include <sys/uio.h> 36*b29e1426SEnji Cooper #include <err.h> 37*b29e1426SEnji Cooper #include <errno.h> 38*b29e1426SEnji Cooper #include <fcntl.h> 39*b29e1426SEnji Cooper #include <netdb.h> 40*b29e1426SEnji Cooper #include <paths.h> 41*b29e1426SEnji Cooper #include <stdio.h> 42*b29e1426SEnji Cooper #include <stdlib.h> 43*b29e1426SEnji Cooper #include <string.h> 44*b29e1426SEnji Cooper #include <unistd.h> 45*b29e1426SEnji Cooper 46*b29e1426SEnji Cooper #include <atf-c.h> 47*b29e1426SEnji Cooper 48*b29e1426SEnji Cooper const char DETERMINISTIC_PATTERN[] = 49*b29e1426SEnji Cooper "The past is already gone, the future is not yet here. There's only one moment for you to live.\n"; 50*b29e1426SEnji Cooper 51*b29e1426SEnji Cooper #define SOURCE_FILE "source" 52*b29e1426SEnji Cooper #define DESTINATION_FILE "dest" 53*b29e1426SEnji Cooper 54*b29e1426SEnji Cooper #define PORTRANGE_FIRST "net.inet.ip.portrange.first" 55*b29e1426SEnji Cooper #define PORTRANGE_LAST "net.inet.ip.portrange.last" 56*b29e1426SEnji Cooper 57*b29e1426SEnji Cooper static int portrange_first, portrange_last; 58*b29e1426SEnji Cooper 59*b29e1426SEnji Cooper static int 60*b29e1426SEnji Cooper get_int_via_sysctlbyname(const char *oidname) 61*b29e1426SEnji Cooper { 62*b29e1426SEnji Cooper size_t oldlen; 63*b29e1426SEnji Cooper int int_value; 64*b29e1426SEnji Cooper 65*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(sysctlbyname(oidname, &int_value, &oldlen, NULL, 0), 66*b29e1426SEnji Cooper 0, "sysctlbyname(%s, ...) failed: %s", oidname, strerror(errno)); 67*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(sizeof(int_value), oldlen, "sanity check failed"); 68*b29e1426SEnji Cooper 69*b29e1426SEnji Cooper return (int_value); 70*b29e1426SEnji Cooper } 71*b29e1426SEnji Cooper 72*b29e1426SEnji Cooper static int 73*b29e1426SEnji Cooper generate_random_port(int seed) 74*b29e1426SEnji Cooper { 75*b29e1426SEnji Cooper int random_port; 76*b29e1426SEnji Cooper 77*b29e1426SEnji Cooper printf("Generating a random port with seed=%d\n", seed); 78*b29e1426SEnji Cooper if (portrange_first == 0) { 79*b29e1426SEnji Cooper portrange_first = get_int_via_sysctlbyname(PORTRANGE_FIRST); 80*b29e1426SEnji Cooper printf("Port range lower bound: %d\n", portrange_first); 81*b29e1426SEnji Cooper } 82*b29e1426SEnji Cooper 83*b29e1426SEnji Cooper if (portrange_last == 0) { 84*b29e1426SEnji Cooper portrange_last = get_int_via_sysctlbyname(PORTRANGE_LAST); 85*b29e1426SEnji Cooper printf("Port range upper bound: %d\n", portrange_last); 86*b29e1426SEnji Cooper } 87*b29e1426SEnji Cooper 88*b29e1426SEnji Cooper srand((unsigned)seed); 89*b29e1426SEnji Cooper 90*b29e1426SEnji Cooper random_port = rand() % (portrange_last - portrange_first) + 91*b29e1426SEnji Cooper portrange_first; 92*b29e1426SEnji Cooper 93*b29e1426SEnji Cooper printf("Random port generated: %d\n", random_port); 94*b29e1426SEnji Cooper return (random_port); 95*b29e1426SEnji Cooper } 96*b29e1426SEnji Cooper 97*b29e1426SEnji Cooper static void 98*b29e1426SEnji Cooper resolve_localhost(struct addrinfo **res, int domain, int type, int port) 99*b29e1426SEnji Cooper { 100*b29e1426SEnji Cooper char *serv; 101*b29e1426SEnji Cooper struct addrinfo hints; 102*b29e1426SEnji Cooper int error; 103*b29e1426SEnji Cooper 104*b29e1426SEnji Cooper ATF_REQUIRE_MSG(domain == AF_INET || domain == AF_INET6, 105*b29e1426SEnji Cooper "unhandled domain: %d", domain); 106*b29e1426SEnji Cooper 107*b29e1426SEnji Cooper ATF_REQUIRE_MSG(asprintf(&serv, "%d", port) >= 0, 108*b29e1426SEnji Cooper "asprintf failed: %s", strerror(errno)); 109*b29e1426SEnji Cooper 110*b29e1426SEnji Cooper memset(&hints, 0, sizeof(hints)); 111*b29e1426SEnji Cooper hints.ai_family = domain; 112*b29e1426SEnji Cooper hints.ai_flags = AI_ADDRCONFIG|AI_NUMERICSERV; 113*b29e1426SEnji Cooper hints.ai_socktype = type; 114*b29e1426SEnji Cooper 115*b29e1426SEnji Cooper error = getaddrinfo("localhost", serv, &hints, res); 116*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, 117*b29e1426SEnji Cooper "getaddrinfo failed: %s", gai_strerror(errno)); 118*b29e1426SEnji Cooper free(serv); 119*b29e1426SEnji Cooper } 120*b29e1426SEnji Cooper 121*b29e1426SEnji Cooper static int 122*b29e1426SEnji Cooper make_socket(int domain, int type, int protocol) 123*b29e1426SEnji Cooper { 124*b29e1426SEnji Cooper int sock; 125*b29e1426SEnji Cooper 126*b29e1426SEnji Cooper sock = socket(domain, type, protocol); 127*b29e1426SEnji Cooper ATF_REQUIRE_MSG(sock != -1, "socket(%d, %d, 0) failed: %s", 128*b29e1426SEnji Cooper domain, type, strerror(errno)); 129*b29e1426SEnji Cooper 130*b29e1426SEnji Cooper return (sock); 131*b29e1426SEnji Cooper } 132*b29e1426SEnji Cooper 133*b29e1426SEnji Cooper static int 134*b29e1426SEnji Cooper setup_client(int domain, int type, int port) 135*b29e1426SEnji Cooper { 136*b29e1426SEnji Cooper struct addrinfo *res; 137*b29e1426SEnji Cooper char host[NI_MAXHOST+1]; 138*b29e1426SEnji Cooper int error, sock; 139*b29e1426SEnji Cooper 140*b29e1426SEnji Cooper resolve_localhost(&res, domain, type, port); 141*b29e1426SEnji Cooper error = getnameinfo( 142*b29e1426SEnji Cooper (const struct sockaddr*)res->ai_addr, res->ai_addrlen, 143*b29e1426SEnji Cooper host, nitems(host) - 1, NULL, 0, NI_NUMERICHOST); 144*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, 145*b29e1426SEnji Cooper "getnameinfo failed: %s", gai_strerror(error)); 146*b29e1426SEnji Cooper printf( 147*b29e1426SEnji Cooper "Will try to connect to host='%s', address_family=%d, " 148*b29e1426SEnji Cooper "socket_type=%d\n", 149*b29e1426SEnji Cooper host, res->ai_family, res->ai_socktype); 150*b29e1426SEnji Cooper sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol); 151*b29e1426SEnji Cooper error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen); 152*b29e1426SEnji Cooper freeaddrinfo(res); 153*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, "connect failed: %s", strerror(errno)); 154*b29e1426SEnji Cooper return (sock); 155*b29e1426SEnji Cooper } 156*b29e1426SEnji Cooper 157*b29e1426SEnji Cooper /* 158*b29e1426SEnji Cooper * XXX: use linear probing to find a free port and eliminate `port` argument as 159*b29e1426SEnji Cooper * a [const] int (it will need to be a pointer so it can be passed back out of 160*b29e1426SEnji Cooper * the function and can influence which port `setup_client(..)` connects on. 161*b29e1426SEnji Cooper */ 162*b29e1426SEnji Cooper static int 163*b29e1426SEnji Cooper setup_server(int domain, int type, int port) 164*b29e1426SEnji Cooper { 165*b29e1426SEnji Cooper struct addrinfo *res; 166*b29e1426SEnji Cooper char host[NI_MAXHOST+1]; 167*b29e1426SEnji Cooper int error, sock; 168*b29e1426SEnji Cooper 169*b29e1426SEnji Cooper resolve_localhost(&res, domain, type, port); 170*b29e1426SEnji Cooper sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol); 171*b29e1426SEnji Cooper 172*b29e1426SEnji Cooper error = getnameinfo( 173*b29e1426SEnji Cooper (const struct sockaddr*)res->ai_addr, res->ai_addrlen, 174*b29e1426SEnji Cooper host, nitems(host) - 1, NULL, 0, NI_NUMERICHOST); 175*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, 176*b29e1426SEnji Cooper "getnameinfo failed: %s", gai_strerror(error)); 177*b29e1426SEnji Cooper printf( 178*b29e1426SEnji Cooper "Will try to bind socket to host='%s', address_family=%d, " 179*b29e1426SEnji Cooper "socket_type=%d\n", 180*b29e1426SEnji Cooper host, res->ai_family, res->ai_socktype); 181*b29e1426SEnji Cooper error = bind(sock, res->ai_addr, res->ai_addrlen); 182*b29e1426SEnji Cooper freeaddrinfo(res); 183*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno)); 184*b29e1426SEnji Cooper error = listen(sock, 1); 185*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(error, 0, "listen failed: %s", strerror(errno)); 186*b29e1426SEnji Cooper 187*b29e1426SEnji Cooper return (sock); 188*b29e1426SEnji Cooper } 189*b29e1426SEnji Cooper 190*b29e1426SEnji Cooper /* 191*b29e1426SEnji Cooper * This function is a helper routine for taking data being sent by `sendfile` via 192*b29e1426SEnji Cooper * `server_sock`, and pushing the received stream out to a file, denoted by 193*b29e1426SEnji Cooper * `dest_filename`. 194*b29e1426SEnji Cooper */ 195*b29e1426SEnji Cooper static void 196*b29e1426SEnji Cooper server_cat(const char *dest_filename, int server_sock, size_t len) 197*b29e1426SEnji Cooper { 198*b29e1426SEnji Cooper void *buffer; 199*b29e1426SEnji Cooper int recv_sock; 200*b29e1426SEnji Cooper ssize_t received_bytes; 201*b29e1426SEnji Cooper 202*b29e1426SEnji Cooper buffer = calloc(len + 1, sizeof(char)); 203*b29e1426SEnji Cooper if (buffer == NULL) 204*b29e1426SEnji Cooper err(1, "malloc failed"); 205*b29e1426SEnji Cooper 206*b29e1426SEnji Cooper recv_sock = accept(server_sock, NULL, 0); 207*b29e1426SEnji Cooper if (recv_sock == -1) 208*b29e1426SEnji Cooper err(1, "accept failed"); 209*b29e1426SEnji Cooper 210*b29e1426SEnji Cooper /* 211*b29e1426SEnji Cooper * XXX: this assumes the simplest case where all data is received in a 212*b29e1426SEnji Cooper * single recv(2) call. 213*b29e1426SEnji Cooper */ 214*b29e1426SEnji Cooper if (recv(recv_sock, buffer, len, 0) == -1) 215*b29e1426SEnji Cooper err(1, "recv failed"); 216*b29e1426SEnji Cooper 217*b29e1426SEnji Cooper atf_utils_create_file(dest_filename, "%s", buffer); 218*b29e1426SEnji Cooper 219*b29e1426SEnji Cooper /* 220*b29e1426SEnji Cooper * This recv(2) call helps ensure the amount of sent data is exactly 221*b29e1426SEnji Cooper * what was specified by `len`. 222*b29e1426SEnji Cooper */ 223*b29e1426SEnji Cooper received_bytes = recv(recv_sock, buffer, len, 0); 224*b29e1426SEnji Cooper switch (received_bytes) { 225*b29e1426SEnji Cooper case -1: 226*b29e1426SEnji Cooper err(1, "recv failed"); 227*b29e1426SEnji Cooper case 0: 228*b29e1426SEnji Cooper break; 229*b29e1426SEnji Cooper default: 230*b29e1426SEnji Cooper errx(1, "received unexpected data: %s", buffer); 231*b29e1426SEnji Cooper } 232*b29e1426SEnji Cooper 233*b29e1426SEnji Cooper (void)close(recv_sock); 234*b29e1426SEnji Cooper (void)close(server_sock); 235*b29e1426SEnji Cooper free(buffer); 236*b29e1426SEnji Cooper } 237*b29e1426SEnji Cooper 238*b29e1426SEnji Cooper static int 239*b29e1426SEnji Cooper setup_tcp_server(int domain, int port) 240*b29e1426SEnji Cooper { 241*b29e1426SEnji Cooper 242*b29e1426SEnji Cooper return (setup_server(domain, SOCK_STREAM, port)); 243*b29e1426SEnji Cooper } 244*b29e1426SEnji Cooper 245*b29e1426SEnji Cooper static int 246*b29e1426SEnji Cooper setup_tcp_client(int domain, int port) 247*b29e1426SEnji Cooper { 248*b29e1426SEnji Cooper 249*b29e1426SEnji Cooper return (setup_client(domain, SOCK_STREAM, port)); 250*b29e1426SEnji Cooper } 251*b29e1426SEnji Cooper 252*b29e1426SEnji Cooper static off_t 253*b29e1426SEnji Cooper file_size_from_fd(int fd) 254*b29e1426SEnji Cooper { 255*b29e1426SEnji Cooper struct stat st; 256*b29e1426SEnji Cooper 257*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, fstat(fd, &st), 258*b29e1426SEnji Cooper "fstat failed: %s", strerror(errno)); 259*b29e1426SEnji Cooper 260*b29e1426SEnji Cooper return (st.st_size); 261*b29e1426SEnji Cooper } 262*b29e1426SEnji Cooper 263*b29e1426SEnji Cooper /* 264*b29e1426SEnji Cooper * NB: `nbytes` == 0 has special connotations given the sendfile(2) API 265*b29e1426SEnji Cooper * contract. In short, "send the whole file" (paraphrased). 266*b29e1426SEnji Cooper */ 267*b29e1426SEnji Cooper static void 268*b29e1426SEnji Cooper verify_source_and_dest(const char* dest_filename, int src_fd, off_t offset, 269*b29e1426SEnji Cooper size_t nbytes) 270*b29e1426SEnji Cooper { 271*b29e1426SEnji Cooper void *dest_pointer, *src_pointer; 272*b29e1426SEnji Cooper off_t dest_file_size, src_file_size; 273*b29e1426SEnji Cooper size_t length; 274*b29e1426SEnji Cooper int dest_fd; 275*b29e1426SEnji Cooper 276*b29e1426SEnji Cooper atf_utils_cat_file(dest_filename, "dest_file: "); 277*b29e1426SEnji Cooper 278*b29e1426SEnji Cooper dest_fd = open(dest_filename, O_RDONLY); 279*b29e1426SEnji Cooper ATF_REQUIRE_MSG(dest_fd != -1, "open failed"); 280*b29e1426SEnji Cooper 281*b29e1426SEnji Cooper dest_file_size = file_size_from_fd(dest_fd); 282*b29e1426SEnji Cooper src_file_size = file_size_from_fd(src_fd); 283*b29e1426SEnji Cooper 284*b29e1426SEnji Cooper /* 285*b29e1426SEnji Cooper * Per sendfile(2), "send the whole file" (paraphrased). This means 286*b29e1426SEnji Cooper * that we need to grab the file size, as passing in length = 0 with 287*b29e1426SEnji Cooper * mmap(2) will result in a failure with EINVAL (length = 0 is invalid). 288*b29e1426SEnji Cooper */ 289*b29e1426SEnji Cooper length = (nbytes == 0) ? (size_t)(src_file_size - offset) : nbytes; 290*b29e1426SEnji Cooper 291*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(dest_file_size, length, 292*b29e1426SEnji Cooper "number of bytes written out to %s (%ju) doesn't match the " 293*b29e1426SEnji Cooper "expected number of bytes (%ju)", dest_filename, dest_file_size, 294*b29e1426SEnji Cooper length); 295*b29e1426SEnji Cooper 296*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, lseek(src_fd, offset, SEEK_SET), 297*b29e1426SEnji Cooper "lseek failed: %s", strerror(errno)); 298*b29e1426SEnji Cooper 299*b29e1426SEnji Cooper dest_pointer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, dest_fd, 0); 300*b29e1426SEnji Cooper ATF_REQUIRE_MSG(dest_pointer != MAP_FAILED, "mmap failed: %s", 301*b29e1426SEnji Cooper strerror(errno)); 302*b29e1426SEnji Cooper 303*b29e1426SEnji Cooper printf("Will mmap in the source file from offset=%jd to length=%zu\n", 304*b29e1426SEnji Cooper offset, length); 305*b29e1426SEnji Cooper 306*b29e1426SEnji Cooper src_pointer = mmap(NULL, length, PROT_READ, MAP_PRIVATE, src_fd, offset); 307*b29e1426SEnji Cooper ATF_REQUIRE_MSG(src_pointer != MAP_FAILED, "mmap failed: %s", 308*b29e1426SEnji Cooper strerror(errno)); 309*b29e1426SEnji Cooper 310*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, memcmp(src_pointer, dest_pointer, length), 311*b29e1426SEnji Cooper "Contents of source and destination do not match. '%s' != '%s'", 312*b29e1426SEnji Cooper src_pointer, dest_pointer); 313*b29e1426SEnji Cooper 314*b29e1426SEnji Cooper (void)munmap(src_pointer, length); 315*b29e1426SEnji Cooper (void)munmap(dest_pointer, length); 316*b29e1426SEnji Cooper (void)close(dest_fd); 317*b29e1426SEnji Cooper } 318*b29e1426SEnji Cooper 319*b29e1426SEnji Cooper static void 320*b29e1426SEnji Cooper fd_positive_file_test(int domain) 321*b29e1426SEnji Cooper { 322*b29e1426SEnji Cooper off_t offset; 323*b29e1426SEnji Cooper size_t nbytes, pattern_size; 324*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 325*b29e1426SEnji Cooper pid_t server_pid; 326*b29e1426SEnji Cooper 327*b29e1426SEnji Cooper pattern_size = strlen(DETERMINISTIC_PATTERN); 328*b29e1426SEnji Cooper 329*b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 330*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 331*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 332*b29e1426SEnji Cooper 333*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 334*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 335*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 336*b29e1426SEnji Cooper 337*b29e1426SEnji Cooper server_pid = atf_utils_fork(); 338*b29e1426SEnji Cooper if (server_pid == 0) { 339*b29e1426SEnji Cooper (void)close(client_sock); 340*b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, pattern_size); 341*b29e1426SEnji Cooper _exit(0); 342*b29e1426SEnji Cooper } else 343*b29e1426SEnji Cooper (void)close(server_sock); 344*b29e1426SEnji Cooper 345*b29e1426SEnji Cooper nbytes = 0; 346*b29e1426SEnji Cooper offset = 0; 347*b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, NULL, NULL, 348*b29e1426SEnji Cooper SF_FLAGS(0, 0)); 349*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, error, "sendfile failed: %s", strerror(errno)); 350*b29e1426SEnji Cooper (void)close(client_sock); 351*b29e1426SEnji Cooper 352*b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 353*b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd, offset, nbytes); 354*b29e1426SEnji Cooper 355*b29e1426SEnji Cooper (void)close(fd); 356*b29e1426SEnji Cooper } 357*b29e1426SEnji Cooper 358*b29e1426SEnji Cooper ATF_TC(fd_positive_file_v4); 359*b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_file_v4, tc) 360*b29e1426SEnji Cooper { 361*b29e1426SEnji Cooper 362*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 363*b29e1426SEnji Cooper "Verify regular file as file descriptor support (IPv4)"); 364*b29e1426SEnji Cooper } 365*b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_file_v4, tc) 366*b29e1426SEnji Cooper { 367*b29e1426SEnji Cooper 368*b29e1426SEnji Cooper fd_positive_file_test(AF_INET); 369*b29e1426SEnji Cooper } 370*b29e1426SEnji Cooper 371*b29e1426SEnji Cooper ATF_TC(fd_positive_file_v6); 372*b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_file_v6, tc) 373*b29e1426SEnji Cooper { 374*b29e1426SEnji Cooper 375*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 376*b29e1426SEnji Cooper "Verify regular file as file descriptor support (IPv6)"); 377*b29e1426SEnji Cooper } 378*b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_file_v6, tc) 379*b29e1426SEnji Cooper { 380*b29e1426SEnji Cooper 381*b29e1426SEnji Cooper fd_positive_file_test(AF_INET6); 382*b29e1426SEnji Cooper } 383*b29e1426SEnji Cooper 384*b29e1426SEnji Cooper static void 385*b29e1426SEnji Cooper fd_positive_shm_test(int domain) 386*b29e1426SEnji Cooper { 387*b29e1426SEnji Cooper void *shm_pointer; 388*b29e1426SEnji Cooper off_t offset; 389*b29e1426SEnji Cooper size_t nbytes, pattern_size; 390*b29e1426SEnji Cooper pid_t server_pid; 391*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 392*b29e1426SEnji Cooper 393*b29e1426SEnji Cooper pattern_size = strlen(DETERMINISTIC_PATTERN); 394*b29e1426SEnji Cooper 395*b29e1426SEnji Cooper printf("pattern size: %zu\n", pattern_size); 396*b29e1426SEnji Cooper 397*b29e1426SEnji Cooper fd = shm_open(SHM_ANON, O_RDWR|O_CREAT, 0600); 398*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "shm_open failed: %s", strerror(errno)); 399*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, ftruncate(fd, pattern_size), 400*b29e1426SEnji Cooper "ftruncate failed: %s", strerror(errno)); 401*b29e1426SEnji Cooper shm_pointer = mmap(NULL, pattern_size, PROT_READ|PROT_WRITE, 402*b29e1426SEnji Cooper MAP_SHARED, fd, 0); 403*b29e1426SEnji Cooper ATF_REQUIRE_MSG(shm_pointer != MAP_FAILED, 404*b29e1426SEnji Cooper "mmap failed: %s", strerror(errno)); 405*b29e1426SEnji Cooper memcpy(shm_pointer, DETERMINISTIC_PATTERN, pattern_size); 406*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, 407*b29e1426SEnji Cooper memcmp(shm_pointer, DETERMINISTIC_PATTERN, pattern_size), 408*b29e1426SEnji Cooper "memcmp showed data mismatch: '%s' != '%s'", 409*b29e1426SEnji Cooper DETERMINISTIC_PATTERN, shm_pointer); 410*b29e1426SEnji Cooper 411*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 412*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 413*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 414*b29e1426SEnji Cooper 415*b29e1426SEnji Cooper server_pid = atf_utils_fork(); 416*b29e1426SEnji Cooper if (server_pid == 0) { 417*b29e1426SEnji Cooper (void)close(client_sock); 418*b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, pattern_size); 419*b29e1426SEnji Cooper _exit(0); 420*b29e1426SEnji Cooper } else 421*b29e1426SEnji Cooper (void)close(server_sock); 422*b29e1426SEnji Cooper 423*b29e1426SEnji Cooper nbytes = 0; 424*b29e1426SEnji Cooper offset = 0; 425*b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, NULL, NULL, 426*b29e1426SEnji Cooper SF_FLAGS(0, 0)); 427*b29e1426SEnji Cooper ATF_REQUIRE_EQ_MSG(0, error, "sendfile failed: %s", strerror(errno)); 428*b29e1426SEnji Cooper (void)close(client_sock); 429*b29e1426SEnji Cooper 430*b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 431*b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd, offset, nbytes); 432*b29e1426SEnji Cooper 433*b29e1426SEnji Cooper (void)munmap(shm_pointer, sizeof(DETERMINISTIC_PATTERN)); 434*b29e1426SEnji Cooper (void)close(fd); 435*b29e1426SEnji Cooper } 436*b29e1426SEnji Cooper 437*b29e1426SEnji Cooper ATF_TC(fd_positive_shm_v4); 438*b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_shm_v4, tc) 439*b29e1426SEnji Cooper { 440*b29e1426SEnji Cooper 441*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 442*b29e1426SEnji Cooper "Verify shared memory as file descriptor support (IPv4)"); 443*b29e1426SEnji Cooper } 444*b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_shm_v4, tc) 445*b29e1426SEnji Cooper { 446*b29e1426SEnji Cooper 447*b29e1426SEnji Cooper fd_positive_shm_test(AF_INET); 448*b29e1426SEnji Cooper } 449*b29e1426SEnji Cooper 450*b29e1426SEnji Cooper ATF_TC(fd_positive_shm_v6); 451*b29e1426SEnji Cooper ATF_TC_HEAD(fd_positive_shm_v6, tc) 452*b29e1426SEnji Cooper { 453*b29e1426SEnji Cooper 454*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 455*b29e1426SEnji Cooper "Verify shared memory as file descriptor support (IPv6))"); 456*b29e1426SEnji Cooper } 457*b29e1426SEnji Cooper ATF_TC_BODY(fd_positive_shm_v6, tc) 458*b29e1426SEnji Cooper { 459*b29e1426SEnji Cooper 460*b29e1426SEnji Cooper fd_positive_shm_test(AF_INET6); 461*b29e1426SEnji Cooper } 462*b29e1426SEnji Cooper 463*b29e1426SEnji Cooper static void 464*b29e1426SEnji Cooper fd_negative_bad_fd_test(int domain) 465*b29e1426SEnji Cooper { 466*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 467*b29e1426SEnji Cooper 468*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 469*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 470*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 471*b29e1426SEnji Cooper 472*b29e1426SEnji Cooper fd = -1; 473*b29e1426SEnji Cooper 474*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 475*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, error == -1); 476*b29e1426SEnji Cooper 477*b29e1426SEnji Cooper (void)close(client_sock); 478*b29e1426SEnji Cooper (void)close(server_sock); 479*b29e1426SEnji Cooper } 480*b29e1426SEnji Cooper 481*b29e1426SEnji Cooper ATF_TC(fd_negative_bad_fd_v4); 482*b29e1426SEnji Cooper ATF_TC_HEAD(fd_negative_bad_fd_v4, tc) 483*b29e1426SEnji Cooper { 484*b29e1426SEnji Cooper 485*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 486*b29e1426SEnji Cooper "Verify bad file descriptor returns EBADF (IPv4)"); 487*b29e1426SEnji Cooper } 488*b29e1426SEnji Cooper ATF_TC_BODY(fd_negative_bad_fd_v4, tc) 489*b29e1426SEnji Cooper { 490*b29e1426SEnji Cooper 491*b29e1426SEnji Cooper fd_negative_bad_fd_test(AF_INET); 492*b29e1426SEnji Cooper } 493*b29e1426SEnji Cooper 494*b29e1426SEnji Cooper ATF_TC(fd_negative_bad_fd_v6); 495*b29e1426SEnji Cooper ATF_TC_HEAD(fd_negative_bad_fd_v6, tc) 496*b29e1426SEnji Cooper { 497*b29e1426SEnji Cooper 498*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 499*b29e1426SEnji Cooper "Verify bad file descriptor returns EBADF (IPv6)"); 500*b29e1426SEnji Cooper } 501*b29e1426SEnji Cooper ATF_TC_BODY(fd_negative_bad_fd_v6, tc) 502*b29e1426SEnji Cooper { 503*b29e1426SEnji Cooper 504*b29e1426SEnji Cooper fd_negative_bad_fd_test(AF_INET6); 505*b29e1426SEnji Cooper } 506*b29e1426SEnji Cooper 507*b29e1426SEnji Cooper static void 508*b29e1426SEnji Cooper flags_test(int domain) 509*b29e1426SEnji Cooper { 510*b29e1426SEnji Cooper off_t offset; 511*b29e1426SEnji Cooper size_t nbytes, pattern_size; 512*b29e1426SEnji Cooper int client_sock, error, fd, i, port, server_sock; 513*b29e1426SEnji Cooper pid_t server_pid; 514*b29e1426SEnji Cooper int16_t number_pages = 10; 515*b29e1426SEnji Cooper 516*b29e1426SEnji Cooper pattern_size = strlen(DETERMINISTIC_PATTERN); 517*b29e1426SEnji Cooper 518*b29e1426SEnji Cooper struct testcase { 519*b29e1426SEnji Cooper int16_t readahead_pages, flags; 520*b29e1426SEnji Cooper } testcases[] = { 521*b29e1426SEnji Cooper /* This is covered in `:fd_positive_file` */ 522*b29e1426SEnji Cooper #if 0 523*b29e1426SEnji Cooper { 524*b29e1426SEnji Cooper .readahead_pages = 0, 525*b29e1426SEnji Cooper .flags = 0 526*b29e1426SEnji Cooper }, 527*b29e1426SEnji Cooper #endif 528*b29e1426SEnji Cooper { 529*b29e1426SEnji Cooper .readahead_pages = 0, 530*b29e1426SEnji Cooper .flags = SF_NOCACHE 531*b29e1426SEnji Cooper }, 532*b29e1426SEnji Cooper #ifdef SF_USER_READAHEAD 533*b29e1426SEnji Cooper { 534*b29e1426SEnji Cooper .readahead_pages = 0, 535*b29e1426SEnji Cooper .flags = SF_NOCACHE|SF_USER_READAHEAD 536*b29e1426SEnji Cooper }, 537*b29e1426SEnji Cooper { 538*b29e1426SEnji Cooper .readahead_pages = 0, 539*b29e1426SEnji Cooper .flags = SF_USER_READAHEAD 540*b29e1426SEnji Cooper }, 541*b29e1426SEnji Cooper #endif 542*b29e1426SEnji Cooper { 543*b29e1426SEnji Cooper .readahead_pages = number_pages, 544*b29e1426SEnji Cooper .flags = 0 545*b29e1426SEnji Cooper }, 546*b29e1426SEnji Cooper { 547*b29e1426SEnji Cooper .readahead_pages = number_pages, 548*b29e1426SEnji Cooper .flags = SF_NOCACHE 549*b29e1426SEnji Cooper }, 550*b29e1426SEnji Cooper #ifdef SF_USER_READAHEAD 551*b29e1426SEnji Cooper { 552*b29e1426SEnji Cooper .readahead_pages = number_pages, 553*b29e1426SEnji Cooper .flags = SF_NOCACHE|SF_USER_READAHEAD 554*b29e1426SEnji Cooper }, 555*b29e1426SEnji Cooper #endif 556*b29e1426SEnji Cooper { 557*b29e1426SEnji Cooper .readahead_pages = number_pages, 558*b29e1426SEnji Cooper .flags = SF_NOCACHE 559*b29e1426SEnji Cooper }, 560*b29e1426SEnji Cooper { 561*b29e1426SEnji Cooper .readahead_pages = number_pages, 562*b29e1426SEnji Cooper .flags = SF_NODISKIO 563*b29e1426SEnji Cooper } 564*b29e1426SEnji Cooper }; 565*b29e1426SEnji Cooper 566*b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 567*b29e1426SEnji Cooper for (i = 0; i < nitems(testcases); i++) { 568*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 569*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 570*b29e1426SEnji Cooper 571*b29e1426SEnji Cooper port = generate_random_port(i * __LINE__ + domain); 572*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 573*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 574*b29e1426SEnji Cooper 575*b29e1426SEnji Cooper server_pid = atf_utils_fork(); 576*b29e1426SEnji Cooper if (server_pid == 0) { 577*b29e1426SEnji Cooper (void)close(client_sock); 578*b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, pattern_size); 579*b29e1426SEnji Cooper _exit(0); 580*b29e1426SEnji Cooper } else 581*b29e1426SEnji Cooper (void)close(server_sock); 582*b29e1426SEnji Cooper 583*b29e1426SEnji Cooper nbytes = 0; 584*b29e1426SEnji Cooper offset = 0; 585*b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, NULL, NULL, 586*b29e1426SEnji Cooper SF_FLAGS(testcases[i].readahead_pages, testcases[i].flags)); 587*b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(error, 0, "sendfile testcase #%d failed: %s", 588*b29e1426SEnji Cooper i, strerror(errno)); 589*b29e1426SEnji Cooper (void)close(client_sock); 590*b29e1426SEnji Cooper 591*b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 592*b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd, offset, nbytes); 593*b29e1426SEnji Cooper 594*b29e1426SEnji Cooper (void)close(fd); 595*b29e1426SEnji Cooper } 596*b29e1426SEnji Cooper } 597*b29e1426SEnji Cooper 598*b29e1426SEnji Cooper ATF_TC(flags_v4); 599*b29e1426SEnji Cooper ATF_TC_HEAD(flags_v4, tc) 600*b29e1426SEnji Cooper { 601*b29e1426SEnji Cooper 602*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", "Verify flags functionality (IPv4)"); 603*b29e1426SEnji Cooper } 604*b29e1426SEnji Cooper ATF_TC_BODY(flags_v4, tc) 605*b29e1426SEnji Cooper { 606*b29e1426SEnji Cooper 607*b29e1426SEnji Cooper flags_test(AF_INET); 608*b29e1426SEnji Cooper } 609*b29e1426SEnji Cooper 610*b29e1426SEnji Cooper ATF_TC(flags_v6); 611*b29e1426SEnji Cooper ATF_TC_HEAD(flags_v6, tc) 612*b29e1426SEnji Cooper { 613*b29e1426SEnji Cooper 614*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", "Verify flags functionality (IPv6)"); 615*b29e1426SEnji Cooper } 616*b29e1426SEnji Cooper ATF_TC_BODY(flags_v6, tc) 617*b29e1426SEnji Cooper { 618*b29e1426SEnji Cooper 619*b29e1426SEnji Cooper flags_test(AF_INET6); 620*b29e1426SEnji Cooper } 621*b29e1426SEnji Cooper 622*b29e1426SEnji Cooper static void 623*b29e1426SEnji Cooper hdtr_positive_test(int domain) 624*b29e1426SEnji Cooper { 625*b29e1426SEnji Cooper struct iovec headers[1], trailers[1]; 626*b29e1426SEnji Cooper struct testcase { 627*b29e1426SEnji Cooper bool include_headers, include_trailers; 628*b29e1426SEnji Cooper } testcases[] = { 629*b29e1426SEnji Cooper /* This is covered in `:fd_positive_file` */ 630*b29e1426SEnji Cooper #if 0 631*b29e1426SEnji Cooper { 632*b29e1426SEnji Cooper .include_headers = false, 633*b29e1426SEnji Cooper .include_trailers = false 634*b29e1426SEnji Cooper }, 635*b29e1426SEnji Cooper #endif 636*b29e1426SEnji Cooper { 637*b29e1426SEnji Cooper .include_headers = true, 638*b29e1426SEnji Cooper .include_trailers = false 639*b29e1426SEnji Cooper }, 640*b29e1426SEnji Cooper { 641*b29e1426SEnji Cooper .include_headers = false, 642*b29e1426SEnji Cooper .include_trailers = true 643*b29e1426SEnji Cooper }, 644*b29e1426SEnji Cooper { 645*b29e1426SEnji Cooper .include_headers = true, 646*b29e1426SEnji Cooper .include_trailers = true 647*b29e1426SEnji Cooper } 648*b29e1426SEnji Cooper }; 649*b29e1426SEnji Cooper off_t offset; 650*b29e1426SEnji Cooper size_t nbytes; 651*b29e1426SEnji Cooper int client_sock, error, fd, fd2, i, port, rc, server_sock; 652*b29e1426SEnji Cooper pid_t server_pid; 653*b29e1426SEnji Cooper 654*b29e1426SEnji Cooper headers[0].iov_base = "This is a header"; 655*b29e1426SEnji Cooper headers[0].iov_len = strlen(headers[0].iov_base); 656*b29e1426SEnji Cooper trailers[0].iov_base = "This is a trailer"; 657*b29e1426SEnji Cooper trailers[0].iov_len = strlen(trailers[0].iov_base); 658*b29e1426SEnji Cooper offset = 0; 659*b29e1426SEnji Cooper nbytes = 0; 660*b29e1426SEnji Cooper 661*b29e1426SEnji Cooper atf_tc_expect_fail( 662*b29e1426SEnji Cooper "The header/trailer testcases fail today with a data mismatch; " 663*b29e1426SEnji Cooper "bug # 234809"); 664*b29e1426SEnji Cooper 665*b29e1426SEnji Cooper for (i = 0; i < nitems(testcases); i++) { 666*b29e1426SEnji Cooper struct sf_hdtr hdtr; 667*b29e1426SEnji Cooper char *pattern; 668*b29e1426SEnji Cooper 669*b29e1426SEnji Cooper if (testcases[i].include_headers) { 670*b29e1426SEnji Cooper hdtr.headers = headers; 671*b29e1426SEnji Cooper hdtr.hdr_cnt = nitems(headers); 672*b29e1426SEnji Cooper } else { 673*b29e1426SEnji Cooper hdtr.headers = NULL; 674*b29e1426SEnji Cooper hdtr.hdr_cnt = 0; 675*b29e1426SEnji Cooper } 676*b29e1426SEnji Cooper 677*b29e1426SEnji Cooper if (testcases[i].include_trailers) { 678*b29e1426SEnji Cooper hdtr.trailers = trailers; 679*b29e1426SEnji Cooper hdtr.trl_cnt = nitems(trailers); 680*b29e1426SEnji Cooper } else { 681*b29e1426SEnji Cooper hdtr.trailers = NULL; 682*b29e1426SEnji Cooper hdtr.trl_cnt = 0; 683*b29e1426SEnji Cooper } 684*b29e1426SEnji Cooper 685*b29e1426SEnji Cooper port = generate_random_port(i * __LINE__ + domain); 686*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 687*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 688*b29e1426SEnji Cooper 689*b29e1426SEnji Cooper rc = asprintf(&pattern, "%s%s%s", 690*b29e1426SEnji Cooper testcases[i].include_headers ? headers[0].iov_base : "", 691*b29e1426SEnji Cooper DETERMINISTIC_PATTERN, 692*b29e1426SEnji Cooper testcases[i].include_trailers ? trailers[0].iov_base : ""); 693*b29e1426SEnji Cooper ATF_REQUIRE_MSG(rc != -1, "asprintf failed: %s", strerror(errno)); 694*b29e1426SEnji Cooper 695*b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE ".full", "%s", pattern); 696*b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 697*b29e1426SEnji Cooper 698*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 699*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 700*b29e1426SEnji Cooper 701*b29e1426SEnji Cooper fd2 = open(SOURCE_FILE ".full", O_RDONLY); 702*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd2 != -1, "open failed: %s", strerror(errno)); 703*b29e1426SEnji Cooper 704*b29e1426SEnji Cooper server_pid = atf_utils_fork(); 705*b29e1426SEnji Cooper if (server_pid == 0) { 706*b29e1426SEnji Cooper (void)close(client_sock); 707*b29e1426SEnji Cooper server_cat(DESTINATION_FILE, server_sock, 708*b29e1426SEnji Cooper strlen(pattern)); 709*b29e1426SEnji Cooper _exit(0); 710*b29e1426SEnji Cooper } else 711*b29e1426SEnji Cooper (void)close(server_sock); 712*b29e1426SEnji Cooper 713*b29e1426SEnji Cooper error = sendfile(fd, client_sock, offset, nbytes, &hdtr, 714*b29e1426SEnji Cooper NULL, SF_FLAGS(0, 0)); 715*b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(error, 0, "sendfile testcase #%d failed: %s", 716*b29e1426SEnji Cooper i, strerror(errno)); 717*b29e1426SEnji Cooper (void)close(client_sock); 718*b29e1426SEnji Cooper 719*b29e1426SEnji Cooper atf_utils_wait(server_pid, 0, "", ""); 720*b29e1426SEnji Cooper verify_source_and_dest(DESTINATION_FILE, fd2, offset, nbytes); 721*b29e1426SEnji Cooper 722*b29e1426SEnji Cooper (void)close(fd); 723*b29e1426SEnji Cooper (void)close(fd2); 724*b29e1426SEnji Cooper free(pattern); 725*b29e1426SEnji Cooper pattern = NULL; 726*b29e1426SEnji Cooper } 727*b29e1426SEnji Cooper } 728*b29e1426SEnji Cooper 729*b29e1426SEnji Cooper ATF_TC(hdtr_positive_v4); 730*b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_positive_v4, tc) 731*b29e1426SEnji Cooper { 732*b29e1426SEnji Cooper 733*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 734*b29e1426SEnji Cooper "Verify positive hdtr functionality (IPv4)"); 735*b29e1426SEnji Cooper } 736*b29e1426SEnji Cooper ATF_TC_BODY(hdtr_positive_v4, tc) 737*b29e1426SEnji Cooper { 738*b29e1426SEnji Cooper 739*b29e1426SEnji Cooper hdtr_positive_test(AF_INET); 740*b29e1426SEnji Cooper } 741*b29e1426SEnji Cooper 742*b29e1426SEnji Cooper ATF_TC(hdtr_positive_v6); 743*b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_positive_v6, tc) 744*b29e1426SEnji Cooper { 745*b29e1426SEnji Cooper 746*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 747*b29e1426SEnji Cooper "Verify positive hdtr functionality (IPv6)"); 748*b29e1426SEnji Cooper } 749*b29e1426SEnji Cooper ATF_TC_BODY(hdtr_positive_v6, tc) 750*b29e1426SEnji Cooper { 751*b29e1426SEnji Cooper 752*b29e1426SEnji Cooper hdtr_positive_test(AF_INET); 753*b29e1426SEnji Cooper } 754*b29e1426SEnji Cooper 755*b29e1426SEnji Cooper static void 756*b29e1426SEnji Cooper hdtr_negative_bad_pointers_test(int domain) 757*b29e1426SEnji Cooper { 758*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 759*b29e1426SEnji Cooper struct sf_hdtr *hdtr1, hdtr2, hdtr3; 760*b29e1426SEnji Cooper 761*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 762*b29e1426SEnji Cooper 763*b29e1426SEnji Cooper hdtr1 = (struct sf_hdtr*)-1; 764*b29e1426SEnji Cooper 765*b29e1426SEnji Cooper memset(&hdtr2, 0, sizeof(hdtr2)); 766*b29e1426SEnji Cooper hdtr2.hdr_cnt = 1; 767*b29e1426SEnji Cooper hdtr2.headers = (struct iovec*)-1; 768*b29e1426SEnji Cooper 769*b29e1426SEnji Cooper memset(&hdtr3, 0, sizeof(hdtr3)); 770*b29e1426SEnji Cooper hdtr3.trl_cnt = 1; 771*b29e1426SEnji Cooper hdtr3.trailers = (struct iovec*)-1; 772*b29e1426SEnji Cooper 773*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 774*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 775*b29e1426SEnji Cooper 776*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 777*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 778*b29e1426SEnji Cooper 779*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, hdtr1, NULL, SF_FLAGS(0, 0)); 780*b29e1426SEnji Cooper ATF_CHECK_ERRNO(EFAULT, error == -1); 781*b29e1426SEnji Cooper 782*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, &hdtr2, NULL, SF_FLAGS(0, 0)); 783*b29e1426SEnji Cooper ATF_CHECK_ERRNO(EFAULT, error == -1); 784*b29e1426SEnji Cooper 785*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, &hdtr3, NULL, SF_FLAGS(0, 0)); 786*b29e1426SEnji Cooper ATF_CHECK_ERRNO(EFAULT, error == -1); 787*b29e1426SEnji Cooper 788*b29e1426SEnji Cooper (void)close(fd); 789*b29e1426SEnji Cooper (void)close(client_sock); 790*b29e1426SEnji Cooper (void)close(server_sock); 791*b29e1426SEnji Cooper } 792*b29e1426SEnji Cooper 793*b29e1426SEnji Cooper ATF_TC(hdtr_negative_bad_pointers_v4); 794*b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_negative_bad_pointers_v4, tc) 795*b29e1426SEnji Cooper { 796*b29e1426SEnji Cooper 797*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 798*b29e1426SEnji Cooper "Verify that bad pointers for hdtr storage result in EFAULT (IPv4)"); 799*b29e1426SEnji Cooper } 800*b29e1426SEnji Cooper ATF_TC_BODY(hdtr_negative_bad_pointers_v4, tc) 801*b29e1426SEnji Cooper { 802*b29e1426SEnji Cooper 803*b29e1426SEnji Cooper hdtr_negative_bad_pointers_test(AF_INET); 804*b29e1426SEnji Cooper } 805*b29e1426SEnji Cooper 806*b29e1426SEnji Cooper ATF_TC(hdtr_negative_bad_pointers_v6); 807*b29e1426SEnji Cooper ATF_TC_HEAD(hdtr_negative_bad_pointers_v6, tc) 808*b29e1426SEnji Cooper { 809*b29e1426SEnji Cooper 810*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 811*b29e1426SEnji Cooper "Verify that bad pointers for hdtr storage result in EFAULT (IPv6)"); 812*b29e1426SEnji Cooper } 813*b29e1426SEnji Cooper ATF_TC_BODY(hdtr_negative_bad_pointers_v6, tc) 814*b29e1426SEnji Cooper { 815*b29e1426SEnji Cooper 816*b29e1426SEnji Cooper hdtr_negative_bad_pointers_test(AF_INET6); 817*b29e1426SEnji Cooper } 818*b29e1426SEnji Cooper 819*b29e1426SEnji Cooper static void 820*b29e1426SEnji Cooper offset_negative_value_less_than_zero_test(int domain) 821*b29e1426SEnji Cooper { 822*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 823*b29e1426SEnji Cooper 824*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 825*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 826*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 827*b29e1426SEnji Cooper 828*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 829*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 830*b29e1426SEnji Cooper 831*b29e1426SEnji Cooper error = sendfile(fd, client_sock, -1, 0, NULL, NULL, SF_FLAGS(0, 0)); 832*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EINVAL, error == -1); 833*b29e1426SEnji Cooper 834*b29e1426SEnji Cooper (void)close(fd); 835*b29e1426SEnji Cooper (void)close(client_sock); 836*b29e1426SEnji Cooper (void)close(server_sock); 837*b29e1426SEnji Cooper } 838*b29e1426SEnji Cooper 839*b29e1426SEnji Cooper ATF_TC(offset_negative_value_less_than_zero_v4); 840*b29e1426SEnji Cooper ATF_TC_HEAD(offset_negative_value_less_than_zero_v4, tc) 841*b29e1426SEnji Cooper { 842*b29e1426SEnji Cooper 843*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 844*b29e1426SEnji Cooper "Verify that a negative offset results in EINVAL (IPv4)"); 845*b29e1426SEnji Cooper } 846*b29e1426SEnji Cooper ATF_TC_BODY(offset_negative_value_less_than_zero_v4, tc) 847*b29e1426SEnji Cooper { 848*b29e1426SEnji Cooper 849*b29e1426SEnji Cooper offset_negative_value_less_than_zero_test(AF_INET); 850*b29e1426SEnji Cooper } 851*b29e1426SEnji Cooper 852*b29e1426SEnji Cooper ATF_TC(offset_negative_value_less_than_zero_v6); 853*b29e1426SEnji Cooper ATF_TC_HEAD(offset_negative_value_less_than_zero_v6, tc) 854*b29e1426SEnji Cooper { 855*b29e1426SEnji Cooper 856*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 857*b29e1426SEnji Cooper "Verify that a negative offset results in EINVAL (IPv6)"); 858*b29e1426SEnji Cooper } 859*b29e1426SEnji Cooper ATF_TC_BODY(offset_negative_value_less_than_zero_v6, tc) 860*b29e1426SEnji Cooper { 861*b29e1426SEnji Cooper 862*b29e1426SEnji Cooper offset_negative_value_less_than_zero_test(AF_INET6); 863*b29e1426SEnji Cooper } 864*b29e1426SEnji Cooper 865*b29e1426SEnji Cooper static void 866*b29e1426SEnji Cooper sbytes_positive_test(int domain) 867*b29e1426SEnji Cooper { 868*b29e1426SEnji Cooper size_t pattern_size = strlen(DETERMINISTIC_PATTERN); 869*b29e1426SEnji Cooper off_t sbytes; 870*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 871*b29e1426SEnji Cooper 872*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 873*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 874*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 875*b29e1426SEnji Cooper 876*b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 877*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 878*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 879*b29e1426SEnji Cooper 880*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, &sbytes, SF_FLAGS(0, 0)); 881*b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(error, 0, "sendfile failed: %s", strerror(errno)); 882*b29e1426SEnji Cooper 883*b29e1426SEnji Cooper (void)close(fd); 884*b29e1426SEnji Cooper (void)close(client_sock); 885*b29e1426SEnji Cooper (void)close(server_sock); 886*b29e1426SEnji Cooper 887*b29e1426SEnji Cooper ATF_CHECK_EQ_MSG(pattern_size, sbytes, 888*b29e1426SEnji Cooper "the value returned by sbytes does not match the expected pattern " 889*b29e1426SEnji Cooper "size"); 890*b29e1426SEnji Cooper } 891*b29e1426SEnji Cooper 892*b29e1426SEnji Cooper ATF_TC(sbytes_positive_v4); 893*b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_positive_v4, tc) 894*b29e1426SEnji Cooper { 895*b29e1426SEnji Cooper 896*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 897*b29e1426SEnji Cooper "Verify positive `sbytes` functionality (IPv4)"); 898*b29e1426SEnji Cooper } 899*b29e1426SEnji Cooper ATF_TC_BODY(sbytes_positive_v4, tc) 900*b29e1426SEnji Cooper { 901*b29e1426SEnji Cooper 902*b29e1426SEnji Cooper sbytes_positive_test(AF_INET); 903*b29e1426SEnji Cooper } 904*b29e1426SEnji Cooper 905*b29e1426SEnji Cooper ATF_TC(sbytes_positive_v6); 906*b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_positive_v6, tc) 907*b29e1426SEnji Cooper { 908*b29e1426SEnji Cooper 909*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 910*b29e1426SEnji Cooper "Verify positive `sbytes` functionality (IPv6)"); 911*b29e1426SEnji Cooper } 912*b29e1426SEnji Cooper ATF_TC_BODY(sbytes_positive_v6, tc) 913*b29e1426SEnji Cooper { 914*b29e1426SEnji Cooper 915*b29e1426SEnji Cooper sbytes_positive_test(AF_INET6); 916*b29e1426SEnji Cooper } 917*b29e1426SEnji Cooper 918*b29e1426SEnji Cooper static void 919*b29e1426SEnji Cooper sbytes_negative_test(int domain) 920*b29e1426SEnji Cooper { 921*b29e1426SEnji Cooper off_t *sbytes_p = (off_t*)-1; 922*b29e1426SEnji Cooper int client_sock, error, fd, port, server_sock; 923*b29e1426SEnji Cooper 924*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 925*b29e1426SEnji Cooper server_sock = setup_tcp_server(domain, port); 926*b29e1426SEnji Cooper client_sock = setup_tcp_client(domain, port); 927*b29e1426SEnji Cooper 928*b29e1426SEnji Cooper atf_utils_create_file(SOURCE_FILE, "%s", DETERMINISTIC_PATTERN); 929*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_RDONLY); 930*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 931*b29e1426SEnji Cooper 932*b29e1426SEnji Cooper atf_tc_expect_fail( 933*b29e1426SEnji Cooper "bug 232210: EFAULT assert fails because copyout(9) call is not checked"); 934*b29e1426SEnji Cooper 935*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, sbytes_p, SF_FLAGS(0, 0)); 936*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EFAULT, error == -1); 937*b29e1426SEnji Cooper 938*b29e1426SEnji Cooper (void)close(fd); 939*b29e1426SEnji Cooper (void)close(client_sock); 940*b29e1426SEnji Cooper (void)close(server_sock); 941*b29e1426SEnji Cooper } 942*b29e1426SEnji Cooper 943*b29e1426SEnji Cooper ATF_TC(sbytes_negative_v4); 944*b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_negative_v4, tc) 945*b29e1426SEnji Cooper { 946*b29e1426SEnji Cooper 947*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 948*b29e1426SEnji Cooper "Verify negative `sbytes` functionality (IPv4)"); 949*b29e1426SEnji Cooper } 950*b29e1426SEnji Cooper ATF_TC_BODY(sbytes_negative_v4, tc) 951*b29e1426SEnji Cooper { 952*b29e1426SEnji Cooper 953*b29e1426SEnji Cooper sbytes_negative_test(AF_INET); 954*b29e1426SEnji Cooper } 955*b29e1426SEnji Cooper 956*b29e1426SEnji Cooper ATF_TC(sbytes_negative_v6); 957*b29e1426SEnji Cooper ATF_TC_HEAD(sbytes_negative_v6, tc) 958*b29e1426SEnji Cooper { 959*b29e1426SEnji Cooper 960*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 961*b29e1426SEnji Cooper "Verify negative `sbytes` functionality (IPv6)"); 962*b29e1426SEnji Cooper } 963*b29e1426SEnji Cooper ATF_TC_BODY(sbytes_negative_v6, tc) 964*b29e1426SEnji Cooper { 965*b29e1426SEnji Cooper 966*b29e1426SEnji Cooper sbytes_negative_test(AF_INET6); 967*b29e1426SEnji Cooper } 968*b29e1426SEnji Cooper 969*b29e1426SEnji Cooper static void 970*b29e1426SEnji Cooper s_negative_not_connected_socket_test(int domain) 971*b29e1426SEnji Cooper { 972*b29e1426SEnji Cooper int client_sock, error, fd, port; 973*b29e1426SEnji Cooper 974*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 975*b29e1426SEnji Cooper client_sock = setup_tcp_server(domain, port); 976*b29e1426SEnji Cooper 977*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 978*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 979*b29e1426SEnji Cooper 980*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 981*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(ENOTCONN, error == -1); 982*b29e1426SEnji Cooper 983*b29e1426SEnji Cooper (void)close(fd); 984*b29e1426SEnji Cooper (void)close(client_sock); 985*b29e1426SEnji Cooper } 986*b29e1426SEnji Cooper 987*b29e1426SEnji Cooper ATF_TC(s_negative_not_connected_socket_v4); 988*b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_connected_socket_v4, tc) 989*b29e1426SEnji Cooper { 990*b29e1426SEnji Cooper 991*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 992*b29e1426SEnji Cooper "Verify that a non-connected SOCK_STREAM socket results in ENOTCONN (IPv4)"); 993*b29e1426SEnji Cooper } 994*b29e1426SEnji Cooper 995*b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_connected_socket_v4, tc) 996*b29e1426SEnji Cooper { 997*b29e1426SEnji Cooper 998*b29e1426SEnji Cooper s_negative_not_connected_socket_test(AF_INET); 999*b29e1426SEnji Cooper } 1000*b29e1426SEnji Cooper 1001*b29e1426SEnji Cooper ATF_TC(s_negative_not_connected_socket_v6); 1002*b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_connected_socket_v6, tc) 1003*b29e1426SEnji Cooper { 1004*b29e1426SEnji Cooper 1005*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1006*b29e1426SEnji Cooper "Verify that a non-connected SOCK_STREAM socket results in ENOTCONN (IPv6)"); 1007*b29e1426SEnji Cooper } 1008*b29e1426SEnji Cooper 1009*b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_connected_socket_v6, tc) 1010*b29e1426SEnji Cooper { 1011*b29e1426SEnji Cooper 1012*b29e1426SEnji Cooper s_negative_not_connected_socket_test(AF_INET6); 1013*b29e1426SEnji Cooper } 1014*b29e1426SEnji Cooper 1015*b29e1426SEnji Cooper ATF_TC(s_negative_not_descriptor); 1016*b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_descriptor, tc) 1017*b29e1426SEnji Cooper { 1018*b29e1426SEnji Cooper 1019*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1020*b29e1426SEnji Cooper "Verify that an invalid file descriptor, e.g., -1, fails with EBADF"); 1021*b29e1426SEnji Cooper } 1022*b29e1426SEnji Cooper 1023*b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_descriptor, tc) 1024*b29e1426SEnji Cooper { 1025*b29e1426SEnji Cooper int client_sock, error, fd; 1026*b29e1426SEnji Cooper 1027*b29e1426SEnji Cooper client_sock = -1; 1028*b29e1426SEnji Cooper 1029*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 1030*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1031*b29e1426SEnji Cooper 1032*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 1033*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EBADF, error == -1); 1034*b29e1426SEnji Cooper 1035*b29e1426SEnji Cooper (void)close(fd); 1036*b29e1426SEnji Cooper } 1037*b29e1426SEnji Cooper 1038*b29e1426SEnji Cooper ATF_TC(s_negative_not_socket_file_descriptor); 1039*b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_not_socket_file_descriptor, tc) 1040*b29e1426SEnji Cooper { 1041*b29e1426SEnji Cooper 1042*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1043*b29e1426SEnji Cooper "Verify that a non-socket file descriptor fails with ENOTSOCK"); 1044*b29e1426SEnji Cooper } 1045*b29e1426SEnji Cooper 1046*b29e1426SEnji Cooper ATF_TC_BODY(s_negative_not_socket_file_descriptor, tc) 1047*b29e1426SEnji Cooper { 1048*b29e1426SEnji Cooper int client_sock, error, fd; 1049*b29e1426SEnji Cooper 1050*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 1051*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1052*b29e1426SEnji Cooper 1053*b29e1426SEnji Cooper client_sock = open(_PATH_DEVNULL, O_WRONLY); 1054*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1055*b29e1426SEnji Cooper 1056*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 1057*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(ENOTSOCK, error == -1); 1058*b29e1426SEnji Cooper 1059*b29e1426SEnji Cooper (void)close(fd); 1060*b29e1426SEnji Cooper (void)close(client_sock); 1061*b29e1426SEnji Cooper } 1062*b29e1426SEnji Cooper 1063*b29e1426SEnji Cooper static void 1064*b29e1426SEnji Cooper s_negative_udp_socket_test(int domain) 1065*b29e1426SEnji Cooper { 1066*b29e1426SEnji Cooper int client_sock, error, fd, port; 1067*b29e1426SEnji Cooper 1068*b29e1426SEnji Cooper port = generate_random_port(__LINE__ + domain); 1069*b29e1426SEnji Cooper client_sock = setup_client(domain, SOCK_DGRAM, port); 1070*b29e1426SEnji Cooper 1071*b29e1426SEnji Cooper fd = open(SOURCE_FILE, O_CREAT|O_RDWR); 1072*b29e1426SEnji Cooper ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno)); 1073*b29e1426SEnji Cooper 1074*b29e1426SEnji Cooper error = sendfile(fd, client_sock, 0, 0, NULL, NULL, SF_FLAGS(0, 0)); 1075*b29e1426SEnji Cooper ATF_REQUIRE_ERRNO(EINVAL, error == -1); 1076*b29e1426SEnji Cooper 1077*b29e1426SEnji Cooper (void)close(fd); 1078*b29e1426SEnji Cooper (void)close(client_sock); 1079*b29e1426SEnji Cooper } 1080*b29e1426SEnji Cooper 1081*b29e1426SEnji Cooper ATF_TC(s_negative_udp_socket_v4); 1082*b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_udp_socket_v4, tc) 1083*b29e1426SEnji Cooper { 1084*b29e1426SEnji Cooper 1085*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1086*b29e1426SEnji Cooper "Verify that a non-SOCK_STREAM type socket results in EINVAL (IPv4)"); 1087*b29e1426SEnji Cooper } 1088*b29e1426SEnji Cooper ATF_TC_BODY(s_negative_udp_socket_v4, tc) 1089*b29e1426SEnji Cooper { 1090*b29e1426SEnji Cooper 1091*b29e1426SEnji Cooper s_negative_udp_socket_test(AF_INET); 1092*b29e1426SEnji Cooper } 1093*b29e1426SEnji Cooper 1094*b29e1426SEnji Cooper ATF_TC(s_negative_udp_socket_v6); 1095*b29e1426SEnji Cooper ATF_TC_HEAD(s_negative_udp_socket_v6, tc) 1096*b29e1426SEnji Cooper { 1097*b29e1426SEnji Cooper 1098*b29e1426SEnji Cooper atf_tc_set_md_var(tc, "descr", 1099*b29e1426SEnji Cooper "Verify that a non-SOCK_STREAM type socket results in EINVAL (IPv6)"); 1100*b29e1426SEnji Cooper } 1101*b29e1426SEnji Cooper ATF_TC_BODY(s_negative_udp_socket_v6, tc) 1102*b29e1426SEnji Cooper { 1103*b29e1426SEnji Cooper 1104*b29e1426SEnji Cooper s_negative_udp_socket_test(AF_INET6); 1105*b29e1426SEnji Cooper } 1106*b29e1426SEnji Cooper 1107*b29e1426SEnji Cooper ATF_TP_ADD_TCS(tp) 1108*b29e1426SEnji Cooper { 1109*b29e1426SEnji Cooper 1110*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_file_v4); 1111*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_file_v6); 1112*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_shm_v4); 1113*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_positive_shm_v6); 1114*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_negative_bad_fd_v4); 1115*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, fd_negative_bad_fd_v6); 1116*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, flags_v4); 1117*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, flags_v6); 1118*b29e1426SEnji Cooper /* 1119*b29e1426SEnji Cooper * TODO: the negative case for SF_NODISKIO (returns EBUSY if file in 1120*b29e1426SEnji Cooper * use) is not covered yet. 1121*b29e1426SEnji Cooper * 1122*b29e1426SEnji Cooper * Need to lock a file in a subprocess in write mode, then try and 1123*b29e1426SEnji Cooper * send the data in read mode with sendfile. 1124*b29e1426SEnji Cooper * 1125*b29e1426SEnji Cooper * This should work with FFS/UFS, but there are no guarantees about 1126*b29e1426SEnji Cooper * other filesystem implementations of sendfile(2), e.g., ZFS. 1127*b29e1426SEnji Cooper */ 1128*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_positive_v4); 1129*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_positive_v6); 1130*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_negative_bad_pointers_v4); 1131*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, hdtr_negative_bad_pointers_v6); 1132*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, offset_negative_value_less_than_zero_v4); 1133*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, offset_negative_value_less_than_zero_v6); 1134*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_positive_v4); 1135*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_positive_v6); 1136*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_negative_v4); 1137*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, sbytes_negative_v6); 1138*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_connected_socket_v4); 1139*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_connected_socket_v6); 1140*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_descriptor); 1141*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_not_socket_file_descriptor); 1142*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_udp_socket_v4); 1143*b29e1426SEnji Cooper ATF_TP_ADD_TC(tp, s_negative_udp_socket_v6); 1144*b29e1426SEnji Cooper 1145*b29e1426SEnji Cooper return (atf_no_error()); 1146*b29e1426SEnji Cooper } 1147