aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDave Täht <dgithub@taht.net>2017-04-14 13:27:18 -0700
committerBruce A. Mah <bmah@kitchenlab.org>2017-04-14 13:27:18 -0700
commit97c95c3be2542894db7d58578b2734d00ec6d63f (patch)
tree8ea053aea46378bf4c8bc8223f48f621479e377a /src
parente9e2d6d19c713f9a849609eb32a6cc06d7cc211a (diff)
downloadiperf3-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.am1
-rw-r--r--src/dscp.c156
-rwxr-xr-xsrc/iperf_api.c9
-rw-r--r--src/iperf_locale.c3
-rw-r--r--src/net.h1
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 */
diff --git a/src/net.h b/src/net.h
index 543365c..d1188c3 100644
--- a/src/net.h
+++ b/src/net.h
@@ -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