diff --git a/binding/c/test_util b/binding/c/test_util index bc93a29..6f2c779 100755 Binary files a/binding/c/test_util and b/binding/c/test_util differ diff --git a/binding/c/xdb_api.h b/binding/c/xdb_api.h index 21e28d3..af846cc 100644 --- a/binding/c/xdb_api.h +++ b/binding/c/xdb_api.h @@ -34,9 +34,19 @@ #define xdb_vector_index_size 8 #define xdb_segment_index_size 14 +// --- ip version info +#define xdb_ipv4_version_no 4 +#define xdb_ipv6_version_no 6 +#define XDB_IPV4 4 +#define XDB_IPv6 6 + // cache of vector_index_row × vector_index_rows × vector_index_size #define xdb_vector_index_length 524288 +// types type define +typedef char string_ip_t; +typedef unsigned char bytes_ip_t; + // --- xdb util functions // get the current time in microseconds @@ -55,15 +65,32 @@ XDB_PUBLIC(int) xdb_check_ip(const char *, unsigned int *); XDB_PUBLIC(void) xdb_long2ip(unsigned int, char *); -// parse the specified IP address to byte array -XDB_PUBLIC(int) xdb_parse_ip(const char *, const char *, size_t); +// parse the specified IP address to byte array. +// returns: 4 for valid ipv4, 16 for valid ipv6, or -1 for failed +XDB_PUBLIC(int) xdb_parse_ip(const string_ip_t *, bytes_ip_t *, size_t); -// convert a specified ip bytes to humen-readable string -XDB_PUBLIC(int) xdb_ip_to_string(const char *, size_t); +// parse the specified IPv4 address to byte array +// returns: 4 for valid ipv4, or -1 for failed +XDB_PUBLIC(int) xdb_parse_v4_ip(const string_ip_t *, bytes_ip_t *, size_t); + +// parse the specified IPv6 address to byte array +// returns: 16 for valid ipv6, or -1 for failed +XDB_PUBLIC(int) xdb_parse_v6_ip(const string_ip_t *, bytes_ip_t *, size_t); + +// convert a specified ip bytes to humen-readable string. +// returns: 0 for success or -1 for failed. +XDB_PUBLIC(int) xdb_ip_to_string(const bytes_ip_t *, size_t, char *, size_t); + +// ipv4 bytes to string +XDB_PUBLIC(int) xdb_v4_ip_to_string(const bytes_ip_t *, char *, size_t); + +// ipv6 bytes to string +XDB_PUBLIC(int) xdb_v6_ip_to_string(const bytes_ip_t *, char *, size_t); // compare the specified ip bytes with another ip bytes in the specified buff from offset. +// ip args must be the return value from #xdb_parse_ip. // returns: -1 if ip1 < ip2, 1 if ip1 > ip2 or 0 -XDB_PUBLIC(int) xdb_ip_sub_compare(const char *, const char *, int, size_t); +XDB_PUBLIC(int) xdb_ip_sub_compare(const bytes_ip_t *, size_t, const char *, int); // --- END xdb utils diff --git a/binding/c/xdb_util.c b/binding/c/xdb_util.c index 2c0f034..812f7b4 100644 --- a/binding/c/xdb_util.c +++ b/binding/c/xdb_util.c @@ -96,15 +96,73 @@ XDB_PUBLIC(void) xdb_long2ip(unsigned int ip, char *buffer) { sprintf(buffer, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); } -XDB_PUBLIC(int) xdb_parse_ip(const char *ip, const char *buffer, size_t length) { +XDB_PUBLIC(int) xdb_parse_ip(const string_ip_t *ip, bytes_ip_t *buffer, size_t length) { + // where there is a . there is a IPV4 even though there are IPv6 wrapped IPv4 like + // ::ffff:192.168.1.100, lets just keep it in this way. + if (strchr(ip, '.') != NULL) { + return xdb_parse_v4_ip(ip, buffer, length); + } else if (strchr(ip, ':') != NULL) { + return xdb_parse_v6_ip(ip, buffer, length); + } + + return -1; +} + +XDB_PUBLIC(int) xdb_parse_v4_ip(const string_ip_t *ip, bytes_ip_t *buffer, size_t length) { return 0; } -XDB_PUBLIC(int) xdb_ip_to_string(const char *bytes, size_t length) { +XDB_PUBLIC(int) xdb_parse_v6_ip(const string_ip_t *ip, bytes_ip_t *buffer, size_t length) { return 0; } -XDB_PUBLIC(int) xdb_ip_sub_compare(const char *ip1, const char *buffer, int offset, size_t length) { +XDB_PUBLIC(int) xdb_ip_to_string(const bytes_ip_t *ip, size_t bytes, char *buffer, size_t length) { + if (bytes == 4) { + return xdb_v4_ip_to_string(ip, buffer, length); + } else if (bytes == 16) { + return xdb_v6_ip_to_string(ip, buffer, length); + } + + return -1; +} + +XDB_PUBLIC(int) xdb_v4_ip_to_string(const bytes_ip_t *ip, char *buffer, size_t length) { + snprintf( + buffer, length, + "%d.%d.%d.%d", + ip[0], ip[1], ip[2], ip[3] + ); + return 0; +} + +XDB_PUBLIC(int) xdb_v6_ip_to_string(const bytes_ip_t *ip, char *buffer, size_t length) { + // temp solution for testing ONLY, we will handle the :: later + snprintf( + buffer, length, + "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", + ip[0], ip[1], + ip[2], ip[3], + ip[4], ip[5], + ip[6], ip[7], + ip[8], ip[9], + ip[10], ip[11], + ip[12], ip[13], + ip[14], ip[15] + ); + return 0; +} + +XDB_PUBLIC(int) xdb_ip_sub_compare(const bytes_ip_t *ip1, size_t length, const char *buffer, int offset) { + int i, i1, i2; + for (i = 0; i < length; i++) { + i1 = ip1[i] & 0xFF; + i2 = buffer[offset + i] & 0xFF; + if (i1 > i2) { + return 1; + } else if (i1 < i2) { + return -1; + } + } return 0; }