diff options
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tcpbench/tcpbench.1 | 7 | ||||
-rw-r--r-- | usr.bin/tcpbench/tcpbench.c | 54 |
2 files changed, 48 insertions, 13 deletions
diff --git a/usr.bin/tcpbench/tcpbench.1 b/usr.bin/tcpbench/tcpbench.1 index 60b3edf7387..f24ff04bedb 100644 --- a/usr.bin/tcpbench/tcpbench.1 +++ b/usr.bin/tcpbench/tcpbench.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tcpbench.1,v 1.14 2011/08/23 07:02:34 jmc Exp $ +.\" $OpenBSD: tcpbench.1,v 1.15 2011/09/09 00:40:54 haesbaert Exp $ .\" .\" Copyright (c) 2008 Damien Miller <djm@mindrot.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 23 2011 $ +.Dd $Mdocdate: September 9 2011 $ .Dt TCPBENCH 1 .Os .Sh NAME @@ -26,6 +26,7 @@ .Nm .Op Fl uv .Op Fl B Ar buf +.Op Fl b Ar addr .Op Fl k Ar kvars .Op Fl n Ar connections .Op Fl p Ar port @@ -79,6 +80,8 @@ Specify the size of the internal read/write buffer used by The default is 262144 bytes for TCP client/server and UDP server. In UDP client mode this may be used to specify the packet size on the test stream. +.It Fl b Ar addr +Specifies the IP address of the interface which is used to send the packets. .It Fl k Ar kvars Specify one or more kernel variables to monitor; multiple variables must be separated with commas. diff --git a/usr.bin/tcpbench/tcpbench.c b/usr.bin/tcpbench/tcpbench.c index 07b628b6063..a5fb1efdd1b 100644 --- a/usr.bin/tcpbench/tcpbench.c +++ b/usr.bin/tcpbench/tcpbench.c @@ -110,7 +110,8 @@ static void tcp_server_handle_sc(int, short, void *); static void tcp_server_accept(int, short, void *); static void server_init(struct addrinfo *, struct statctx *); static void client_handle_sc(int, short, void *); -static void client_init(struct addrinfo *, int, struct statctx *); +static void client_init(struct addrinfo *, int, struct statctx *, + struct addrinfo *); static int clock_gettime_tv(clockid_t, struct timeval *); static void udp_server_handle_sc(int, short, void *); static void udp_process_slice(int, short, void *); @@ -173,9 +174,9 @@ usage(void) { fprintf(stderr, "usage: tcpbench -l\n" - " tcpbench [-uv] [-B buf] [-k kvars] [-n connections] [-p port]\n" - " [-r interval] [-S space] [-T toskeyword] [-V rtable]\n" - " hostname\n" + " tcpbench [-uv] [-B buf] [-b addr] [-k kvars] [-n connections]\n" + " [-p port] [-r interval] [-S space] [-T toskeyword]\n" + " [-V rtable] hostname\n" " tcpbench -s [-uv] [-B buf] [-k kvars] [-p port]\n" " [-r interval] [-S space] [-T toskeyword] [-V rtable]\n"); exit(1); @@ -821,7 +822,8 @@ again: } static void -client_init(struct addrinfo *aitop, int nconn, struct statctx *udp_sc) +client_init(struct addrinfo *aitop, int nconn, struct statctx *udp_sc, + struct addrinfo *aib) { struct statctx *sc; struct addrinfo *ai; @@ -843,6 +845,17 @@ client_init(struct addrinfo *aitop, int nconn, struct statctx *udp_sc) warn("socket"); continue; } + if (aib != NULL) { + saddr_ntop(aib->ai_addr, aib->ai_addrlen, + tmp, sizeof(tmp)); + if (ptb->vflag) + fprintf(stderr, + "Try to bind to %s\n", tmp); + if (bind(sock, (struct sockaddr *)aib->ai_addr, + aib->ai_addrlen) == -1) + err(1, "bind"); + freeaddrinfo(aib); + } if (ptb->Tflag != -1 && ai->ai_family == AF_INET) { if (setsockopt(sock, IPPROTO_IP, IP_TOS, &ptb->Tflag, sizeof(ptb->Tflag))) @@ -962,12 +975,12 @@ main(int argc, char **argv) extern char *optarg; char kerr[_POSIX2_LINE_MAX], *tmp; - struct addrinfo *aitop, hints; + struct addrinfo *aitop, *aib, hints; const char *errstr; struct rlimit rl; int ch, herr, nconn; struct nlist nl[] = { { "_tcbtable" }, { "" } }; - const char *host = NULL, *port = DEFAULT_PORT; + const char *host = NULL, *port = DEFAULT_PORT, *srcbind = NULL; struct event ev_sigint, ev_sigterm, ev_sighup; struct statctx *udp_sc = NULL; @@ -980,9 +993,13 @@ main(int argc, char **argv) ptb->rflag = DEFAULT_STATS_INTERVAL; ptb->Tflag = -1; nconn = 1; + aib = NULL; - while ((ch = getopt(argc, argv, "B:hlk:n:p:r:sS:T:uvV:")) != -1) { + while ((ch = getopt(argc, argv, "b:B:hlk:n:p:r:sS:T:uvV:")) != -1) { switch (ch) { + case 'b': + srcbind = optarg; + break; case 'l': list_kvars(); exit(0); @@ -1079,12 +1096,27 @@ main(int argc, char **argv) } bzero(&hints, sizeof(hints)); - if (UDP_MODE) + if (UDP_MODE) { hints.ai_socktype = SOCK_DGRAM; - else + hints.ai_protocol = IPPROTO_UDP; + } + else { hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + } if (ptb->sflag) hints.ai_flags = AI_PASSIVE; + if (srcbind != NULL) { + hints.ai_flags |= AI_NUMERICHOST; + herr = getaddrinfo(srcbind, NULL, &hints, &aib); + hints.ai_flags &= ~AI_NUMERICHOST; + if (herr != 0) { + if (herr == EAI_SYSTEM) + err(1, "getaddrinfo"); + else + errx(1, "getaddrinfo: %s", gai_strerror(herr)); + } + } if ((herr = getaddrinfo(host, port, &hints, &aitop)) != 0) { if (herr == EAI_SYSTEM) err(1, "getaddrinfo"); @@ -1145,7 +1177,7 @@ main(int argc, char **argv) if (ptb->sflag) { server_init(aitop, udp_sc); } else - client_init(aitop, nconn, udp_sc); + client_init(aitop, nconn, udp_sc, aib); /* libevent main loop*/ event_dispatch(); |