diff options
author | Dave Täht <dgithub@taht.net> | 2017-04-14 13:27:18 -0700 |
---|---|---|
committer | Bruce A. Mah <bmah@kitchenlab.org> | 2017-04-14 13:27:18 -0700 |
commit | 97c95c3be2542894db7d58578b2734d00ec6d63f (patch) | |
tree | 8ea053aea46378bf4c8bc8223f48f621479e377a /src | |
parent | e9e2d6d19c713f9a849609eb32a6cc06d7cc211a (diff) | |
download | iperf3-97c95c3be2542894db7d58578b2734d00ec6d63f.tar.gz |
add support for specifying --dscp symbolically and numerically (#508)
Using a command line adding dscp (instead of tos) you can:
--dscp EF,CS1,etc.
--dscp 0x08
--dscp 63
These will provide the correct shifted left 2 tos value for these, and
for people that think in terms of dscp values, this is a goodness.
Having this option available lets an enduser clearly distinguish between
an old version of iperf with a non-working --tos facility, vs a
version where it works, with something saner that lets just specify
the dscp.
I did not come up with a good -? option for it, and used -5 internally.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/dscp.c | 156 | ||||
-rwxr-xr-x | src/iperf_api.c | 9 | ||||
-rw-r--r-- | src/iperf_locale.c | 3 | ||||
-rw-r--r-- | src/net.h | 1 |
5 files changed, 169 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 23b0c72..a46a365 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -25,6 +25,7 @@ libiperf_la_SOURCES = \ iperf_sctp.h \ iperf_util.c \ iperf_util.h \ + dscp.c \ net.c \ net.h \ portable_endian.h \ diff --git a/src/dscp.c b/src/dscp.c new file mode 100644 index 0000000..329b304 --- /dev/null +++ b/src/dscp.c @@ -0,0 +1,156 @@ +/* dscp lookup routines lifted wholesale from openssh */ + +/* + * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2005,2006 Damien Miller. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <inttypes.h> + +#ifdef WIN32 +#define strcasecmp(a,b) _stricmp(a,b) +#define snprintf _snprintf +#endif + +int parse_qos(const char *cp); +const char * iptos2str(int iptos); + +/* + * Definitions for IP type of service (ip_tos) + */ + +#if HAVE_NETINET_IN_SYSTM_H +#include <netinet/in_systm.h> +#endif +#if HAVE_NETINET_IP_H +#include <netinet/ip.h> +#endif + +#ifndef IPTOS_LOWDELAY +# define IPTOS_LOWDELAY 0x10 +# define IPTOS_THROUGHPUT 0x08 +# define IPTOS_RELIABILITY 0x04 +# define IPTOS_LOWCOST 0x02 +# define IPTOS_MINCOST IPTOS_LOWCOST +#endif /* IPTOS_LOWDELAY */ + +/* + * Definitions for DiffServ Codepoints as per RFC2474 + */ +#ifndef IPTOS_DSCP_AF11 +# define IPTOS_DSCP_AF11 0x28 +# define IPTOS_DSCP_AF12 0x30 +# define IPTOS_DSCP_AF13 0x38 +# define IPTOS_DSCP_AF21 0x48 +# define IPTOS_DSCP_AF22 0x50 +# define IPTOS_DSCP_AF23 0x58 +# define IPTOS_DSCP_AF31 0x68 +# define IPTOS_DSCP_AF32 0x70 +# define IPTOS_DSCP_AF33 0x78 +# define IPTOS_DSCP_AF41 0x88 +# define IPTOS_DSCP_AF42 0x90 +# define IPTOS_DSCP_AF43 0x98 +# define IPTOS_DSCP_EF 0xb8 +#endif /* IPTOS_DSCP_AF11 */ + +#ifndef IPTOS_DSCP_CS0 +# define IPTOS_DSCP_CS0 0x00 +# define IPTOS_DSCP_CS1 0x20 +# define IPTOS_DSCP_CS2 0x40 +# define IPTOS_DSCP_CS3 0x60 +# define IPTOS_DSCP_CS4 0x80 +# define IPTOS_DSCP_CS5 0xa0 +# define IPTOS_DSCP_CS6 0xc0 +# define IPTOS_DSCP_CS7 0xe0 +#endif /* IPTOS_DSCP_CS0 */ +#ifndef IPTOS_DSCP_EF +# define IPTOS_DSCP_EF 0xb8 +#endif /* IPTOS_DSCP_EF */ + +static const struct { + const char *name; + int value; +} ipqos[] = { + { "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 }, + { "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 }, + { "lowdelay", IPTOS_LOWDELAY }, + { "throughput", IPTOS_THROUGHPUT }, + { "reliability", IPTOS_RELIABILITY }, + { NULL, -1 } +}; + +int +parse_qos(const char *cp) +{ + unsigned int i; + char *ep = NULL; + long val; + + if (cp == NULL) + return -1; + for (i = 0; ipqos[i].name != NULL; i++) { + if (strcasecmp(cp, ipqos[i].name) == 0) + return ipqos[i].value; + } + /* Try parsing as an integer */ + val = strtol(cp, &ep, 0); + if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) + return -1; + return val; +} + +const char * +iptos2str(int iptos) +{ + int i; + static char iptos_str[sizeof "0xff"]; + if (iptos < 0 || iptos > 64) iptos = 0; + for (i = 0; ipqos[i].name != NULL; i++) { + if (ipqos[i].value == iptos) + return ipqos[i].name; + } + snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); + return iptos_str; +} diff --git a/src/iperf_api.c b/src/iperf_api.c index e80312f..1f08937 100755 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -645,6 +645,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) {"version4", no_argument, NULL, '4'}, {"version6", no_argument, NULL, '6'}, {"tos", required_argument, NULL, 'S'}, + {"dscp", required_argument, NULL, '5'}, #if defined(HAVE_FLOWLABEL) {"flowlabel", required_argument, NULL, 'L'}, #endif /* HAVE_FLOWLABEL */ @@ -851,6 +852,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv) } client_flag = 1; break; + case '5': + test->settings->tos = parse_qos(optarg); + if(test->settings->tos < 0) { + i_errno = IEBADTOS; + return -1; + } + client_flag = 1; + break; case 'L': #if defined(HAVE_FLOWLABEL) test->settings->flowlabel = strtol(optarg, &endptr, 0); diff --git a/src/iperf_locale.c b/src/iperf_locale.c index 0a3d80e..b054adb 100644 --- a/src/iperf_locale.c +++ b/src/iperf_locale.c @@ -148,7 +148,8 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n" " -N, --no-delay set TCP/SCTP no delay, disabling Nagle's Algorithm\n" " -4, --version4 only use IPv4\n" " -6, --version6 only use IPv6\n" - " -S, --tos N set the IP 'type of service'\n" + " -S, --tos N set the IP 'type of service 0-255'\n" + " , --dscp N or dscp val set the IP 'dscp value either 0-63 or symbolic'\n" #if defined(HAVE_FLOWLABEL) " -L, --flowlabel N set the IPv6 flow label (only supported on Linux)\n" #endif /* HAVE_FLOWLABEL */ @@ -37,6 +37,7 @@ int getsock_tcp_mss(int inSock); int set_tcp_options(int sock, int no_delay, int mss); int setnonblocking(int fd, int nonblocking); int getsockdomain(int sock); +int parse_qos(const char *tos); #define NET_SOFTERROR -1 #define NET_HARDERROR -2 |