Created
April 18, 2017 03:26
-
-
Save xdqi/cdd7a52f35abe77b8c63a5061220ca04 to your computer and use it in GitHub Desktop.
Add ipip.net database to MTR
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
From 1d43349759ffdf9b9d7e4961d1326119dd6c44c0 Mon Sep 17 00:00:00 2001 | |
From: Alexander Qi <xdqi@users.noreply.github.com> | |
Date: Tue, 18 Apr 2017 11:24:28 +0800 | |
Subject: [PATCH] Add IPIP support | |
--- | |
.gitignore | 2 ++ | |
Makefile.am | 4 ++- | |
configure.ac | 2 +- | |
ipip/ipip.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
ipip/ipip.h | 5 ++++ | |
ui/curses.c | 19 ++++++++------ | |
ui/ipip.c | 31 +++++++++++++++++++++++ | |
ui/ipip.h | 3 +++ | |
ui/mtr.c | 2 ++ | |
9 files changed, 140 insertions(+), 9 deletions(-) | |
create mode 100644 ipip/ipip.c | |
create mode 100644 ipip/ipip.h | |
create mode 100644 ui/ipip.c | |
create mode 100644 ui/ipip.h | |
diff --git a/.gitignore b/.gitignore | |
index d3d1068..3bf545e 100644 | |
--- a/.gitignore | |
+++ b/.gitignore | |
@@ -23,6 +23,8 @@ stamp-h1* | |
/.deps/ | |
/packet/.deps/ | |
/packet/.dirstamp | |
+/ipip/.deps/ | |
+/ipip/.dirstamp | |
/packet/testpacket.py.log | |
/packet/testpacket.py.trs | |
/test-suite.log | |
diff --git a/Makefile.am b/Makefile.am | |
index c0709ca..eca572b 100644 | |
--- a/Makefile.am | |
+++ b/Makefile.am | |
@@ -57,7 +57,9 @@ mtr_SOURCES = ui/mtr.c ui/mtr.h \ | |
packet/cmdparse.c packet/cmdparse.h \ | |
ui/mtr-curses.h \ | |
img/mtr_icon.xpm \ | |
- ui/mtr-gtk.h | |
+ ui/mtr-gtk.h \ | |
+ ipip/ipip.c ipip/ipip.h \ | |
+ ui/ipip.c ui/ipip.h | |
if WITH_ERROR | |
mtr_SOURCES += \ | |
diff --git a/configure.ac b/configure.ac | |
index a08ce67..88fdbeb 100644 | |
--- a/configure.ac | |
+++ b/configure.ac | |
@@ -100,7 +100,7 @@ AS_IF([test "x$with_ncurses" = "xyes"], | |
# Prefer ncurses over curses, if both are available. | |
# (On Solaris 11.3, ncurses builds and links for us, but curses does not.) | |
[AC_SEARCH_LIBS( | |
- [initscr], [ncurses curses], | |
+ [initscr], [ncursesw ncurses curses], | |
[AC_DEFINE([HAVE_CURSES], [1], [Define if a curses library available])], | |
[with_ncurses=no]) | |
]) | |
diff --git a/ipip/ipip.c b/ipip/ipip.c | |
new file mode 100644 | |
index 0000000..e4390a0 | |
--- /dev/null | |
+++ b/ipip/ipip.c | |
@@ -0,0 +1,81 @@ | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+ | |
+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; | |
+} | |
+ | |
diff --git a/ipip/ipip.h b/ipip/ipip.h | |
new file mode 100644 | |
index 0000000..af36eea | |
--- /dev/null | |
+++ b/ipip/ipip.h | |
@@ -0,0 +1,5 @@ | |
+#pragma once | |
+ | |
+int ipipdb_init(const char* ipdb); | |
+int ipipdb_destroy(); | |
+int ipipdb_find(const uint32_t ip, char *result); | |
diff --git a/ui/curses.c b/ui/curses.c | |
index a7588ca..ca33af2 100644 | |
--- a/ui/curses.c | |
+++ b/ui/curses.c | |
@@ -63,6 +63,7 @@ | |
#include "asn.h" | |
#include "display.h" | |
#include "utils.h" | |
+#include "ipip.h" | |
enum { NUM_FACTORS = 8 }; | |
@@ -428,13 +429,14 @@ static void mtr_curses_hosts( | |
if (is_printii(ctl)) | |
printw(fmt_ipinfo(ctl, addr)); | |
#endif | |
+ const char *ipip_location = ipip_get_location(ctl, addr); | |
if (name != NULL) { | |
if (ctl->show_ips) | |
- printw("%s (%s)", name, strlongip(ctl, addr)); | |
+ printw("%s (%s) %s", name, strlongip(ctl, addr), ipip_location); | |
else | |
- printw("%s", name); | |
+ printw("%s %s", name, ipip_location); | |
} else { | |
- printw("%s", strlongip(ctl, addr)); | |
+ printw("%s %s", strlongip(ctl, addr), ipip_location); | |
} | |
attroff(A_BOLD); | |
@@ -483,13 +485,15 @@ static void mtr_curses_hosts( | |
if (is_printii(ctl)) | |
printw(fmt_ipinfo(ctl, addrs)); | |
#endif | |
+ | |
+ const char *ipip_location = ipip_get_location(ctl, addr); | |
if (name != NULL) { | |
if (ctl->show_ips) | |
- printw("%s (%s)", name, strlongip(ctl, addrs)); | |
+ printw("%s (%s) %s", name, strlongip(ctl, addrs), ipip_location); | |
else | |
- printw("%s", name); | |
+ printw("%s %s", name, ipip_location); | |
} else { | |
- printw("%s", strlongip(ctl, addrs)); | |
+ printw("%s %s", strlongip(ctl, addrs), ipip_location); | |
} | |
for (k = 0; k < mplss->labels && ctl->enablempls; k++) { | |
printw("\n [MPLS: Lbl %lu Exp %u S %u TTL %u]", | |
@@ -642,7 +646,8 @@ static void mtr_curses_graph( | |
printw(fmt_ipinfo(ctl, addr)); | |
#endif | |
name = dns_lookup(ctl, addr); | |
- printw("%s", name ? name : strlongip(ctl, addr)); | |
+ const char *ipip_location = ipip_get_location(ctl, addr); | |
+ printw("%s %s", name ? name : strlongip(ctl, addr), ipip_location); | |
} else | |
printw("???"); | |
attroff(A_BOLD); | |
diff --git a/ui/ipip.c b/ui/ipip.c | |
new file mode 100644 | |
index 0000000..85f9cdf | |
--- /dev/null | |
+++ b/ui/ipip.c | |
@@ -0,0 +1,31 @@ | |
+#include "config.h" | |
+#include "mtr.h" | |
+#include "../ipip/ipip.h" | |
+ | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <sys/socket.h> | |
+#include <netinet/in.h> | |
+ | |
+const char *ipip_get_location(struct mtr_ctl *ctl, ip_t *ip) { | |
+ ipipdb_init("/usr/local/share/17monipdb.dat"); | |
+ static char buf[256]; | |
+ buf[0] = '\0'; | |
+ uint32_t res_ip; | |
+#ifdef ENABLE_IPV6 | |
+#define ip6 ip->s6_addr | |
+ if (ctl->af == AF_INET) { | |
+ uint32_t be_ip = *(uint32_t *)ip6; | |
+ res_ip = htonl(be_ip); | |
+ } else { | |
+ return buf; | |
+ } | |
+#else | |
+ res_ip = ntohl(ip->s_addr); | |
+#endif | |
+ strcpy(buf, "["); | |
+ ipipdb_find(res_ip, buf + 1); | |
+ strcat(buf, "]"); | |
+ return buf; | |
+} | |
diff --git a/ui/ipip.h b/ui/ipip.h | |
new file mode 100644 | |
index 0000000..351f476 | |
--- /dev/null | |
+++ b/ui/ipip.h | |
@@ -0,0 +1,3 @@ | |
+#pragma once | |
+ | |
+const char *ipip_get_location(struct mtr_ctl *ctl, ip_t *ip); | |
\ No newline at end of file | |
diff --git a/ui/mtr.c b/ui/mtr.c | |
index 70ae5c4..002bedc 100644 | |
--- a/ui/mtr.c | |
+++ b/ui/mtr.c | |
@@ -47,6 +47,7 @@ | |
#include <limits.h> | |
#include <sys/stat.h> | |
#include <sys/time.h> | |
+#include <locale.h> | |
#include "mtr.h" | |
#include "mtr-curses.h" | |
@@ -685,6 +686,7 @@ int main( | |
int argc, | |
char **argv) | |
{ | |
+ setlocale(LC_ALL, ""); // support chinese output | |
struct hostent *host = NULL; | |
struct addrinfo hints, *res; | |
int gai_error; | |
-- | |
2.12.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment