aboutsummaryrefslogtreecommitdiff
path: root/helper
diff options
context:
space:
mode:
authorPetri Savolainen <petri.savolainen@nokia.com>2016-02-09 14:25:08 +0200
committerMaxim Uvarov <maxim.uvarov@linaro.org>2016-03-03 22:32:04 +0300
commit96cef77a0aad6940f5b210277ffb0bccb6e5b3c1 (patch)
tree55001f97f8d7d94200e8d27ab035a9b5cca3ab97 /helper
parentcc03b63e667c3acf580f20765910dbb342d452b2 (diff)
helper: ip: added ipv4 address parse
IPv4 address parse function is commonly needed by test applications. A common parse function harmonizes the definition IPv4 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/include/odp/helper/ip.h22
-rw-r--r--helper/ip.c30
-rw-r--r--helper/test/odp_parse.c153
4 files changed, 203 insertions, 3 deletions
diff --git a/helper/Makefile.am b/helper/Makefile.am
index 6f6d6cd28..4753c48fe 100644
--- a/helper/Makefile.am
+++ b/helper/Makefile.am
@@ -29,6 +29,7 @@ noinst_HEADERS = \
__LIB__libodphelper_la_SOURCES = \
eth.c \
+ ip.c \
linux.c \
hashtable.c \
lineartable.c
diff --git a/helper/include/odp/helper/ip.h b/helper/include/odp/helper/ip.h
index 2fa4aae47..769384f62 100644
--- a/helper/include/odp/helper/ip.h
+++ b/helper/include/odp/helper/ip.h
@@ -18,9 +18,7 @@
extern "C" {
#endif
-#include <odp/align.h>
-#include <odp/debug.h>
-#include <odp/byteorder.h>
+#include <odp.h>
#include <odp/helper/chksum.h>
#include <string.h>
@@ -32,6 +30,7 @@ extern "C" {
#define ODPH_IPV4 4 /**< IP version 4 */
#define ODPH_IPV4HDR_LEN 20 /**< Min length of IP header (no options) */
#define ODPH_IPV4HDR_IHL_MIN 5 /**< Minimum IHL value*/
+#define ODPH_IPV4ADDR_LEN 4 /**< IPv4 address length in bytes */
/** @internal Returns IPv4 version */
#define ODPH_IPV4HDR_VER(ver_ihl) (((ver_ihl) & 0xf0) >> 4)
@@ -176,6 +175,23 @@ typedef struct ODP_PACKED {
/**@}*/
/**
+ * Parse IPv4 address from a string
+ *
+ * Parses IPv4 address from the string which must be passed in the format of
+ * four decimal digits delimited by dots (xxx.xxx.xxx.xxx). All four 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. The address
+ * byte order is CPU native.
+ *
+ * @param[out] ip_addr Pointer to IPv4 address for output (in native endian)
+ * @param str IPv4 address string to be parsed
+ *
+ * @retval 0 on success
+ * @retval <0 on failure
+ */
+int odph_ipv4_addr_parse(uint32_t *ip_addr, const char *str);
+
+/**
* @}
*/
#ifdef __cplusplus
diff --git a/helper/ip.c b/helper/ip.c
new file mode 100644
index 000000000..eb73e5a08
--- /dev/null
+++ b/helper/ip.c
@@ -0,0 +1,30 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <odp/helper/ip.h>
+
+#include <stdio.h>
+#include <string.h>
+
+int odph_ipv4_addr_parse(uint32_t *ip_addr, const char *str)
+{
+ unsigned byte[ODPH_IPV4ADDR_LEN];
+ int i;
+
+ memset(byte, 0, sizeof(byte));
+
+ if (sscanf(str, "%u.%u.%u.%u",
+ &byte[0], &byte[1], &byte[2], &byte[3]) != ODPH_IPV4ADDR_LEN)
+ return -1;
+
+ for (i = 0; i < ODPH_IPV4ADDR_LEN; i++)
+ if (byte[i] > 255)
+ return -1;
+
+ *ip_addr = byte[0] << 24 | byte[1] << 16 | byte[2] << 8 | byte[3];
+
+ return 0;
+}
diff --git a/helper/test/odp_parse.c b/helper/test/odp_parse.c
index f20b9096a..77c506b17 100644
--- a/helper/test/odp_parse.c
+++ b/helper/test/odp_parse.c
@@ -8,6 +8,7 @@
#include <odp.h>
#include <odp/helper/eth.h>
+#include <odp/helper/ip.h>
#include <stdio.h>
#include <string.h>
@@ -22,6 +23,11 @@ static int different_mac(odph_ethaddr_t *mac1, odph_ethaddr_t *mac2)
mac1->addr[5] != mac2->addr[5];
}
+static int different_ipv4(uint32_t *ip_addr1, uint32_t *ip_addr2)
+{
+ return *ip_addr1 != *ip_addr2;
+}
+
static int test_mac(void)
{
odph_ethaddr_t mac;
@@ -195,11 +201,158 @@ static int test_mac(void)
return 0;
}
+static int test_ipv4(void)
+{
+ uint32_t ip_addr;
+ uint32_t ref;
+
+ ip_addr = 0;
+ ref = 0;
+
+ /*
+ * Erroneous strings
+ */
+
+ /* String must not start with other chars */
+ if (!odph_ipv4_addr_parse(&ip_addr, "foo 1.2.3.4")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Missing digit */
+ if (!odph_ipv4_addr_parse(&ip_addr, "1.2.3.")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Missing dot */
+ if (!odph_ipv4_addr_parse(&ip_addr, "1.2.3 4")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Too large value */
+ if (!odph_ipv4_addr_parse(&ip_addr, "1.2.3.256")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Negative value */
+ if (!odph_ipv4_addr_parse(&ip_addr, "-1.2.3.4")) {
+ LOG_ERR("Accepted bad string\n");
+ return -1;
+ }
+
+ /* Failed function call must not store address */
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Modified address when failed\n");
+ return -1;
+ }
+
+ ref = 0x01020304;
+
+ /* Zero pre-fixed */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "001.002.003.004")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ /* Not zero pre-fixed */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "1.2.3.4")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ /* String may continue with other chars */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "1.2.3.4 foobar")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ ref = 0x1a2b3c4d;
+
+ /* Dual digits */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "26.43.60.77")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ ref = 0xa1b2c3d4;
+
+ /* Triple digits */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "161.178.195.212")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ ref = 0;
+
+ /* All zeros */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "0.0.0.0")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ ref = 0xffffffff;
+
+ /* All ones */
+ ip_addr = 0;
+ if (odph_ipv4_addr_parse(&ip_addr, "255.255.255.255")) {
+ LOG_ERR("Parse call failed\n");
+ return -1;
+ }
+
+ if (different_ipv4(&ip_addr, &ref)) {
+ LOG_ERR("Bad parse result\n");
+ return -1;
+ }
+
+ printf("IPv4 address parse test successful\n");
+ return 0;
+}
+
int main(void)
{
int ret = 0;
ret += test_mac();
+ ret += test_ipv4();
return ret;
}