]> git.saurik.com Git - apple/network_cmds.git/blob - spray.tproj/spray.c
847ac342d884a491eed9fc62cb728de1172040d6
[apple/network_cmds.git] / spray.tproj / spray.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * Copyright (c) 1993 Winning Strategies, Inc.
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by Winning Strategies, Inc.
40 * 4. The name of the author may not be used to endorse or promote products
41 * derived from this software without specific prior written permission
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
44 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
45 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
46 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
47 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
48 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
52 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53 *
54 * $Id: spray.c,v 1.1.1.1 1999/05/02 03:58:27 wsanchez Exp $
55 */
56
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <unistd.h>
60
61 #include <rpc/rpc.h>
62 #include <rpcsvc/spray.h>
63
64 #ifndef SPRAYOVERHEAD
65 #define SPRAYOVERHEAD 86
66 #endif
67
68 void usage ();
69 void print_xferstats ();
70
71 /* spray buffer */
72 char spray_buffer[SPRAYMAX];
73
74 /* RPC timeouts */
75 struct timeval NO_DEFAULT = { -1, -1 };
76 struct timeval ONE_WAY = { 0, 0 };
77 struct timeval TIMEOUT = { 25, 0 };
78
79 int
80 main(argc, argv)
81 int argc;
82 char **argv;
83 {
84 char *progname;
85 spraycumul host_stats;
86 sprayarr host_array;
87 CLIENT *cl;
88 int c;
89 int i;
90 int count = 0;
91 int delay = 0;
92 int length = 0;
93 double xmit_time; /* time to receive data */
94
95 progname = *argv;
96 while ((c = getopt(argc, argv, "c:d:l:")) != -1) {
97 switch (c) {
98 case 'c':
99 count = atoi(optarg);
100 break;
101 case 'd':
102 delay = atoi(optarg);
103 break;
104 case 'l':
105 length = atoi(optarg);
106 break;
107 default:
108 usage();
109 /* NOTREACHED */
110 }
111 }
112 argc -= optind;
113 argv += optind;
114
115 if (argc != 1) {
116 usage();
117 /* NOTREACHED */
118 }
119
120
121 /* Correct packet length. */
122 if (length > SPRAYMAX) {
123 length = SPRAYMAX;
124 } else if (length < SPRAYOVERHEAD) {
125 length = SPRAYOVERHEAD;
126 } else {
127 /* The RPC portion of the packet is a multiple of 32 bits. */
128 length -= SPRAYOVERHEAD - 3;
129 length &= ~3;
130 length += SPRAYOVERHEAD;
131 }
132
133
134 /*
135 * The default value of count is the number of packets required
136 * to make the total stream size 100000 bytes.
137 */
138 if (!count) {
139 count = 100000 / length;
140 }
141
142 /* Initialize spray argument */
143 host_array.sprayarr_len = length - SPRAYOVERHEAD;
144 host_array.sprayarr_val = spray_buffer;
145
146
147 /* create connection with server */
148 cl = clnt_create(*argv, SPRAYPROG, SPRAYVERS, "udp");
149 if (cl == NULL) {
150 clnt_pcreateerror(progname);
151 exit(1);
152 }
153
154
155 /*
156 * For some strange reason, RPC 4.0 sets the default timeout,
157 * thus timeouts specified in clnt_call() are always ignored.
158 *
159 * The following (undocumented) hack resets the internal state
160 * of the client handle.
161 */
162 clnt_control(cl, CLSET_TIMEOUT, &NO_DEFAULT);
163
164
165 /* Clear server statistics */
166 if (clnt_call(cl, SPRAYPROC_CLEAR, xdr_void, NULL, xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) {
167 clnt_perror(cl, progname);
168 exit(1);
169 }
170
171
172 /* Spray server with packets */
173 printf ("sending %d packets of lnth %d to %s ...", count, length, *argv);
174 fflush (stdout);
175
176 for (i = 0; i < count; i++) {
177 clnt_call(cl, SPRAYPROC_SPRAY, xdr_sprayarr, &host_array, xdr_void, NULL, ONE_WAY);
178
179 if (delay) {
180 usleep(delay);
181 }
182 }
183
184
185 /* Collect statistics from server */
186 if (clnt_call(cl, SPRAYPROC_GET, xdr_void, NULL, xdr_spraycumul, &host_stats, TIMEOUT) != RPC_SUCCESS) {
187 clnt_perror(cl, progname);
188 exit(1);
189 }
190
191 xmit_time = host_stats.clock.sec +
192 (host_stats.clock.usec / 1000000.0);
193
194 printf ("\n\tin %.2f seconds elapsed time\n", xmit_time);
195
196
197 /* report dropped packets */
198 if (host_stats.counter != count) {
199 int packets_dropped = count - host_stats.counter;
200
201 printf("\t%d packets (%.2f%%) dropped\n",
202 packets_dropped,
203 100.0 * packets_dropped / count );
204 } else {
205 printf("\tno packets dropped\n");
206 }
207
208 printf("Sent:");
209 print_xferstats(count, length, xmit_time);
210
211 printf("Rcvd:");
212 print_xferstats(host_stats.counter, length, xmit_time);
213
214 exit (0);
215 }
216
217
218 void
219 print_xferstats(packets, packetlen, xfertime)
220 int packets;
221 int packetlen;
222 double xfertime;
223 {
224 int datalen;
225 double pps; /* packets per second */
226 double bps; /* bytes per second */
227
228 datalen = packets * packetlen;
229 pps = packets / xfertime;
230 bps = datalen / xfertime;
231
232 printf("\t%.0f packets/sec, ", pps);
233
234 if (bps >= 1024)
235 printf ("%.1fK ", bps / 1024);
236 else
237 printf ("%.0f ", bps);
238
239 printf("bytes/sec\n");
240 }
241
242
243 void
244 usage ()
245 {
246 fprintf(stderr, "usage: spray [-c count] [-l length] [-d delay] host\n");
247 exit(1);
248 }