]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - tools/tools/netrate/tcpp/tcpp.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / tools / tools / netrate / tcpp / tcpp.c
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 }