1189623Srwatson/*- 2189623Srwatson * Copyright (c) 2008-2009 Robert N. M. Watson 3189623Srwatson * All rights reserved. 4189623Srwatson * 5189623Srwatson * Redistribution and use in source and binary forms, with or without 6189623Srwatson * modification, are permitted provided that the following conditions 7189623Srwatson * are met: 8189623Srwatson * 1. Redistributions of source code must retain the above copyright 9189623Srwatson * notice, this list of conditions and the following disclaimer. 10189623Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11189623Srwatson * notice, this list of conditions and the following disclaimer in the 12189623Srwatson * documentation and/or other materials provided with the distribution. 13189623Srwatson * 14189623Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15189623Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16189623Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17189623Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18189623Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19189623Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20189623Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21189623Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22189623Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23189623Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24189623Srwatson * SUCH DAMAGE. 25189623Srwatson * 26189623Srwatson * $FreeBSD$ 27189623Srwatson */ 28189623Srwatson 29189623Srwatson#include <sys/types.h> 30189623Srwatson#include <sys/socket.h> 31189623Srwatson 32189623Srwatson#include <netinet/in.h> 33189623Srwatson 34189623Srwatson#include <arpa/inet.h> 35189623Srwatson 36189623Srwatson#include <err.h> 37189623Srwatson#include <getopt.h> 38189623Srwatson#include <stdio.h> 39189623Srwatson#include <stdlib.h> 40189623Srwatson#include <string.h> 41189623Srwatson#include <sysexits.h> 42189623Srwatson#include <unistd.h> 43189623Srwatson 44189623Srwatson#include "tcpp.h" 45189623Srwatson 46189623Srwatson#define BYTES_DEFAULT 10*1024*1024 /* Data per connection. */ 47189623Srwatson#define MAXTCPS_DEFAULT 32 /* Number of TCPs at a time per proc. */ 48189623Srwatson#define PROCS_DEFAULT 1 /* Processes used in run. */ 49189623Srwatson#define TCPS_DEFAULT 1 /* Number of connections per process. */ 50189623Srwatson#define BASEPORT_DEFAULT 10000 51189623Srwatson 52189623Srwatsonstruct sockaddr_in remoteip; /* Base target address. */ 53189623Srwatsonstruct sockaddr_in localipbase; /* Base local address, if -l. */ 54208873Srwatsonint cflag, hflag, lflag, mflag, pflag, sflag, tflag, Mflag, Pflag; 55189623Srwatsonuint64_t bflag; 56189623Srwatsonu_short rflag; 57189623Srwatson 58189623Srwatsonstatic void 59189623Srwatsonusage(void) 60189623Srwatson{ 61189623Srwatson 62189623Srwatson fprintf(stderr, "client: tcpp" 63189623Srwatson " -c remoteIP" 64208873Srwatson " [-h]" 65208873Srwatson " [-P]" 66189623Srwatson " [-M localIPcount]" 67189623Srwatson " [-l localIPbase]" 68208859Srwatson "\n\t" 69189623Srwatson " [-b bytespertcp]" 70189623Srwatson " [-m maxtcpsatonce]" 71208859Srwatson " [-p procs]" 72208859Srwatson " [-t tcpsperproc]" 73189623Srwatson "\n" 74189623Srwatson "\t" 75189623Srwatson " [-r baseport]" 76189623Srwatson "\n"); 77189623Srwatson 78189623Srwatson fprintf(stderr, "server: tcpp" 79189623Srwatson " -s" 80208873Srwatson " [-P]" 81189623Srwatson " [-l localIPbase]" 82189623Srwatson " [-m maxtcpsatonce]" 83189623Srwatson " [-p procs]" 84208859Srwatson "\n" 85208859Srwatson "\t" 86189623Srwatson " [-r baseport]" 87189623Srwatson "\n"); 88189623Srwatson exit(EX_USAGE); 89189623Srwatson} 90189623Srwatson 91189623Srwatsonint 92189623Srwatsonmain(int argc, char *argv[]) 93189623Srwatson{ 94189623Srwatson long long ll; 95189623Srwatson char *dummy; 96189623Srwatson int ch; 97189623Srwatson 98189623Srwatson bzero(&localipbase, sizeof(localipbase)); 99189623Srwatson localipbase.sin_len = sizeof(localipbase); 100189623Srwatson localipbase.sin_family = AF_INET; 101189623Srwatson localipbase.sin_addr.s_addr = htonl(INADDR_ANY); /* Default. */ 102189623Srwatson localipbase.sin_port = htons(0); /* Default. */ 103189623Srwatson 104189623Srwatson bzero(&remoteip, sizeof(remoteip)); 105189623Srwatson remoteip.sin_len = sizeof(remoteip); 106189623Srwatson remoteip.sin_family = AF_INET; 107189623Srwatson remoteip.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* Default. */ 108189623Srwatson remoteip.sin_port = htons(0); /* Default. */ 109189623Srwatson 110189623Srwatson bflag = BYTES_DEFAULT; 111189623Srwatson mflag = MAXTCPS_DEFAULT; 112189623Srwatson pflag = PROCS_DEFAULT; 113189623Srwatson rflag = BASEPORT_DEFAULT; 114189623Srwatson tflag = TCPS_DEFAULT; 115189623Srwatson Mflag = 1; 116208873Srwatson while ((ch = getopt(argc, argv, "b:c:hl:m:p:r:st:CM:PT")) != -1) { 117189623Srwatson switch (ch) { 118189623Srwatson case 'b': 119189623Srwatson ll = strtoll(optarg, &dummy, 10); 120189623Srwatson if (*dummy != '\0' || ll <= 0) 121189623Srwatson usage(); 122189623Srwatson bflag = ll; 123189623Srwatson break; 124189623Srwatson 125189623Srwatson case 'c': 126189623Srwatson cflag++; 127189623Srwatson if (inet_aton(optarg, &remoteip.sin_addr) != 1) 128189623Srwatson err(-1, "inet_aton: %s", optarg); 129189623Srwatson break; 130189623Srwatson 131208873Srwatson case 'h': 132208873Srwatson hflag++; 133208873Srwatson break; 134208873Srwatson 135189623Srwatson case 'l': 136189623Srwatson lflag++; 137189623Srwatson if (inet_aton(optarg, &localipbase.sin_addr) != 1) 138189623Srwatson err(-1, "inet_aton: %s", optarg); 139189623Srwatson break; 140189623Srwatson 141189623Srwatson case 'm': 142189623Srwatson ll = strtoll(optarg, &dummy, 10); 143189623Srwatson if (*dummy != '\0' || ll <= 0) 144189623Srwatson usage(); 145189623Srwatson mflag = ll; 146189623Srwatson break; 147189623Srwatson 148189623Srwatson case 'p': 149189623Srwatson ll = strtoll(optarg, &dummy, 10); 150189623Srwatson if (*dummy != '\0' || ll <= 0) 151189623Srwatson usage(); 152189623Srwatson pflag = ll; 153189623Srwatson break; 154189623Srwatson 155189623Srwatson case 'r': 156189623Srwatson ll = strtol(optarg, &dummy, 10); 157189623Srwatson if (*dummy != '\0' || ll < 1 || ll > 65535) 158189623Srwatson usage(); 159189623Srwatson rflag = ll; 160189623Srwatson break; 161189623Srwatson 162189623Srwatson case 's': 163189623Srwatson sflag++; 164189623Srwatson break; 165189623Srwatson 166189623Srwatson case 't': 167189623Srwatson ll = strtoll(optarg, &dummy, 10); 168189623Srwatson if (*dummy != '\0' || ll <= 0) 169189623Srwatson usage(); 170189623Srwatson tflag = ll; 171189623Srwatson break; 172189623Srwatson 173189623Srwatson case 'M': 174189623Srwatson ll = strtoll(optarg, &dummy, 10); 175189623Srwatson if (*dummy != '\0' || ll <= 1) 176189623Srwatson usage(); 177189623Srwatson Mflag = ll; 178189623Srwatson break; 179189623Srwatson 180208859Srwatson case 'P': 181208859Srwatson#if defined(CPU_SETSIZE) && 0 182208859Srwatson Pflag++; 183208859Srwatson break; 184208859Srwatson#else 185208859Srwatson errx(EX_USAGE, "-P current unsupported"); 186208859Srwatson#endif 187208859Srwatson 188189623Srwatson default: 189189623Srwatson usage(); 190189623Srwatson } 191189623Srwatson } 192189623Srwatson 193189623Srwatson /* Exactly one of client and server. */ 194189623Srwatson if (cflag > 1 || sflag > 1) 195189623Srwatson usage(); 196189623Srwatson if ((cflag && sflag) || (!cflag && !sflag)) 197189623Srwatson usage(); 198189623Srwatson 199189623Srwatson /* If Mflag is specified, we must have the lflag for a local IP. */ 200189623Srwatson if (Mflag > 1 && !lflag) 201189623Srwatson usage(); 202189623Srwatson 203189623Srwatson /* Several flags are valid only on the client, disallow if server. */ 204208873Srwatson if (sflag && (hflag || Mflag > 1)) 205189623Srwatson usage(); 206189623Srwatson 207189623Srwatson if (cflag) 208189623Srwatson tcpp_client(); 209189623Srwatson else 210189623Srwatson tcpp_server(); 211189623Srwatson exit(0); 212189623Srwatson} 213