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 * $FreeBSD$ 27 */ 28 29 #include <sys/types.h> 30 #include <sys/socket.h> 31 32 #include <netinet/in.h> 33 34 #include <arpa/inet.h> 35 36 #include <err.h> 37 #include <getopt.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <sysexits.h> 42 #include <unistd.h> 43 44 #include "tcpp.h" 45 46 #define BYTES_DEFAULT 10*1024*1024 /* Data per connection. */ 47 #define MAXTCPS_DEFAULT 32 /* Number of TCPs at a time per proc. */ 48 #define PROCS_DEFAULT 1 /* Processes used in run. */ 49 #define TCPS_DEFAULT 1 /* Number of connections per process. */ 50 #define BASEPORT_DEFAULT 10000 51 52 struct sockaddr_in remoteip; /* Base target address. */ 53 struct sockaddr_in localipbase; /* Base local address, if -l. */ 54 int cflag, hflag, lflag, mflag, pflag, sflag, tflag, Mflag, Pflag; 55 uint64_t bflag; 56 u_short rflag; 57 58 static void 59 usage(void) 60 { 61 62 fprintf(stderr, "client: tcpp" 63 " -c remoteIP" 64 " [-h]" 65 " [-P]" 66 " [-M localIPcount]" 67 " [-l localIPbase]" 68 "\n\t" 69 " [-b bytespertcp]" 70 " [-m maxtcpsatonce]" 71 " [-p procs]" 72 " [-t tcpsperproc]" 73 "\n" 74 "\t" 75 " [-r baseport]" 76 "\n"); 77 78 fprintf(stderr, "server: tcpp" 79 " -s" 80 " [-P]" 81 " [-l localIPbase]" 82 " [-m maxtcpsatonce]" 83 " [-p procs]" 84 "\n" 85 "\t" 86 " [-r baseport]" 87 "\n"); 88 exit(EX_USAGE); 89 } 90 91 int 92 main(int argc, char *argv[]) 93 { 94 long long ll; 95 char *dummy; 96 int ch; 97 98 bzero(&localipbase, sizeof(localipbase)); 99 localipbase.sin_len = sizeof(localipbase); 100 localipbase.sin_family = AF_INET; 101 localipbase.sin_addr.s_addr = htonl(INADDR_ANY); /* Default. */ 102 localipbase.sin_port = htons(0); /* Default. */ 103 104 bzero(&remoteip, sizeof(remoteip)); 105 remoteip.sin_len = sizeof(remoteip); 106 remoteip.sin_family = AF_INET; 107 remoteip.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Default. */ 108 remoteip.sin_port = htons(0); /* Default. */ 109 110 bflag = BYTES_DEFAULT; 111 mflag = MAXTCPS_DEFAULT; 112 pflag = PROCS_DEFAULT; 113 rflag = BASEPORT_DEFAULT; 114 tflag = TCPS_DEFAULT; 115 Mflag = 1; 116 while ((ch = getopt(argc, argv, "b:c:hl:m:p:r:st:CM:PT")) != -1) { 117 switch (ch) { 118 case 'b': 119 ll = strtoll(optarg, &dummy, 10); 120 if (*dummy != '\0' || ll <= 0) 121 usage(); 122 bflag = ll; 123 break; 124 125 case 'c': 126 cflag++; 127 if (inet_aton(optarg, &remoteip.sin_addr) != 1) 128 err(-1, "inet_aton: %s", optarg); 129 break; 130 131 case 'h': 132 hflag++; 133 break; 134 135 case 'l': 136 lflag++; 137 if (inet_aton(optarg, &localipbase.sin_addr) != 1) 138 err(-1, "inet_aton: %s", optarg); 139 break; 140 141 case 'm': 142 ll = strtoll(optarg, &dummy, 10); 143 if (*dummy != '\0' || ll <= 0) 144 usage(); 145 mflag = ll; 146 break; 147 148 case 'p': 149 ll = strtoll(optarg, &dummy, 10); 150 if (*dummy != '\0' || ll <= 0) 151 usage(); 152 pflag = ll; 153 break; 154 155 case 'r': 156 ll = strtol(optarg, &dummy, 10); 157 if (*dummy != '\0' || ll < 1 || ll > 65535) 158 usage(); 159 rflag = ll; 160 break; 161 162 case 's': 163 sflag++; 164 break; 165 166 case 't': 167 ll = strtoll(optarg, &dummy, 10); 168 if (*dummy != '\0' || ll <= 0) 169 usage(); 170 tflag = ll; 171 break; 172 173 case 'M': 174 ll = strtoll(optarg, &dummy, 10); 175 if (*dummy != '\0' || ll <= 1) 176 usage(); 177 Mflag = ll; 178 break; 179 180 case 'P': 181 #if defined(CPU_SETSIZE) && 0 182 Pflag++; 183 break; 184 #else 185 errx(EX_USAGE, "-P current unsupported"); 186 #endif 187 188 default: 189 usage(); 190 } 191 } 192 193 /* Exactly one of client and server. */ 194 if (cflag > 1 || sflag > 1) 195 usage(); 196 if ((cflag && sflag) || (!cflag && !sflag)) 197 usage(); 198 199 /* If Mflag is specified, we must have the lflag for a local IP. */ 200 if (Mflag > 1 && !lflag) 201 usage(); 202 203 /* Several flags are valid only on the client, disallow if server. */ 204 if (sflag && (hflag || Mflag > 1)) 205 usage(); 206 207 if (cflag) 208 tcpp_client(); 209 else 210 tcpp_server(); 211 exit(0); 212 } 213