Skip to content

Instantly share code, notes, and snippets.

@Benau
Created October 25, 2019 03:17
Show Gist options
  • Save Benau/03832e52abffe83404bf9624113bd45e to your computer and use it in GitHub Desktop.
Save Benau/03832e52abffe83404bf9624113bd45e to your computer and use it in GitHub Desktop.
ipv6 sqlite extension
#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