Skip to content

Instantly share code, notes, and snippets.

@xdqi
Created April 18, 2017 03:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xdqi/cdd7a52f35abe77b8c63a5061220ca04 to your computer and use it in GitHub Desktop.
Save xdqi/cdd7a52f35abe77b8c63a5061220ca04 to your computer and use it in GitHub Desktop.
Add ipip.net database to MTR
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