aboutsummaryrefslogtreecommitdiff
path: root/helper
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2016-02-09 14:25:07 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2016-03-03 22:32:04 +0300
commitcc03b63e667c3acf580f20765910dbb342d452b2 (patch)
tree491fc29041a2f0e75f9e4f89bfc1ae7ad268de80 /helper
parent0ebc7f2d0788a2adec58e25032ba2317f9e089ac (diff)
helper: eth: added mac address parse
Ethernet MAC address parse function is commonly needed by test applications. A common parse function harmonizes the definition of MAC address as a command line parameter. Signed-off-by: Petri Savolainen <petri.savolainen@nokia.com> Reviewed-by: Juha-Matti Tilli <juha-matti.tilli@nokia.com> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Diffstat (limited to 'helper')
-rw-r--r--helper/Makefile.am1
-rw-r--r--helper/eth.c36
-rw-r--r--helper/include/odp/helper/eth.h22
-rw-r--r--helper/test/.gitignore2
-rw-r--r--helper/test/Makefile.am2
-rw-r--r--helper/test/odp_parse.c205
6 files changed, 263 insertions, 5 deletions
diff --git a/helper/Makefile.am b/helper/Makefile.am
index 655779311..6f6d6cd28 100644
--- a/helper/Makefile.am
+++ b/helper/Makefile.am
@@ -28,6 +28,7 @@ noinst_HEADERS = \
$(srcdir)/odph_list_internal.h
__LIB__libodphelper_la_SOURCES = \
+ eth.c \
linux.c \
hashtable.c \
lineartable.c
diff --git a/helper/eth.c b/helper/eth.c
new file mode 100644
index 000000000..9a151fa23
--- /dev/null
+++ b/helper/eth.c
@@ -0,0 +1,36 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp/helper/eth.h>
+
+#include <stdio.h>
+#include <string.h>
+
+int odph_eth_addr_parse(odph_ethaddr_t *mac, const char *str)
+{
+ int byte[ODPH_ETHADDR_LEN];
+ int i;
+
+ memset(byte, 0, sizeof(byte));
+
+ if (sscanf(str, "%x:%x:%x:%x:%x:%x",
+ &byte[0], &byte[1], &byte[2],
+ &byte[3], &byte[4], &byte[5]) != ODPH_ETHADDR_LEN)
+ return -1;
+
+ for (i = 0; i < ODPH_ETHADDR_LEN; i++)
+ if (byte[i] < 0 || byte[i] > 255)
+ return -1;
+
+ mac->addr[0] = byte[0];
+ mac->addr[1] = byte[1];
+ mac->addr[2] = byte[2];
+ mac->addr[3] = byte[3];
+ mac->addr[4] = byte[4];
+ mac->addr[5] = byte[5];
+
+ return 0;
+}
diff --git a/helper/include/odp/helper/eth.h b/helper/include/odp/helper/eth.h
index 7c9c7287a..93841bba8 100644
--- a/helper/include/odp/helper/eth.h
+++ b/helper/include/odp/helper/eth.h
@@ -18,10 +18,7 @@
extern "C" {
#endif
-#include <odp/std_types.h>
-#include <odp/byteorder.h>
-#include <odp/align.h>
-#include <odp/debug.h>
+#include <odp.h>
/** @addtogroup odph_header ODPH HEADER
* @{
@@ -85,6 +82,23 @@ _ODP_STATIC_ASSERT(sizeof(odph_vlanhdr_t) == ODPH_VLANHDR_LEN, "ODPH_VLANHDR_T__
#define ODPH_ETHTYPE_1588 0x88F7 /**< Precision Time Protocol IEEE 1588 */
/**
+ * Parse Ethernet from a string
+ *
+ * Parses Ethernet MAC address from the string which must be passed in format of
+ * six hexadecimal digits delimited by colons (xx:xx:xx:xx:xx:xx). Both upper
+ * and lower case characters are supported. All six digits have to be present
+ * and may have leading zeros. String does not have to be NULL terminated.
+ * The address is written only when successful.
+ *
+ * @param[out] mac Pointer to Ethernet address for output
+ * @param str MAC address string to be parsed
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odph_eth_addr_parse(odph_ethaddr_t *mac, const char *str);
+
+/**
* @}
*/
diff --git a/helper/test/.gitignore b/helper/test/.gitignore
index 50a0da4e6..8f107def9 100644
--- a/helper/test/.gitignore
+++ b/helper/test/.gitignore
@@ -1,7 +1,7 @@
*.trs
*.log
odp_chksum
+odp_parse
odp_process
odp_table
odp_thread
-odph_pause
diff --git a/helper/test/Makefile.am b/helper/test/Makefile.am
index bbad2a58b..918638175 100644
--- a/helper/test/Makefile.am
+++ b/helper/test/Makefile.am
@@ -7,6 +7,7 @@ TESTS_ENVIRONMENT += TEST_DIR=${builddir}
EXECUTABLES = odp_chksum$(EXEEXT) \
odp_thread$(EXEEXT) \
+ odp_parse$(EXEEXT)\
odp_process$(EXEEXT)\
odp_table$(EXEEXT)
@@ -26,6 +27,7 @@ bin_PROGRAMS = $(EXECUTABLES) $(COMPILE_ONLY)
dist_odp_chksum_SOURCES = odp_chksum.c
dist_odp_thread_SOURCES = odp_thread.c
odp_thread_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
+dist_odp_parse_SOURCES = odp_parse.c
dist_odp_process_SOURCES = odp_process.c
odp_process_LDADD = $(LIB)/libodphelper.la $(LIB)/libodp.la
dist_odp_table_SOURCES = odp_table.c
diff --git a/helper/test/odp_parse.c b/helper/test/odp_parse.c
new file mode 100644
index 000000000..f20b9096a
--- /dev/null
+++ b/helper/test/odp_parse.c
@@ -0,0 +1,205 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <test_debug.h>
+
+#include <odp.h>
+#include <odp/helper/eth.h>
+
+#include <stdio.h>
+#include <string.h>
+
+static int different_mac(odph_ethaddr_t *mac1, odph_ethaddr_t *mac2)
+{
+ return mac1->addr[0] != mac2->addr[0] ||
+ mac1->addr[1] != mac2->addr[1] ||
+ mac1->addr[2] != mac2->addr[2] ||
+ mac1->addr[3] != mac2->addr[3] ||
+ mac1->addr[4] != mac2->addr[4] ||
+ mac1->addr[5] != mac2->addr[5];
+}
+
+static int test_mac(void)
+{
+ odph_ethaddr_t mac;
+ odph_ethaddr_t ref;
+
+ memset(&ref, 0, sizeof(odph_ethaddr_t));
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+
+ /*
+ * Erroneous strings
+ */
+
+ /* String must not start with other chars */
+ if (!odph_eth_addr_parse(&mac, "foo 01:02:03:04:05:06")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Missing digit */
+ if (!odph_eth_addr_parse(&mac, "01:02:03:04:05:")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Missing colon */
+ if (!odph_eth_addr_parse(&mac, "01:02:03:04:05 06")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Too large value */
+ if (!odph_eth_addr_parse(&mac, "01:02:03:04:05:1ff")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Negative value */
+ if (!odph_eth_addr_parse(&mac, "-1:02:03:04:05:06")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Failed function call must not store address */
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Modified address when failed\n");
+ return -1;
+ }
+
+ ref.addr[0] = 1;
+ ref.addr[1] = 2;
+ ref.addr[2] = 3;
+ ref.addr[3] = 4;
+ ref.addr[4] = 5;
+ ref.addr[5] = 6;
+
+ /* Zero pre-fixed */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "01:02:03:04:05:06")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ /* Not zero pre-fixed */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "1:2:3:4:5:6")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ /* String may continue with other chars */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "01:02:03:04:05:06 foobar")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ ref.addr[0] = 0xa;
+ ref.addr[1] = 0xb;
+ ref.addr[2] = 0xc;
+ ref.addr[3] = 0xd;
+ ref.addr[4] = 0xe;
+ ref.addr[5] = 0xf;
+
+ /* Zero pre-fixed */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "0a:0b:0c:0d:0e:0f")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ /* Not zero pre-fixed */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "a:b:c:d:e:f")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ ref.addr[0] = 0x1a;
+ ref.addr[1] = 0x2b;
+ ref.addr[2] = 0x3c;
+ ref.addr[3] = 0x4d;
+ ref.addr[4] = 0x5e;
+ ref.addr[5] = 0x6f;
+
+ /* Dual digits */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "1a:2b:3c:4d:5e:6f")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ memset(&ref, 0, sizeof(odph_ethaddr_t));
+
+ /* All zeros */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "00:00:00:00:00:00")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ memset(&ref, 0xff, sizeof(odph_ethaddr_t));
+
+ /* All ones */
+ memset(&mac, 0, sizeof(odph_ethaddr_t));
+ if (odph_eth_addr_parse(&mac, "ff:ff:ff:ff:ff:ff")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_mac(&mac, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ printf("MAC address parse test successful\n");
+ return 0;
+}
+
+int main(void)
+{
+ int ret = 0;
+
+ ret += test_mac();
+
+ return ret;
+}