summaryrefslogtreecommitdiffstats
path: root/mmdbresolve.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /mmdbresolve.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mmdbresolve.c')
-rw-r--r--mmdbresolve.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/mmdbresolve.c b/mmdbresolve.c
new file mode 100644
index 00000000..5669e89e
--- /dev/null
+++ b/mmdbresolve.c
@@ -0,0 +1,203 @@
+/* Read IPv4 and IPv6 addresses on stdin and print their MMDB entries on stdout.
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program uses the MaxMind DB library (libmaxminddb) and MUST be
+ * compatible with its license (Apache 2.0).
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <maxminddb.h>
+
+#define MAX_ADDR_LEN 46
+#define MMDBR_STRINGIFY(x) MMDBR_STRINGIFY_S(x)
+#define MMDBR_STRINGIFY_S(s) #s
+#define OUT_BUF_SIZE 65536
+
+// Uncomment to enable slow lookups. Only useful on Windows for now.
+// #define MMDB_DEBUG_SLOW 1
+
+#ifdef MMDB_DEBUG_SLOW
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+#endif
+
+static const char *co_iso_key[] = {"country", "iso_code", NULL};
+static const char *co_name_key[] = {"country", "names", "en", NULL};
+static const char *ci_name_key[] = {"city", "names", "en", NULL};
+static const char *asn_o_key[] = {"autonomous_system_organization", NULL};
+static const char *asn_key[] = {"autonomous_system_number", NULL};
+static const char *l_lat_key[] = {"location", "latitude", NULL};
+static const char *l_lon_key[] = {"location", "longitude", NULL};
+static const char *l_accuracy_key[] = {"location", "accuracy_radius", NULL};
+static const char *empty_key[] = {NULL};
+
+static const char **lookup_keys[] = {
+ co_iso_key,
+ co_name_key,
+ ci_name_key,
+ asn_o_key,
+ asn_key,
+ l_lat_key,
+ l_lon_key,
+ l_accuracy_key,
+ empty_key
+};
+
+static void exit_err(void) {
+ fprintf(stderr, "Usage: mmdbresolve -f db_file [-f db_file ...]\n");
+ exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char addr_str[MAX_ADDR_LEN+1];
+ size_t mmdb_count = 0;
+ MMDB_s *mmdbs = NULL, *new_mmdbs;
+ int mmdb_err;
+
+ char *out_buf = (char *) malloc(OUT_BUF_SIZE);
+ if (out_buf == NULL) {
+ fprintf(stdout, "ERROR: malloc failed\n");
+ return 1;
+ }
+ setvbuf(stdout, out_buf, _IOFBF, OUT_BUF_SIZE);
+
+ fprintf(stdout, "[init]\n");
+
+ // If we need to handle anything beyond "-f" we'll probably want to
+ // link with GLib and use GOption.
+ int arg_idx = 0;
+ while (arg_idx < argc - 1) {
+ if (strcmp(argv[arg_idx], "-f") == 0) {
+ arg_idx++;
+ const char *db_arg = argv[arg_idx];
+ MMDB_s try_mmdb;
+ mmdb_err = MMDB_open(db_arg, 0, &try_mmdb);
+ fprintf(stdout, "db.%zd.path: %s\n", mmdb_count, db_arg);
+ fprintf(stdout, "db.%zd.status: ", mmdb_count);
+ if (mmdb_err == MMDB_SUCCESS) {
+ mmdb_count++;
+ new_mmdbs = (MMDB_s *) realloc(mmdbs, mmdb_count * sizeof(MMDB_s));
+ if (new_mmdbs == NULL) {
+ free(mmdbs);
+ fprintf(stdout, "ERROR out of memory\n");
+ return 1;
+ }
+ mmdbs = new_mmdbs;
+ mmdbs[mmdb_count - 1] = try_mmdb;
+ fprintf(stdout, "OK\n");
+ fprintf(stdout, "db.%zd.type: %s\n", mmdb_count, mmdbs[mmdb_count - 1].metadata.database_type);
+ } else {
+ fprintf(stdout, "ERROR %s\n", MMDB_strerror(mmdb_err));
+ }
+ }
+ arg_idx++;
+ }
+
+ fprintf(stdout, "mmdbresolve.status: %s\n", mmdb_count > 0 ? "true": "false");
+ fprintf(stdout, "# End init\n");
+ fflush(stdout);
+
+ if (arg_idx != argc || mmdb_count < 1) {
+ exit_err();
+ }
+
+ int in_items = 0;
+ while (in_items != EOF) {
+ int gai_err;
+
+ in_items = fscanf(stdin, "%" MMDBR_STRINGIFY(MAX_ADDR_LEN) "s", addr_str);
+
+ if (in_items < 1) {
+ continue;
+ }
+
+ fprintf(stdout, "[%s]\n", addr_str);
+
+#ifdef MMDB_DEBUG_SLOW
+#ifdef _WIN32
+ Sleep(1000);
+#endif
+#endif
+
+ for (size_t mmdb_idx = 0; mmdb_idx < mmdb_count; mmdb_idx++) {
+ fprintf(stdout, "# %s\n", mmdbs[mmdb_idx].metadata.database_type);
+ MMDB_lookup_result_s result = MMDB_lookup_string(&mmdbs[mmdb_idx], addr_str, &gai_err, &mmdb_err);
+
+ if (result.found_entry && gai_err == 0 && mmdb_err == MMDB_SUCCESS) {
+ for (size_t key_idx = 0; lookup_keys[key_idx][0]; key_idx++) {
+ MMDB_entry_data_s entry_data;
+ int status = MMDB_aget_value(&result.entry, &entry_data, lookup_keys[key_idx]);
+ if (status == MMDB_SUCCESS && entry_data.has_data) {
+ char *sep = "";
+ for (int idx = 0; lookup_keys[key_idx][idx] != 0; idx++) {
+ fprintf(stdout, "%s%s", sep, lookup_keys[key_idx][idx]);
+ sep = ".";
+ }
+ switch (entry_data.type) {
+ case MMDB_DATA_TYPE_UTF8_STRING:
+ {
+ char len_fmt[12]; // : %.xxxxxs\n\0
+ snprintf(len_fmt, 11, ": %%.%us\n", entry_data.data_size);
+ fprintf(stdout, len_fmt, entry_data.utf8_string);
+ }
+ break;
+ case MMDB_DATA_TYPE_UINT16:
+ fprintf(stdout, ": %u\n", entry_data.uint16);
+ break;
+ case MMDB_DATA_TYPE_UINT32:
+ fprintf(stdout, ": %u\n", entry_data.uint32);
+ break;
+ case MMDB_DATA_TYPE_INT32:
+ fprintf(stdout, ": %d\n", entry_data.int32);
+ break;
+ case MMDB_DATA_TYPE_BOOLEAN:
+ fprintf(stdout, ": %s\n", entry_data.boolean ? "True" : "False");
+ break;
+ case MMDB_DATA_TYPE_DOUBLE:
+ fprintf(stdout, ": %f\n", entry_data.double_value);
+ break;
+ case MMDB_DATA_TYPE_FLOAT:
+ fprintf(stdout, ": %f\n", entry_data.float_value);
+ break;
+ default:
+ fprintf(stdout, ": UNKNOWN (%u)\n", entry_data.type);
+ }
+ }
+ }
+ } else {
+ // dump error info.
+ }
+ }
+ fprintf(stdout, "# End %s\n", addr_str);
+ fflush(stdout);
+ }
+
+ free(mmdbs);
+
+ return 0;
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */