Created
April 18, 2017 06:09
-
-
Save xdqi/bf0d3886c60e429dceb0f4aeafab4a29 to your computer and use it in GitHub Desktop.
Add IPIP geolocation display to BIND 9.11.0-P3.patch
This file contains hidden or 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
From 42081ef76faf196ca354622a18885f3f7677ded5 Mon Sep 17 00:00:00 2001 | |
From: Alexander Qi <[email protected]> | |
Date: Tue, 18 Apr 2017 14:05:03 +0800 | |
Subject: [PATCH] Add IPIP geolocation display to BIND-9.11.0-P3 | |
--- | |
bin/dig/nslookup.c | 3 +- | |
lib/dns/rdata.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++- | |
2 files changed, 96 insertions(+), 2 deletions(-) | |
diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c | |
index f00ab45..bc990b6 100644 | |
--- a/bin/dig/nslookup.c | |
+++ b/bin/dig/nslookup.c | |
@@ -185,7 +185,8 @@ printsoa(dns_rdata_t *rdata) { | |
static void | |
printaddr(dns_rdata_t *rdata) { | |
isc_result_t result; | |
- char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; | |
+ //char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; | |
+ char text[256]; | |
isc_buffer_t b; | |
isc_buffer_init(&b, text, sizeof(text)); | |
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c | |
index 83dc7f8..76e7995 100644 | |
--- a/lib/dns/rdata.c | |
+++ b/lib/dns/rdata.c | |
@@ -1707,13 +1707,106 @@ str_totext(const char *source, isc_buffer_t *target) { | |
return (ISC_R_SUCCESS); | |
} | |
+typedef unsigned char byte; | |
+typedef unsigned int uint; | |
+#define B2IL(b) (((b)[0] & 0xFF) | (((b)[1] << 8) & 0xFF00) | (((b)[2] << 16) & 0xFF0000) | (((b)[3] << 24) & 0xFF000000)) | |
+#define B2IU(b) (((b)[3] & 0xFF) | (((b)[2] << 8) & 0xFF00) | (((b)[1] << 16) & 0xFF0000) | (((b)[0] << 24) & 0xFF000000)) | |
+ | |
+struct { | |
+ byte *data; | |
+ byte *index; | |
+ uint *flag; | |
+ uint offset; | |
+} ipip; | |
+ | |
+int ipipdb_destroy() { | |
+ if (!ipip.offset) { | |
+ return 0; | |
+ } | |
+ free(ipip.flag); | |
+ free(ipip.index); | |
+ free(ipip.data); | |
+ ipip.offset = 0; | |
+ return 0; | |
+} | |
+ | |
+int ipipdb_init(const char *ipdb) { | |
+ if (ipip.offset) { | |
+ return 0; | |
+ } | |
+ FILE *file = fopen(ipdb, "rb"); | |
+ fseek(file, 0, SEEK_END); | |
+ long size = ftell(file); | |
+ fseek(file, 0, SEEK_SET); | |
+ | |
+ ipip.data = (byte *) malloc(size * sizeof(byte)); | |
+ size_t r = fread(ipip.data, sizeof(byte), (size_t) size, file); | |
+ | |
+ if (r == 0) { | |
+ return 0; | |
+ } | |
+ | |
+ fclose(file); | |
+ | |
+ uint length = B2IU(ipip.data); | |
+ | |
+ ipip.index = (byte *) malloc(length * sizeof(byte)); | |
+ memcpy(ipip.index, ipip.data + 4, length); | |
+ | |
+ ipip.offset = length; | |
+ | |
+ ipip.flag = (uint *) malloc(256 * sizeof(uint)); | |
+ memcpy(ipip.flag, ipip.index, 256 * sizeof(uint)); | |
+ | |
+ return 0; | |
+} | |
+ | |
+int ipipdb_find(const uint32_t ip, char *result) { | |
+ uint ip_prefix_value = (ip & 0xFF000000) >> 24; | |
+ uint start = ipip.flag[ip_prefix_value]; | |
+ uint max_comp_len = ipip.offset - 1028; | |
+ uint index_offset = 0; | |
+ uint index_length = 0; | |
+ for (start = start * 8 + 1024; start < max_comp_len; start += 8) { | |
+ if (B2IU(ipip.index + start) >= ip) { | |
+ index_offset = B2IL(ipip.index + start + 4) & 0x00FFFFFF; | |
+ index_length = ipip.index[start + 7]; | |
+ break; | |
+ } | |
+ } | |
+ memcpy(result, ipip.data + ipip.offset + index_offset - 1024, index_length); | |
+ result[index_length] = '\0'; | |
+ for (int i = 0; i < index_length; i++) { | |
+ if (result[i] == '\t') { | |
+ result[i] = ' '; | |
+ } | |
+ } | |
+ return 0; | |
+} | |
+ | |
+ | |
+static const char *ipip_get_location(struct in6_addr *ip) { | |
+ ipipdb_init("/usr/local/share/17monipdb.dat"); | |
+ static char buf[192]; | |
+ buf[0] = '\0'; | |
+ uint32_t be_ip = *(uint32_t *)(ip->s6_addr); | |
+ uint32_t res_ip = htonl(be_ip); | |
+ strcpy(buf, " ["); | |
+ ipipdb_find(res_ip, buf + 2); | |
+ strcat(buf, "]"); | |
+ return buf; | |
+} | |
+ | |
static isc_result_t | |
inet_totext(int af, isc_region_t *src, isc_buffer_t *target) { | |
- char tmpbuf[64]; | |
+ char tmpbuf[256]; | |
/* Note - inet_ntop doesn't do size checking on its input. */ | |
if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL) | |
return (ISC_R_NOSPACE); | |
+ if (af == AF_INET) { | |
+ strcat(tmpbuf, ipip_get_location((struct in6_addr *) src->base)); | |
+ } | |
if (strlen(tmpbuf) > isc_buffer_availablelength(target)) | |
return (ISC_R_NOSPACE); | |
isc_buffer_putstr(target, tmpbuf); | |
-- | |
2.12.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment