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, lflag, mflag, pflag, sflag, tflag, Cflag, Mflag, Tflag; 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 " [-CT]" 65 " [-M localIPcount]" 66 " [-l localIPbase]" 67 " [-b bytespertcp]" 68 " [-m maxtcpsatonce]" 69 "\n" 70 "\t" 71 " [-p procs]" 72 " [-t tcpsperproc]" 73 " [-r baseport]" 74 "\n"); 75 76 fprintf(stderr, "server: tcpp" 77 " -s" 78 " [-T]" 79 " [-l localIPbase]" 80 " [-m maxtcpsatonce]" 81 " [-p procs]" 82 " [-r baseport]" 83 "\n"); 84 exit(EX_USAGE); 85 } 86 87 int 88 main(int argc, char *argv[]) 89 { 90 long long ll; 91 char *dummy; 92 int ch; 93 94 bzero(&localipbase, sizeof(localipbase)); 95 localipbase.sin_len = sizeof(localipbase); 96 localipbase.sin_family = AF_INET; 97 localipbase.sin_addr.s_addr = htonl(INADDR_ANY); /* Default. */ 98 localipbase.sin_port = htons(0); /* Default. */ 99 100 bzero(&remoteip, sizeof(remoteip)); 101 remoteip.sin_len = sizeof(remoteip); 102 remoteip.sin_family = AF_INET; 103 remoteip.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Default. */ 104 remoteip.sin_port = htons(0); /* Default. */ 105 106 bflag = BYTES_DEFAULT; 107 mflag = MAXTCPS_DEFAULT; 108 pflag = PROCS_DEFAULT; 109 rflag = BASEPORT_DEFAULT; 110 tflag = TCPS_DEFAULT; 111 Mflag = 1; 112 while ((ch = getopt(argc, argv, "b:c:l:m:p:r:st:CM:T")) != -1) { 113 switch (ch) { 114 case 'b': 115 ll = strtoll(optarg, &dummy, 10); 116 if (*dummy != '\0' || ll <= 0) 117 usage(); 118 bflag = ll; 119 break; 120 121 case 'c': 122 cflag++; 123 if (inet_aton(optarg, &remoteip.sin_addr) != 1) 124 err(-1, "inet_aton: %s", optarg); 125 break; 126 127 case 'l': 128 lflag++; 129 if (inet_aton(optarg, &localipbase.sin_addr) != 1) 130 err(-1, "inet_aton: %s", optarg); 131 break; 132 133 case 'm': 134 ll = strtoll(optarg, &dummy, 10); 135 if (*dummy != '\0' || ll <= 0) 136 usage(); 137 mflag = ll; 138 break; 139 140 case 'p': 141 ll = strtoll(optarg, &dummy, 10); 142 if (*dummy != '\0' || ll <= 0) 143 usage(); 144 pflag = ll; 145 break; 146 147 case 'r': 148 ll = strtol(optarg, &dummy, 10); 149 if (*dummy != '\0' || ll < 1 || ll > 65535) 150 usage(); 151 rflag = ll; 152 break; 153 154 case 's': 155 sflag++; 156 break; 157 158 case 't': 159 ll = strtoll(optarg, &dummy, 10); 160 if (*dummy != '\0' || ll <= 0) 161 usage(); 162 tflag = ll; 163 break; 164 165 case 'C': 166 Cflag++; 167 break; 168 169 case 'M': 170 ll = strtoll(optarg, &dummy, 10); 171 if (*dummy != '\0' || ll <= 1) 172 usage(); 173 Mflag = ll; 174 break; 175 176 case 'T': 177 Tflag++; 178 break; 179 180 default: 181 usage(); 182 } 183 } 184 185 /* Exactly one of client and server. */ 186 if (cflag > 1 || sflag > 1) 187 usage(); 188 if ((cflag && sflag) || (!cflag && !sflag)) 189 usage(); 190 191 /* If Mflag is specified, we must have the lflag for a local IP. */ 192 if (Mflag > 1 && !lflag) 193 usage(); 194 195 /* Several flags are valid only on the client, disallow if server. */ 196 if (sflag && (Cflag || Mflag > 1)) 197 usage(); 198 199 if (cflag) 200 tcpp_client(); 201 else 202 tcpp_server(); 203 exit(0); 204 } 205