1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * University Copyright- Copyright (c) 1982, 1986, 1988 29 * The Regents of the University of California 30 * All Rights Reserved 31 * 32 * University Acknowledgment- Portions of this document are derived from 33 * software developed by the University of California, Berkeley, and its 34 * contributors. 35 */ 36 37 #pragma ident "%Z%%M% %I% %E% SMI" 38 39 #include <stdlib.h> 40 #include <stdio.h> 41 #include <ctype.h> 42 #include <rpc/rpc.h> 43 #include <rpcsvc/spray.h> 44 #include <sys/poll.h> 45 46 enum clnt_stat sprayproc_spray_1nd(/*argp, clnt*/); 47 48 #define DEFBYTES 100000 /* default numbers of bytes to send */ 49 #define MAXPACKETLEN 1514 50 #define SPRAYOVERHEAD 86 /* size of rpc packet when size=0 */ 51 52 static void slp(int usecs); 53 static void usage(void); 54 55 int 56 main(int argc, char *argv[]) 57 { 58 int c; 59 extern char *optarg; 60 extern int optind; 61 register CLIENT *clnt; 62 unsigned int i; 63 int delay = 0; 64 unsigned int psec, bsec; 65 int buf[SPRAYMAX/4]; 66 char msgbuf[256]; 67 unsigned int lnth, cnt; 68 sprayarr arr; 69 spraycumul cumul; 70 spraycumul *co; 71 char *host = NULL; 72 char *type; 73 74 if (argc < 2) 75 usage(); 76 77 cnt = 0; 78 lnth = SPRAYOVERHEAD; 79 type = "netpath"; 80 while (optind < argc) { 81 if (argv[optind][0] == '-') { 82 if ((c = getopt(argc, argv, "d:c:t:l:")) == EOF) { 83 break; 84 } 85 switch (c) { 86 case 'd': 87 delay = atoi(optarg); 88 break; 89 case 'c': 90 cnt = (unsigned int) atoi(optarg); 91 break; 92 case 't': 93 type = optarg; 94 break; 95 case 'l': 96 lnth = (unsigned int) atoi(optarg); 97 break; 98 default: 99 usage(); 100 } 101 } else { 102 host = argv[optind++]; 103 } 104 } 105 if (host == NULL) 106 usage(); 107 clnt = clnt_create(host, SPRAYPROG, SPRAYVERS, type); 108 if (clnt == (CLIENT *)NULL) { 109 sprintf(msgbuf, "spray: cannot clnt_create %s:%s", host, type); 110 clnt_pcreateerror(msgbuf); 111 exit(1); 112 } 113 if (cnt == 0) 114 cnt = DEFBYTES/lnth; 115 if (lnth < SPRAYOVERHEAD) 116 lnth = SPRAYOVERHEAD; 117 else if (lnth >= SPRAYMAX) 118 lnth = SPRAYMAX; 119 if (lnth <= MAXPACKETLEN && lnth % 4 != 2) 120 lnth = ((lnth + 5) / 4) * 4 - 2; 121 arr.sprayarr_len = lnth - SPRAYOVERHEAD; 122 arr.sprayarr_val = (char *)buf; 123 printf("sending %u packets of length %u to %s ...", cnt, lnth, host); 124 fflush(stdout); 125 if (sprayproc_clear_1(NULL, clnt) == NULL) { 126 clnt_perror(clnt, "SPRAYPROC_CLEAR "); 127 exit(1); 128 } 129 for (i = 0; i < cnt; i++) { 130 sprayproc_spray_1nd(&arr, clnt); 131 if (delay > 0) 132 slp(delay); 133 } 134 if ((co = sprayproc_get_1(NULL, clnt)) == NULL) { 135 clnt_perror(clnt, "SPRAYPROC_GET "); 136 exit(1); 137 } 138 cumul = *co; 139 if (cumul.counter < cnt) 140 printf("\n\t%d packets (%.3f%%) dropped by %s\n", 141 cnt - cumul.counter, 142 100.0 * (cnt - cumul.counter)/cnt, host); 143 else 144 printf("\n\tno packets dropped by %s\n", host); 145 psec = (1000000.0 * cumul.counter) 146 / (1000000.0 * cumul.clock.sec + cumul.clock.usec); 147 bsec = (lnth * 1000000.0 * cumul.counter)/ 148 (1000000.0 * cumul.clock.sec + cumul.clock.usec); 149 printf("\t%u packets/sec, %u bytes/sec\n", psec, bsec); 150 exit(0); 151 /* NOTREACHED */ 152 } 153 154 /* 155 * A special call, where the TIMEOUT is 0. So, every call times-out. 156 */ 157 static struct timeval TIMEOUT = { 0, 0 }; 158 159 enum clnt_stat 160 sprayproc_spray_1nd(argp, clnt) 161 sprayarr *argp; 162 CLIENT *clnt; 163 { 164 return (clnt_call(clnt, SPRAYPROC_SPRAY, xdr_sprayarr, (caddr_t)argp, 165 xdr_void, NULL, TIMEOUT)); 166 } 167 168 /* A cheap milliseconds sleep call */ 169 static void 170 slp(usecs) 171 { 172 static struct pollfd pfds[1] = { 173 0, POLLIN, 0 174 }; 175 pfds[0].fd = fileno(stdout); 176 poll(pfds, 1, usecs/1000); 177 } 178 179 static void 180 usage() 181 { 182 printf("spray host [-t nettype] [-l lnth] [-c cnt] [-d delay]\n"); 183 exit(1); 184 }