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 #include <stdlib.h> 38 #include <stdio.h> 39 #include <ctype.h> 40 #include <rpc/rpc.h> 41 #include <rpcsvc/spray.h> 42 #include <sys/poll.h> 43 44 enum clnt_stat sprayproc_spray_1nd(/*argp, clnt*/); 45 46 #define DEFBYTES 100000 /* default numbers of bytes to send */ 47 #define MAXPACKETLEN 1514 48 #define SPRAYOVERHEAD 86 /* size of rpc packet when size=0 */ 49 50 static void slp(int usecs); 51 static void usage(void); 52 53 int 54 main(int argc, char *argv[]) 55 { 56 int c; 57 extern char *optarg; 58 extern int optind; 59 register CLIENT *clnt; 60 unsigned int i; 61 int delay = 0; 62 unsigned int psec, bsec; 63 int buf[SPRAYMAX/4]; 64 char msgbuf[256]; 65 unsigned int lnth, cnt; 66 sprayarr arr; 67 spraycumul cumul; 68 spraycumul *co; 69 char *host = NULL; 70 char *type; 71 72 if (argc < 2) 73 usage(); 74 75 cnt = 0; 76 lnth = SPRAYOVERHEAD; 77 type = "netpath"; 78 while (optind < argc) { 79 if (argv[optind][0] == '-') { 80 if ((c = getopt(argc, argv, "d:c:t:l:")) == EOF) { 81 break; 82 } 83 switch (c) { 84 case 'd': 85 delay = atoi(optarg); 86 break; 87 case 'c': 88 cnt = (unsigned int) atoi(optarg); 89 break; 90 case 't': 91 type = optarg; 92 break; 93 case 'l': 94 lnth = (unsigned int) atoi(optarg); 95 break; 96 default: 97 usage(); 98 } 99 } else { 100 host = argv[optind++]; 101 } 102 } 103 if (host == NULL) 104 usage(); 105 clnt = clnt_create(host, SPRAYPROG, SPRAYVERS, type); 106 if (clnt == (CLIENT *)NULL) { 107 sprintf(msgbuf, "spray: cannot clnt_create %s:%s", host, type); 108 clnt_pcreateerror(msgbuf); 109 exit(1); 110 } 111 if (cnt == 0) 112 cnt = DEFBYTES/lnth; 113 if (lnth < SPRAYOVERHEAD) 114 lnth = SPRAYOVERHEAD; 115 else if (lnth >= SPRAYMAX) 116 lnth = SPRAYMAX; 117 if (lnth <= MAXPACKETLEN && lnth % 4 != 2) 118 lnth = ((lnth + 5) / 4) * 4 - 2; 119 arr.sprayarr_len = lnth - SPRAYOVERHEAD; 120 arr.sprayarr_val = (char *)buf; 121 printf("sending %u packets of length %u to %s ...", cnt, lnth, host); 122 fflush(stdout); 123 if (sprayproc_clear_1(NULL, clnt) == NULL) { 124 clnt_perror(clnt, "SPRAYPROC_CLEAR "); 125 exit(1); 126 } 127 for (i = 0; i < cnt; i++) { 128 sprayproc_spray_1nd(&arr, clnt); 129 if (delay > 0) 130 slp(delay); 131 } 132 if ((co = sprayproc_get_1(NULL, clnt)) == NULL) { 133 clnt_perror(clnt, "SPRAYPROC_GET "); 134 exit(1); 135 } 136 cumul = *co; 137 if (cumul.counter < cnt) 138 printf("\n\t%d packets (%.3f%%) dropped by %s\n", 139 cnt - cumul.counter, 140 100.0 * (cnt - cumul.counter)/cnt, host); 141 else 142 printf("\n\tno packets dropped by %s\n", host); 143 psec = (1000000.0 * cumul.counter) 144 / (1000000.0 * cumul.clock.sec + cumul.clock.usec); 145 bsec = (lnth * 1000000.0 * cumul.counter)/ 146 (1000000.0 * cumul.clock.sec + cumul.clock.usec); 147 printf("\t%u packets/sec, %u bytes/sec\n", psec, bsec); 148 exit(0); 149 /* NOTREACHED */ 150 } 151 152 /* 153 * A special call, where the TIMEOUT is 0. So, every call times-out. 154 */ 155 static struct timeval TIMEOUT = { 0, 0 }; 156 157 enum clnt_stat 158 sprayproc_spray_1nd(argp, clnt) 159 sprayarr *argp; 160 CLIENT *clnt; 161 { 162 return (clnt_call(clnt, SPRAYPROC_SPRAY, xdr_sprayarr, (caddr_t)argp, 163 xdr_void, NULL, TIMEOUT)); 164 } 165 166 /* A cheap milliseconds sleep call */ 167 static void 168 slp(usecs) 169 { 170 static struct pollfd pfds[1] = { 171 0, POLLIN, 0 172 }; 173 pfds[0].fd = fileno(stdout); 174 poll(pfds, 1, usecs/1000); 175 } 176 177 static void 178 usage() 179 { 180 printf("spray host [-t nettype] [-l lnth] [-c cnt] [-d delay]\n"); 181 exit(1); 182 } 183