Created
October 25, 2019 03:17
-
-
Save Benau/03832e52abffe83404bf9624113bd45e to your computer and use it in GitHub Desktop.
ipv6 sqlite extension
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "sqlite3ext.h" | |
#include <stdlib.h> | |
#include <string.h> | |
#include <arpa/inet.h> | |
// gcc -fPIC -shared ipv6_sql.c -g -o libipv6.so | |
SQLITE_EXTENSION_INIT1 | |
static void andIPv6(struct in6_addr* ipv6, const struct in6_addr* mask) | |
{ | |
for (unsigned i = 0; i < sizeof(struct in6_addr); i++) | |
ipv6->s6_addr[i] &= mask->s6_addr[i]; | |
} | |
static int insideIPv6CIDR(const char* ipv6_cidr, const char* ipv6_in) | |
{ | |
const char* mask_location = strchr(ipv6_cidr, '/'); | |
if (mask_location == NULL) | |
return 0; | |
struct in6_addr v6_in; | |
if (inet_pton(AF_INET6, ipv6_in, &v6_in) != 1) | |
return 0; | |
char ipv6[INET6_ADDRSTRLEN] = {}; | |
memcpy(ipv6, ipv6_cidr, mask_location - ipv6_cidr); | |
struct in6_addr cidr; | |
if (inet_pton(AF_INET6, ipv6, &cidr) != 1) | |
return 0; | |
int mask_length = atoi(mask_location + 1); | |
if (mask_length > 128 || mask_length <= 0) | |
return 0; | |
struct in6_addr mask = {}; | |
for (int i = mask_length, j = 0; i > 0; i -= 8, j++) | |
{ | |
if (i >= 8) | |
mask.s6_addr[j] = 0xff; | |
else | |
mask.s6_addr[j] = (unsigned long)(0xffU << (8 - i)); | |
} | |
andIPv6(&cidr, &mask); | |
andIPv6(&v6_in, &mask); | |
for (unsigned i = 0; i < sizeof(struct in6_addr); i++) | |
{ | |
if (cidr.s6_addr[i] != v6_in.s6_addr[i]) | |
return 0; | |
} | |
return 1; | |
} | |
static void insideIPv6CIDRSQL(sqlite3_context* context, int argc, sqlite3_value** argv) | |
{ | |
if (argc != 2) | |
{ | |
sqlite3_result_int(context, 0); | |
return; | |
} | |
char* ipv6_cidr = (char*)sqlite3_value_text(argv[0]); | |
char* ipv6_in = (char*)sqlite3_value_text(argv[1]); | |
if (ipv6_cidr == NULL || ipv6_in == NULL) | |
{ | |
sqlite3_result_int(context, 0); | |
return; | |
} | |
sqlite3_result_int(context, insideIPv6CIDR(ipv6_cidr, ipv6_in)); | |
} | |
int sqlite3_extension_init(sqlite3* db, char** pzErrMsg, const sqlite3_api_routines* pApi) | |
{ | |
SQLITE_EXTENSION_INIT2(pApi) | |
sqlite3_create_function(db, "insideIPv6CIDR", 2, SQLITE_UTF8, 0, insideIPv6CIDRSQL, 0, 0); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment