From e914307a4d90325a93f20a0711e3b23daf0ba9de Mon Sep 17 00:00:00 2001 From: John Jones Date: Thu, 9 Mar 2017 18:20:56 -0500 Subject: [PATCH] Added some utility methods to make parsing easier --- .cproject | 10 ++++- Makefile | 4 +- include/multiaddr/multiaddr.h | 26 ++++++++++++ multiaddr.c | 74 +++++++++++++++++++++++++++++++++++ test_multiaddr.h | 24 ++++++++++++ testing.c | 6 ++- 6 files changed, 139 insertions(+), 5 deletions(-) diff --git a/.cproject b/.cproject index b2b8c1c..eb008ef 100644 --- a/.cproject +++ b/.cproject @@ -53,7 +53,6 @@ make - all true false @@ -61,12 +60,19 @@ make - clean true false true + + make + + rebuild + true + true + true + diff --git a/Makefile b/Makefile index f85000d..fb2e223 100644 --- a/Makefile +++ b/Makefile @@ -28,4 +28,6 @@ all: test_multiaddr clean: rm -f *.o rm -f libmultiaddr.a - rm -f test_multiaddr \ No newline at end of file + rm -f test_multiaddr + +rebuild: clean all \ No newline at end of file diff --git a/include/multiaddr/multiaddr.h b/include/multiaddr/multiaddr.h index c934936..fce9162 100644 --- a/include/multiaddr/multiaddr.h +++ b/include/multiaddr/multiaddr.h @@ -50,8 +50,34 @@ void multiaddress_free(struct MultiAddress* in); struct MultiAddress* multiaddress_copy(const struct MultiAddress* source); +// helpers to parse the MultiAddress struct + int multiaddress_encapsulate(struct MultiAddress * result, char * string); int multiaddress_decapsulate(struct MultiAddress * result, char * srci); +int multiaddress_is_ip(struct MultiAddress* in); + +int multiaddress_is_ip4(struct MultiAddress* in); + +int multiaddress_is_ip6(struct MultiAddress* in); + +int multiaddress_get_ip_family(struct MultiAddress* in); + +/*** + * Pulls the textual representation of the IP address from a multihash + * @param in the multihash to parse + * @param ip where to put the ip address + * @returns true(1) on success, otherwise 0 + */ +int multiaddress_get_ip_address(struct MultiAddress* in, char** ip); + +/*** + * Pulls the IP port from a multiaddress + * @param in the multiaddress + * @param port where to put the port + * @returns the port, or a negative number for an error + */ +int multiaddress_get_ip_port(struct MultiAddress* in); + #endif diff --git a/multiaddr.c b/multiaddr.c index b6716b6..6cafd20 100644 --- a/multiaddr.c +++ b/multiaddr.c @@ -1,4 +1,6 @@ #include +#include + #include "multiaddr/varhexutils.h" #include "multiaddr/varint.h" #include "multiaddr/protocols.h" @@ -81,6 +83,78 @@ struct MultiAddress* multiaddress_new_from_string(const char* straddress)//Const return out; } +int multiaddress_is_ip(struct MultiAddress* in) { + int byte = in->bytes[0]; + + if (byte == 4 || byte == 41) + return 1; + return 0; +} +int multiaddress_is_ip4(struct MultiAddress* in) { + return in->bytes[0] == 4; +} + +int multiaddress_is_ip6(struct MultiAddress* in) { + return in->bytes[0] == 41; +} + + +int multiaddress_get_ip_family(struct MultiAddress* in) { + if (in->bytes[0] == 4) + return AF_INET; + if (in->bytes[0] == 41) + return AF_INET6; + return 0; +} + +/*** + * Pulls the textual representation of the IP address from a multihash + * @param in the multihash to parse + * @param ip where to put the ip address + * @returns true(1) on success, otherwise 0 + */ +int multiaddress_get_ip_address(struct MultiAddress* in, char** ip) { + // the incoming address is not what was expected + if (strncmp(in->string, "/ip4/", 5) != 0 && strncmp(in->string, "/ip6/", 5) != 0) + return 0; + if (strstr(in->string, "/tcp/") == NULL && strstr(in->string, "/udp/") != NULL) + return 0; + // ip + char* str = malloc(strlen(in->string)); + if (str == NULL) + return 0; + strcpy(str, &in->string[5]); // gets rid of /ip4/ + char* pos = strchr(str, '/'); + pos[0] = 0; + *ip = malloc(strlen(str) + 1); + strcpy(*ip, str); + free(str); + return 0; +} + +/*** + * Pulls the IP port from a multiaddress + * @param in the multiaddress + * @param port where to put the port + * @returns the port, or a negative number for an error + */ +int multiaddress_get_ip_port(struct MultiAddress* in) { + char* ptr = strstr(in->string, "/tcp/"); + if (ptr == NULL) + ptr = strstr(in->string, "/udp/"); + if (ptr == NULL) + return -1; + ptr += 5; + char* end_ptr = strstr(ptr, "/"); + if (end_ptr == NULL) { + return atoi(ptr); + } + char str[end_ptr - ptr + 1]; + memcpy(str, ptr, end_ptr - ptr); + str[end_ptr-ptr] = '\0'; + return atoi(str); +} + void multiaddress_free(struct MultiAddress* in) { if (in != NULL) { if (in->bytes != NULL) diff --git a/test_multiaddr.h b/test_multiaddr.h index f3ca1ee..9a2e68e 100644 --- a/test_multiaddr.h +++ b/test_multiaddr.h @@ -68,3 +68,27 @@ int test_int_to_hex() { return 1; } +int test_multiaddr_utils() { + struct MultiAddress* addr = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001"); + if (!multiaddress_is_ip(addr)) { + fprintf(stderr, "The address should be an IP\n"); + return 0; + } + char* ip = NULL; + multiaddress_get_ip_address(addr, &ip); + if (ip == NULL) { + fprintf(stderr, "get_ip_address returned NULL\n"); + return 0; + } + if(strcmp(ip, "127.0.0.1") != 0) { + fprintf(stderr, "ip addresses are not equal\n"); + return 0; + } + int port = multiaddress_get_ip_port(addr); + if (port != 4001) { + fprintf(stderr, "port incorrect. %d was returned instead of %d\n", port, 4001); + return 0; + } + return 1; +} + diff --git a/testing.c b/testing.c index 7c7bd48..d77c42d 100644 --- a/testing.c +++ b/testing.c @@ -6,14 +6,16 @@ const char* names[] = { "test_new_from_string", "test_full", "test_hex_to_var", - "test_int_to_hex" + "test_int_to_hex", + "test_multiaddr_utils" }; int (*funcs[])(void) = { test_new_from_string, test_full, test_hex_to_var, - test_int_to_hex + test_int_to_hex, + test_multiaddr_utils }; int testit(const char* name, int (*func)(void)) {