1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 */ 25 26 /* 27 * Test helper to abort TCP connections to some server; 28 * either all of the, or those to a specified port. 29 */ 30 31 #include <sys/types.h> 32 #include <sys/socket.h> 33 #include <sys/sockio.h> 34 #include <sys/stropts.h> 35 36 #include <inet/tcp.h> 37 #include <arpa/inet.h> 38 #include <netinet/in.h> 39 #include <netdb.h> 40 41 #include <errno.h> 42 #include <fcntl.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 #include <zone.h> 48 49 /* 50 * Abort all connections to the passed address. 51 */ 52 static void 53 tcp_abort_connections(struct sockaddr *rsa) 54 { 55 tcp_ioc_abort_conn_t conn; 56 struct strioctl ioc; 57 struct sockaddr *lsa; 58 int fd; 59 60 (void) memset(&conn, 0, sizeof (conn)); 61 lsa = (void *)&conn.ac_local; 62 lsa->sa_family = rsa->sa_family; 63 (void) memcpy(&conn.ac_remote, rsa, sizeof (*rsa)); 64 conn.ac_start = TCPS_SYN_SENT; 65 conn.ac_end = TCPS_CLOSE_WAIT; 66 conn.ac_zoneid = ALL_ZONES; 67 68 ioc.ic_cmd = TCP_IOC_ABORT_CONN; 69 ioc.ic_timout = -1; /* infinite timeout */ 70 ioc.ic_len = sizeof (conn); 71 ioc.ic_dp = (char *)&conn; 72 73 if ((fd = open("/dev/tcp", O_RDONLY)) < 0) { 74 (void) fprintf(stderr, "unable to open %s", "/dev/tcp"); 75 return; 76 } 77 78 if (ioctl(fd, I_STR, &ioc) < 0) 79 if (errno != ENOENT) /* ENOENT is not an error */ 80 perror("ioctl"); 81 82 (void) close(fd); 83 } 84 85 static void 86 usage(char *arg0) 87 { 88 (void) fprintf(stderr, "usage: %s [-p <PORT>] <ADDR>\n", arg0); 89 exit(1); 90 } 91 92 int 93 main(int argc, char **argv) 94 { 95 extern char *optarg; 96 extern int optind, optopt; 97 struct addrinfo hints, *res, *ai; 98 char *addr_str = NULL; 99 char *port_str = NULL; 100 int errflag = 0; 101 int c, gaierr; 102 103 while ((c = getopt(argc, argv, "p:")) != -1) { 104 switch (c) { 105 case 'p': 106 port_str = optarg; 107 break; 108 case ':': 109 (void) fprintf(stderr, 110 "Option -%c requires an operand\n", optopt); 111 errflag++; 112 break; 113 case '?': 114 (void) fprintf(stderr, 115 "Unrecognized option: -%c\n", optopt); 116 errflag++; 117 break; 118 } 119 } 120 if (errflag) 121 usage(argv[0]); 122 if (argc <= optind) { 123 (void) fprintf(stderr, "No address specified\n"); 124 usage(argv[0]); 125 } 126 addr_str = argv[optind]; 127 128 /* 129 * Lookup the IP address 130 */ 131 (void) memset(&hints, 0, sizeof (hints)); 132 hints.ai_family = PF_UNSPEC; 133 hints.ai_socktype = SOCK_STREAM; 134 gaierr = getaddrinfo(addr_str, port_str, &hints, &res); 135 if (gaierr != 0) { 136 (void) fprintf(stderr, "%s: %s\n", addr_str, 137 gai_strerror(gaierr)); 138 return (1); 139 } 140 141 for (ai = res; ai != NULL; ai = ai->ai_next) { 142 tcp_abort_connections(ai->ai_addr); 143 } 144 145 return (0); 146 } 147