1 /*- 2 * Copyright (c) 2008-2009 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/socket.h> 29 30 #include <netinet/in.h> 31 32 #include <arpa/inet.h> 33 34 #include <err.h> 35 #include <getopt.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <sysexits.h> 40 #include <unistd.h> 41 42 #include "tcpp.h" 43 44 #define BYTES_DEFAULT 10*1024*1024 /* Data per connection. */ 45 #define MAXTCPS_DEFAULT 32 /* Number of TCPs at a time per proc. */ 46 #define PROCS_DEFAULT 1 /* Processes used in run. */ 47 #define TCPS_DEFAULT 1 /* Number of connections per process. */ 48 #define BASEPORT_DEFAULT 10000 49 50 struct sockaddr_in remoteip; /* Base target address. */ 51 struct sockaddr_in localipbase; /* Base local address, if -l. */ 52 int cflag, hflag, lflag, mflag, pflag, sflag, tflag, Mflag, Pflag; 53 uint64_t bflag; 54 u_short rflag; 55 56 static void 57 usage(void) 58 { 59 60 fprintf(stderr, "client: tcpp" 61 " -c remoteIP" 62 " [-h]" 63 " [-P]" 64 " [-M localIPcount]" 65 " [-l localIPbase]" 66 "\n\t" 67 " [-b bytespertcp]" 68 " [-m maxtcpsatonce]" 69 " [-p procs]" 70 " [-t tcpsperproc]" 71 "\n" 72 "\t" 73 " [-r baseport]" 74 "\n"); 75 76 fprintf(stderr, "server: tcpp" 77 " -s" 78 " [-P]" 79 " [-l localIPbase]" 80 " [-m maxtcpsatonce]" 81 " [-p procs]" 82 "\n" 83 "\t" 84 " [-r baseport]" 85 "\n"); 86 exit(EX_USAGE); 87 } 88 89 int 90 main(int argc, char *argv[]) 91 { 92 long long ll; 93 char *dummy; 94 int ch; 95 96 bzero(&localipbase, sizeof(localipbase)); 97 localipbase.sin_len = sizeof(localipbase); 98 localipbase.sin_family = AF_INET; 99 localipbase.sin_addr.s_addr = htonl(INADDR_ANY); /* Default. */ 100 localipbase.sin_port = htons(0); /* Default. */ 101 102 bzero(&remoteip, sizeof(remoteip)); 103 remoteip.sin_len = sizeof(remoteip); 104 remoteip.sin_family = AF_INET; 105 remoteip.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Default. */ 106 remoteip.sin_port = htons(0); /* Default. */ 107 108 bflag = BYTES_DEFAULT; 109 mflag = MAXTCPS_DEFAULT; 110 pflag = PROCS_DEFAULT; 111 rflag = BASEPORT_DEFAULT; 112 tflag = TCPS_DEFAULT; 113 Mflag = 1; 114 while ((ch = getopt(argc, argv, "b:c:hl:m:p:r:st:CM:PT")) != -1) { 115 switch (ch) { 116 case 'b': 117 ll = strtoll(optarg, &dummy, 10); 118 if (*dummy != '\0' || ll <= 0) 119 usage(); 120 bflag = ll; 121 break; 122 123 case 'c': 124 cflag++; 125 if (inet_aton(optarg, &remoteip.sin_addr) != 1) 126 err(-1, "inet_aton: %s", optarg); 127 break; 128 129 case 'h': 130 hflag++; 131 break; 132 133 case 'l': 134 lflag++; 135 if (inet_aton(optarg, &localipbase.sin_addr) != 1) 136 err(-1, "inet_aton: %s", optarg); 137 break; 138 139 case 'm': 140 ll = strtoll(optarg, &dummy, 10); 141 if (*dummy != '\0' || ll <= 0) 142 usage(); 143 mflag = ll; 144 break; 145 146 case 'p': 147 ll = strtoll(optarg, &dummy, 10); 148 if (*dummy != '\0' || ll <= 0) 149 usage(); 150 pflag = ll; 151 break; 152 153 case 'r': 154 ll = strtol(optarg, &dummy, 10); 155 if (*dummy != '\0' || ll < 1 || ll > 65535) 156 usage(); 157 rflag = ll; 158 break; 159 160 case 's': 161 sflag++; 162 break; 163 164 case 't': 165 ll = strtoll(optarg, &dummy, 10); 166 if (*dummy != '\0' || ll <= 0) 167 usage(); 168 tflag = ll; 169 break; 170 171 case 'M': 172 ll = strtoll(optarg, &dummy, 10); 173 if (*dummy != '\0' || ll <= 1) 174 usage(); 175 Mflag = ll; 176 break; 177 178 case 'P': 179 #if defined(CPU_SETSIZE) && 0 180 Pflag++; 181 break; 182 #else 183 errx(EX_USAGE, "-P current unsupported"); 184 #endif 185 186 default: 187 usage(); 188 } 189 } 190 191 /* Exactly one of client and server. */ 192 if (cflag > 1 || sflag > 1) 193 usage(); 194 if ((cflag && sflag) || (!cflag && !sflag)) 195 usage(); 196 197 /* If Mflag is specified, we must have the lflag for a local IP. */ 198 if (Mflag > 1 && !lflag) 199 usage(); 200 201 /* Several flags are valid only on the client, disallow if server. */ 202 if (sflag && (hflag || Mflag > 1)) 203 usage(); 204 205 if (cflag) 206 tcpp_client(); 207 else 208 tcpp_server(); 209 exit(0); 210 } 211