summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristiano F. Haesbaert <haesbaert@cvs.openbsd.org>2011-08-23 04:13:39 +0000
committerChristiano F. Haesbaert <haesbaert@cvs.openbsd.org>2011-08-23 04:13:39 +0000
commitf1b0eab7804a32863e9881d17d704d1dbaca17cb (patch)
tree0e35ac28906eb32c65e08e26964c3ed7d18dd628
parentaee75940fc50f29acaa7089f0fec0ba10da9d37d (diff)
Allow TOS/TCLASS to be set with -T, accept the same keywords as in pf.conf.
ok mcbride@ djm@ 'fine from me' jmc@
-rw-r--r--usr.bin/tcpbench/tcpbench.121
-rw-r--r--usr.bin/tcpbench/tcpbench.c102
2 files changed, 117 insertions, 6 deletions
diff --git a/usr.bin/tcpbench/tcpbench.1 b/usr.bin/tcpbench/tcpbench.1
index df0e8ebb89f..9f9294bca61 100644
--- a/usr.bin/tcpbench/tcpbench.1
+++ b/usr.bin/tcpbench/tcpbench.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tcpbench.1,v 1.12 2011/03/16 08:06:10 jmc Exp $
+.\" $OpenBSD: tcpbench.1,v 1.13 2011/08/23 04:13:37 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: March 16 2011 $
+.Dd $Mdocdate: August 23 2011 $
.Dt TCPBENCH 1
.Os
.Sh NAME
@@ -31,6 +31,7 @@
.Op Fl p Ar port
.Op Fl r Ar interval
.Op Fl S Ar space
+.Op Fl T Ar toskeyword
.Op Fl V Ar rtable
.Ar hostname
.Nm
@@ -41,6 +42,7 @@
.Op Fl k Ar kvars
.Op Fl p Ar port
.Op Fl r Ar interval
+.Op Fl T Ar toskeyword
.Op Fl S Ar space
.Op Fl V Ar rtable
.Ek
@@ -105,6 +107,21 @@ connections.
It defaults to using TCP if
.Fl u
is not specified.
+.It Fl T Ar toskeyword
+Change the IPv4 TOS or IPv6 TCLASS value.
+.Ar toskeyword
+may be one of
+.Ar critical ,
+.Ar inetcontrol ,
+.Ar lowdelay ,
+.Ar netcontrol ,
+.Ar throughput ,
+.Ar reliability ,
+or one of the DiffServ Code Points:
+.Ar ef ,
+.Ar af11 ... af43 ,
+.Ar cs0 ... cs7 ;
+or a number in either hex or decimal.
.It Fl u
Use UDP instead of TCP; this must be specified on both the client
and the server.
diff --git a/usr.bin/tcpbench/tcpbench.c b/usr.bin/tcpbench/tcpbench.c
index a25314882d1..07b628b6063 100644
--- a/usr.bin/tcpbench/tcpbench.c
+++ b/usr.bin/tcpbench/tcpbench.c
@@ -65,6 +65,7 @@ struct {
int Sflag; /* Socket buffer size (tcp mode) */
u_int rflag; /* Report rate (ms) */
int sflag; /* True if server */
+ int Tflag; /* ToS if != -1 */
int vflag; /* Verbose */
int uflag; /* UDP mode */
kvm_t *kvmh; /* Kvm handler */
@@ -113,7 +114,7 @@ static void client_init(struct addrinfo *, int, struct statctx *);
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 *);
-
+static int map_tos(char *, int *);
/*
* We account the mainstats here, that is the stats
* for all connections, all variables starting with slice
@@ -173,9 +174,10 @@ usage(void)
fprintf(stderr,
"usage: tcpbench -l\n"
" tcpbench [-uv] [-B buf] [-k kvars] [-n connections] [-p port]\n"
- " [-r interval] [-S space] [-V rtable] hostname\n"
+ " [-r interval] [-S space] [-T toskeyword] [-V rtable]\n"
+ " hostname\n"
" tcpbench -s [-uv] [-B buf] [-k kvars] [-p port]\n"
- " [-r interval] [-S space] [-V rtable]\n");
+ " [-r interval] [-S space] [-T toskeyword] [-V rtable]\n");
exit(1);
}
@@ -680,6 +682,16 @@ again:
r |= O_NONBLOCK;
if (fcntl(sock, F_SETFL, r) == -1)
err(1, "fcntl(F_SETFL, O_NONBLOCK)");
+ if (ptb->Tflag != -1 && ss.ss_family == AF_INET) {
+ if (setsockopt(sock, IPPROTO_IP, IP_TOS,
+ &ptb->Tflag, sizeof(ptb->Tflag)))
+ err(1, "setsockopt IP_TOS");
+ }
+ if (ptb->Tflag != -1 && ss.ss_family == AF_INET6) {
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS,
+ &ptb->Tflag, sizeof(ptb->Tflag)))
+ err(1, "setsockopt IPV6_TCLASS");
+ }
/* Alloc client structure and register reading callback */
if ((sc = calloc(1, sizeof(*sc))) == NULL)
err(1, "calloc");
@@ -729,6 +741,16 @@ server_init(struct addrinfo *aitop, struct statctx *udp_sc)
err(1, "setsockopt SO_RTABLE");
}
}
+ if (ptb->Tflag != -1 && ai->ai_family == AF_INET) {
+ if (setsockopt(sock, IPPROTO_IP, IP_TOS,
+ &ptb->Tflag, sizeof(ptb->Tflag)))
+ err(1, "setsockopt IP_TOS");
+ }
+ if (ptb->Tflag != -1 && ai->ai_family == AF_INET6) {
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS,
+ &ptb->Tflag, sizeof(ptb->Tflag)))
+ err(1, "setsockopt IPV6_TCLASS");
+ }
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
&on, sizeof(on)) == -1)
warn("reuse port");
@@ -821,6 +843,16 @@ client_init(struct addrinfo *aitop, int nconn, struct statctx *udp_sc)
warn("socket");
continue;
}
+ if (ptb->Tflag != -1 && ai->ai_family == AF_INET) {
+ if (setsockopt(sock, IPPROTO_IP, IP_TOS,
+ &ptb->Tflag, sizeof(ptb->Tflag)))
+ err(1, "setsockopt IP_TOS");
+ }
+ if (ptb->Tflag != -1 && ai->ai_family == AF_INET6) {
+ if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS,
+ &ptb->Tflag, sizeof(ptb->Tflag)))
+ err(1, "setsockopt IPV6_TCLASS");
+ }
if (ptb->Vflag) {
if (setsockopt(sock, SOL_SOCKET, SO_RTABLE,
&ptb->Vflag, sizeof(ptb->Vflag)) == -1) {
@@ -875,6 +907,54 @@ client_init(struct addrinfo *aitop, int nconn, struct statctx *udp_sc)
fprintf(stderr, "%u connections established\n", nconn);
}
+static int
+map_tos(char *s, int *val)
+{
+ /* DiffServ Codepoints and other TOS mappings */
+ const struct toskeywords {
+ const char *keyword;
+ int val;
+ } *t, toskeywords[] = {
+ { "af11", IPTOS_DSCP_AF11 },
+ { "af12", IPTOS_DSCP_AF12 },
+ { "af13", IPTOS_DSCP_AF13 },
+ { "af21", IPTOS_DSCP_AF21 },
+ { "af22", IPTOS_DSCP_AF22 },
+ { "af23", IPTOS_DSCP_AF23 },
+ { "af31", IPTOS_DSCP_AF31 },
+ { "af32", IPTOS_DSCP_AF32 },
+ { "af33", IPTOS_DSCP_AF33 },
+ { "af41", IPTOS_DSCP_AF41 },
+ { "af42", IPTOS_DSCP_AF42 },
+ { "af43", IPTOS_DSCP_AF43 },
+ { "critical", IPTOS_PREC_CRITIC_ECP },
+ { "cs0", IPTOS_DSCP_CS0 },
+ { "cs1", IPTOS_DSCP_CS1 },
+ { "cs2", IPTOS_DSCP_CS2 },
+ { "cs3", IPTOS_DSCP_CS3 },
+ { "cs4", IPTOS_DSCP_CS4 },
+ { "cs5", IPTOS_DSCP_CS5 },
+ { "cs6", IPTOS_DSCP_CS6 },
+ { "cs7", IPTOS_DSCP_CS7 },
+ { "ef", IPTOS_DSCP_EF },
+ { "inetcontrol", IPTOS_PREC_INTERNETCONTROL },
+ { "lowdelay", IPTOS_LOWDELAY },
+ { "netcontrol", IPTOS_PREC_NETCONTROL },
+ { "reliability", IPTOS_RELIABILITY },
+ { "throughput", IPTOS_THROUGHPUT },
+ { NULL, -1 },
+ };
+
+ for (t = toskeywords; t->keyword != NULL; t++) {
+ if (strcmp(s, t->keyword) == 0) {
+ *val = t->val;
+ return (1);
+ }
+ }
+
+ return (0);
+}
+
int
main(int argc, char **argv)
{
@@ -898,9 +978,10 @@ main(int argc, char **argv)
ptb->kvmh = NULL;
ptb->kvars = NULL;
ptb->rflag = DEFAULT_STATS_INTERVAL;
+ ptb->Tflag = -1;
nconn = 1;
- while ((ch = getopt(argc, argv, "B:hlk:n:p:r:sS:uvV:")) != -1) {
+ while ((ch = getopt(argc, argv, "B:hlk:n:p:r:sS:T:uvV:")) != -1) {
switch (ch) {
case 'l':
list_kvars();
@@ -957,6 +1038,19 @@ main(int argc, char **argv)
case 'u':
ptb->uflag = 1;
break;
+ case 'T':
+ if (map_tos(optarg, &ptb->Tflag))
+ break;
+ errstr = NULL;
+ if (strlen(optarg) > 1 && optarg[0] == '0' &&
+ optarg[1] == 'x')
+ ptb->Tflag = (int)strtol(optarg, NULL, 16);
+ else
+ ptb->Tflag = (int)strtonum(optarg, 0, 255,
+ &errstr);
+ if (ptb->Tflag == -1 || ptb->Tflag > 255 || errstr)
+ errx(1, "illegal tos value %s", optarg);
+ break;
case 'h':
default:
usage();