diff options
author | Petri Savolainen <petri.savolainen@nokia.com> | 2016-02-09 14:25:07 +0200 |
---|---|---|
committer | Maxim Uvarov <maxim.uvarov@linaro.org> | 2016-03-03 22:32:04 +0300 |
commit | cc03b63e667c3acf580f20765910dbb342d452b2 (patch) | |
tree | 491fc29041a2f0e75f9e4f89bfc1ae7ad268de80 /helper | |
parent | 0ebc7f2d0788a2adec58e25032ba2317f9e089ac (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.am | 1 | ||||
-rw-r--r-- | helper/eth.c | 36 | ||||
-rw-r--r-- | helper/include/odp/helper/eth.h | 22 | ||||
-rw-r--r-- | helper/test/.gitignore | 2 | ||||
-rw-r--r-- | helper/test/Makefile.am | 2 | ||||
-rw-r--r-- | helper/test/odp_parse.c | 205 |
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; +} |