geoip2_c 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/ext/geoip2/libmaxminddb/.gitignore +35 -0
  3. data/ext/geoip2/libmaxminddb/.gitmodules +9 -0
  4. data/ext/geoip2/libmaxminddb/.perltidyrc +11 -0
  5. data/ext/geoip2/libmaxminddb/.travis.yml +48 -0
  6. data/ext/geoip2/libmaxminddb/.uncrustify.cfg +78 -0
  7. data/ext/geoip2/libmaxminddb/AUTHORS +0 -0
  8. data/ext/geoip2/libmaxminddb/Changes.md +238 -0
  9. data/ext/geoip2/libmaxminddb/LICENSE +202 -0
  10. data/ext/geoip2/libmaxminddb/Makefile.am +41 -0
  11. data/ext/geoip2/libmaxminddb/NOTICE +13 -0
  12. data/ext/geoip2/libmaxminddb/README.dev.md +58 -0
  13. data/ext/geoip2/libmaxminddb/README.md +122 -0
  14. data/ext/geoip2/libmaxminddb/appveyor.yml +33 -0
  15. data/ext/geoip2/libmaxminddb/bin/Makefile.am +5 -0
  16. data/ext/geoip2/libmaxminddb/bin/mmdblookup.c +397 -0
  17. data/ext/geoip2/libmaxminddb/bootstrap +21 -0
  18. data/ext/geoip2/libmaxminddb/common.mk +7 -0
  19. data/ext/geoip2/libmaxminddb/configure.ac +132 -0
  20. data/ext/geoip2/libmaxminddb/dev-bin/make-man-pages.pl +76 -0
  21. data/ext/geoip2/libmaxminddb/dev-bin/ppa-release.sh +50 -0
  22. data/ext/geoip2/libmaxminddb/dev-bin/regen-prototypes.pl +136 -0
  23. data/ext/geoip2/libmaxminddb/dev-bin/regen-win32-test-projs.pl +54 -0
  24. data/ext/geoip2/libmaxminddb/dev-bin/release.sh +106 -0
  25. data/ext/geoip2/libmaxminddb/dev-bin/uncrustify-all.sh +21 -0
  26. data/ext/geoip2/libmaxminddb/dev-bin/valgrind-all.pl +46 -0
  27. data/ext/geoip2/libmaxminddb/doc/libmaxminddb.md +889 -0
  28. data/ext/geoip2/libmaxminddb/doc/mmdblookup.md +103 -0
  29. data/ext/geoip2/libmaxminddb/include/maxminddb.h +232 -0
  30. data/ext/geoip2/libmaxminddb/include/maxminddb_config.h.in +14 -0
  31. data/ext/geoip2/libmaxminddb/projects/VS12/README.md +59 -0
  32. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-release.props +32 -0
  33. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-x64.props +14 -0
  34. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.props +32 -0
  35. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.sln +150 -0
  36. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj +141 -0
  37. data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj.filters +26 -0
  38. data/ext/geoip2/libmaxminddb/projects/VS12/maxminddb_config.h +14 -0
  39. data/ext/geoip2/libmaxminddb/projects/VS12-tests/bad_pointers.vcxproj +105 -0
  40. data/ext/geoip2/libmaxminddb/projects/VS12-tests/basic_lookup.vcxproj +105 -0
  41. data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_entry_list.vcxproj +105 -0
  42. data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_types.vcxproj +105 -0
  43. data/ext/geoip2/libmaxminddb/projects/VS12-tests/dump.vcxproj +105 -0
  44. data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value.vcxproj +105 -0
  45. data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value_pointer_bug.vcxproj +105 -0
  46. data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv4_start_cache.vcxproj +105 -0
  47. data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv6_lookup_in_ipv4.vcxproj +105 -0
  48. data/ext/geoip2/libmaxminddb/projects/VS12-tests/libtap.vcxproj +85 -0
  49. data/ext/geoip2/libmaxminddb/projects/VS12-tests/maxminddb_test_helper.vcxproj +107 -0
  50. data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata.vcxproj +105 -0
  51. data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata_pointers.vcxproj +105 -0
  52. data/ext/geoip2/libmaxminddb/projects/VS12-tests/no_map_get_value.vcxproj +105 -0
  53. data/ext/geoip2/libmaxminddb/projects/VS12-tests/read_node.vcxproj +105 -0
  54. data/ext/geoip2/libmaxminddb/projects/VS12-tests/shared.vcxproj +104 -0
  55. data/ext/geoip2/libmaxminddb/projects/VS12-tests/threads.vcxproj +103 -0
  56. data/ext/geoip2/libmaxminddb/projects/VS12-tests/version.vcxproj +105 -0
  57. data/ext/geoip2/libmaxminddb/projects/test.vcxproj.template +105 -0
  58. data/ext/geoip2/libmaxminddb/src/Makefile.am +9 -0
  59. data/ext/geoip2/libmaxminddb/src/libmaxminddb.pc.in +11 -0
  60. data/ext/geoip2/libmaxminddb/src/maxminddb-compat-util.h +167 -0
  61. data/ext/geoip2/libmaxminddb/src/maxminddb.c +2171 -0
  62. data/ext/geoip2/libmaxminddb/t/Makefile.am +23 -0
  63. data/ext/geoip2/libmaxminddb/t/bad_databases_t.c +66 -0
  64. data/ext/geoip2/libmaxminddb/t/bad_pointers_t.c +53 -0
  65. data/ext/geoip2/libmaxminddb/t/basic_lookup_t.c +172 -0
  66. data/ext/geoip2/libmaxminddb/t/compile_c++_t.pl +107 -0
  67. data/ext/geoip2/libmaxminddb/t/data_entry_list_t.c +353 -0
  68. data/ext/geoip2/libmaxminddb/t/data_types_t.c +439 -0
  69. data/ext/geoip2/libmaxminddb/t/dump_t.c +103 -0
  70. data/ext/geoip2/libmaxminddb/t/get_value_pointer_bug_t.c +66 -0
  71. data/ext/geoip2/libmaxminddb/t/get_value_t.c +249 -0
  72. data/ext/geoip2/libmaxminddb/t/ipv4_start_cache_t.c +36 -0
  73. data/ext/geoip2/libmaxminddb/t/ipv6_lookup_in_ipv4_t.c +48 -0
  74. data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.c +255 -0
  75. data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.h +69 -0
  76. data/ext/geoip2/libmaxminddb/t/metadata_pointers_t.c +32 -0
  77. data/ext/geoip2/libmaxminddb/t/metadata_t.c +226 -0
  78. data/ext/geoip2/libmaxminddb/t/mmdblookup_t.pl +158 -0
  79. data/ext/geoip2/libmaxminddb/t/no_map_get_value_t.c +32 -0
  80. data/ext/geoip2/libmaxminddb/t/read_node_t.c +157 -0
  81. data/ext/geoip2/libmaxminddb/t/threads_t.c +196 -0
  82. data/ext/geoip2/libmaxminddb/t/version_t.c +10 -0
  83. data/geoip2_c.gemspec +1 -1
  84. data/lib/geoip2/version.rb +1 -1
  85. metadata +82 -1
@@ -0,0 +1,41 @@
1
+
2
+ include_HEADERS = include/maxminddb.h
3
+
4
+ nodist_include_HEADERS = include/maxminddb_config.h
5
+
6
+ SUBDIRS = \
7
+ src \
8
+ bin
9
+
10
+ if TESTS
11
+ SUBDIRS += \
12
+ t
13
+ endif
14
+
15
+ EXTRA_DIST = doc t Changes.md LICENSE NOTICE README.md projects/VS12 projects/VS12-tests
16
+ dist-hook:
17
+ dev-bin/make-man-pages.pl $(distdir)
18
+ find $(distdir) -name '.git*' | xargs rm -fr
19
+
20
+ safedist: clean dist
21
+ tmpdir="$${TMPDIR-/tmp}/safedist-$$$$" \
22
+ && mkdir "$$tmpdir" \
23
+ && tar -xvf $(distdir).tar.gz --directory "$$tmpdir" \
24
+ && $(am__cd) "$$tmpdir/$(distdir)" \
25
+ && ./configure \
26
+ && make -j 4 check
27
+
28
+ man1_MANS = man/man1/*.1
29
+
30
+ man3_MANS = man/man3/*.3
31
+
32
+ man/man1/*.1:
33
+ if [ ! -f man/man1/mmdblookup.1 ]; then mkdir -p man/man1 && touch man/man1/mmdblookup.1; fi
34
+
35
+ man/man3/*.3:
36
+ if [ ! -f man/man3/libmaxminddb.3 ]; then mkdir -p man/man3 && touch man/man3/libmaxminddb.3; fi
37
+
38
+ release:
39
+ dev-bin/make-release.sh
40
+
41
+ .PHONY: man/man1/*.1 man/man3/*.3 release
@@ -0,0 +1,13 @@
1
+ Copyright 2013-2014 MaxMind, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,58 @@
1
+ # Releasing this library
2
+
3
+ We release by uploading the tarball to GitHub, uploading Ubuntu PPAs, and by
4
+ updating the Homebrew recipe for this library.
5
+
6
+ ## Creating the release tarball
7
+
8
+ * Update `Changes.md` to include specify the new version, today's date, and
9
+ list relevant changes.
10
+ * Run `./dev-bin/make-release.sh` to update various files in the distro, our
11
+ GitHub pages, creates and pushes a tag, etc.
12
+ * Run `make safedist` in the checkout directory to create a tarball.
13
+
14
+ ## GitHub
15
+
16
+ * Go to https://github.com/maxmind/libmaxminddb/releases
17
+ * GitHub will already have a release for the tag you just created.
18
+ * Click on the new tag new.
19
+ * Click on "Edit tag".
20
+ * Give the release a title summarizing the changes.
21
+ * Paste in the changes from the `Changes.md` file as the body.
22
+ * Attach the release tarball you just created.
23
+ * Click "Update release"
24
+
25
+ ## PPA
26
+
27
+ In order to upload a PPA, you have to create a launchpad.net account and
28
+ register a GPG key with that account. You also need to be added to the MaxMind
29
+ team. Ask in the dev channel for someone to add you. See
30
+ https://help.launchpad.net/Packaging/PPA for more details.
31
+
32
+ The PPA release script is at `dev-bin/ppa-release.sh`. Running it should
33
+ guide you though the release, although it may require some changes to run on
34
+ configurations different than Greg's machine.
35
+
36
+ Pre-script PPA release process:
37
+
38
+ 1. git co ubuntu-ppa
39
+ 2. git merge `<TAG>`
40
+ 3. dch -i
41
+ * Add new entry for wily (or whatever the most recent Ubuntu release
42
+ is. Follow existing PPA versioning style.
43
+ 4. git commit to add the debian changelog
44
+ 5. gbp buildpackage -S
45
+ 6. dput ppa:maxmind/ppa ../libmaxminddb_`<TAG>`-`<DEB VERSION>`_source.changes
46
+ 7. git push
47
+
48
+ If 5 was successful, modify debian/changelog and repeat 5 & 6 for trusty and
49
+ precise. Note that you can skip step #4 for subsequent uploads by adding
50
+ `--git-ignore-new` when you call `gbp`.
51
+
52
+ ## Homebrew
53
+
54
+ * Go to https://github.com/Homebrew/homebrew/blob/master/Library/Formula/libmaxminddb.rb
55
+ * Edit the file to update the url and sha256. You can get the sha256 for the
56
+ tarball with the `sha256sum` command line utility.
57
+ * Make a commit with the summary `libmaxminddb <VERSION>`
58
+ * Submit a PR with the changes you just made.
@@ -0,0 +1,122 @@
1
+ # About
2
+
3
+ The libmaxminddb library provides a C library for reading MaxMind DB files,
4
+ including the GeoIP2 databases from MaxMind. This is a custom binary format
5
+ designed to facilitate fast lookups of IP addresses while allowing for great
6
+ flexibility in the type of data associated with an address.
7
+
8
+ The MaxMind DB format is an open format. The spec is available at
9
+ http://maxmind.github.io/MaxMind-DB/. This spec is licensed under the Creative
10
+ Commons Attribution-ShareAlike 3.0 Unported License.
11
+
12
+ See http://dev.maxmind.com/ for more details about MaxMind's GeoIP2 products.
13
+
14
+ # License
15
+
16
+ This library is licensed under the Apache License, Version 2.
17
+
18
+ # Installation
19
+
20
+ ## From a Tarball
21
+
22
+ This code is known to work with GCC 4.4+ and clang 3.2+. It should also work
23
+ on other compilers that supports C99, POSIX 2011.11, and the `-fms-extensions
24
+ flag` (or equivalent). The latter is needed to allow an anonymous union in a
25
+ structure.
26
+
27
+ To install this code, run the following commands:
28
+
29
+ $ ./configure
30
+ $ make
31
+ $ make check
32
+ $ sudo make install
33
+ $ sudo ldconfig
34
+
35
+ You can skip the `make check` step but it's always good to know that tests are
36
+ passing on your platform.
37
+
38
+ The `configure` script takes the standard options to set where files are
39
+ installed such as `--prefix`, etc. See `./configure --help` for details.
40
+
41
+ If after installing, you receive an error that `libmaxminddb.so.0` is missing
42
+ you may need to add the `lib` directory in your `prefix` to your library path.
43
+ On most Linux distributions when using the default prefix (`/usr/local`), you
44
+ can do this by running the following commands:
45
+
46
+ $ sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf"
47
+ $ ldconfig
48
+
49
+ ## From the Git Repository
50
+
51
+ To install from Git, you will need automake, autoconf, and libtool installed
52
+ in addition to make and a compiler.
53
+
54
+ Our public git repository is hosted on GitHub at
55
+ https://github.com/maxmind/libmaxminddb
56
+
57
+ You can clone this repository and build it by running:
58
+
59
+ $ git clone --recursive https://github.com/maxmind/libmaxminddb
60
+
61
+ After cloning, run `./bootstrap` from the `libmaxminddb` directory and then
62
+ follow the instructions for installing from a tarball as described above.
63
+
64
+ ## On Windows via Visual Studio 2013+
65
+
66
+ We provide a Visual Studio solution in `projects\VS12`. This can be used to
67
+ build both the the library and the tests. Please see the `README.md` file in
68
+ the same directory for more information.
69
+
70
+ ## On Ubuntu via PPA
71
+
72
+ MaxMind provides a PPA for recent version of Ubuntu. To add the PPA to your
73
+ APT sources, run:
74
+
75
+ $ sudo add-apt-repository ppa:maxmind/ppa
76
+
77
+ Then install the packages by running:
78
+
79
+ $ sudo aptitude update
80
+ $ sudo aptitude install libmaxminddb0 libmaxminddb-dev mmdb-bin
81
+
82
+ ## On OS X via Homebrew
83
+
84
+ If you are on OS X and you have homebrew (see http://brew.sh/) you can install
85
+ libmaxminddb via brew.
86
+
87
+ $ brew install libmaxminddb
88
+
89
+ # Bug Reports
90
+
91
+ Please report bugs by filing an issue with our GitHub issue tracker at
92
+ https://github.com/maxmind/libmaxminddb/issues
93
+
94
+ # Dev Tools
95
+
96
+ We have a few development tools under the `dev-bin` directory to make
97
+ development easier. These are written in Perl or shell. They are:
98
+
99
+ * `regen-prototypes.pl` - This regenerates the prototypes in the header and
100
+ source files. This helps keep headers and code in sync.
101
+ * `uncrustify-all.sh` - This runs `uncrustify` on all the code. It runs
102
+ `regen-prototypes.pl` first. Please run this before submitting patches.
103
+ * `valgrind-all.pl` - This runs Valgrind on the tests and `mmdblookup` to
104
+ check for memory leaks.
105
+
106
+ # Creating a Release Tarball
107
+
108
+ Use `make safedist` to check the resulting tarball.
109
+
110
+ # Copyright and License
111
+
112
+ Licensed under the Apache License, Version 2.0 (the "License");
113
+ you may not use this file except in compliance with the License.
114
+ You may obtain a copy of the License at
115
+
116
+ http://www.apache.org/licenses/LICENSE-2.0
117
+
118
+ Unless required by applicable law or agreed to in writing, software
119
+ distributed under the License is distributed on an "AS IS" BASIS,
120
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121
+ See the License for the specific language governing permissions and
122
+ limitations under the License.
@@ -0,0 +1,33 @@
1
+ ---
2
+ install:
3
+ - git submodule update --init --recursive
4
+ test_script:
5
+ - .\projects\VS12\Debug\test_bad_pointers.exe
6
+ - .\projects\VS12\Debug\test_basic_lookup.exe
7
+ - .\projects\VS12\Debug\test_data_entry_list.exe
8
+ - .\projects\VS12\Debug\test_data_types.exe
9
+ - .\projects\VS12\Debug\test_dump.exe
10
+ - .\projects\VS12\Debug\test_get_value_pointer_bug.exe
11
+ - .\projects\VS12\Debug\test_get_value.exe
12
+ - .\projects\VS12\Debug\test_ipv4_start_cache.exe
13
+ - .\projects\VS12\Debug\test_ipv6_lookup_in_ipv4.exe
14
+ - .\projects\VS12\Debug\test_metadata_pointers.exe
15
+ - .\projects\VS12\Debug\test_metadata.exe
16
+ - .\projects\VS12\Debug\test_no_map_get_value.exe
17
+ - .\projects\VS12\Debug\test_read_node.exe
18
+ - .\projects\VS12\Debug\test_version.exe
19
+ notifications:
20
+ - incoming_webhook:
21
+ secure: 8FZP/RE3nS77Yi5UWOB/DQKCRSJxh/BYrLjVPEAkBG6mRojCz3r2mnla4O/5GwzDr7V6XCpxCP0xo1buCcZRIzRN0ZUWJ5hzEQqW5u7R+vM=
22
+ channel: ci
23
+ on_build_failure: true
24
+ on_build_status_changed: true
25
+ on_build_success: true
26
+ provider: Slack
27
+ - on_build_failure: true
28
+ on_build_status_changed: true
29
+ on_build_success: false
30
+ provider: Email
31
+ subject: 'AppVeyor build {{status}}'
32
+ to:
33
+ - dev-ci@maxmind.com
@@ -0,0 +1,5 @@
1
+ include $(top_srcdir)/common.mk
2
+
3
+ AM_LDFLAGS = $(top_builddir)/src/libmaxminddb.la
4
+
5
+ bin_PROGRAMS = mmdblookup
@@ -0,0 +1,397 @@
1
+ #ifdef HAVE_CONFIG_H
2
+ #include <config.h>
3
+ #endif
4
+ #include "maxminddb.h"
5
+ #include <errno.h>
6
+ #include <getopt.h>
7
+ #include <stdio.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <time.h>
11
+
12
+ #ifdef _WIN32
13
+ #include <malloc.h>
14
+ #define snprintf _snprintf
15
+ #undef UNICODE /* Use the non-UTF16 version of the gai_strerror */
16
+ #else
17
+ #include <libgen.h>
18
+ #include <unistd.h>
19
+ #endif
20
+
21
+ #define LOCAL
22
+
23
+ /* *INDENT-OFF* */
24
+ /* --prototypes automatically generated by dev-bin/regen-prototypes.pl - don't remove this comment */
25
+ LOCAL void usage(char *program, int exit_code, const char *error);
26
+ LOCAL const char **get_options(int argc, char **argv, char **mmdb_file,
27
+ char **ip_address, int *verbose, int *iterations,
28
+ int *lookup_path_length);
29
+ LOCAL MMDB_s open_or_die(const char *fname);
30
+ LOCAL void dump_meta(MMDB_s *mmdb);
31
+ LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
32
+ const char **lookup_path,
33
+ int lookup_path_length);
34
+ LOCAL int benchmark(MMDB_s *mmdb, int iterations);
35
+ LOCAL MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr);
36
+ LOCAL void random_ipv4(char *ip);
37
+ /* --prototypes end - don't remove this comment-- */
38
+ /* *INDENT-ON* */
39
+
40
+ int main(int argc, char **argv)
41
+ {
42
+ char *mmdb_file = NULL;
43
+ char *ip_address = NULL;
44
+ int verbose = 0;
45
+ int iterations = 0;
46
+ int lookup_path_length = 0;
47
+
48
+ const char **lookup_path =
49
+ get_options(argc, argv, &mmdb_file, &ip_address, &verbose, &iterations,
50
+ &lookup_path_length);
51
+
52
+ MMDB_s mmdb = open_or_die(mmdb_file);
53
+
54
+ if (verbose) {
55
+ dump_meta(&mmdb);
56
+ }
57
+
58
+ if (0 == iterations) {
59
+ exit(lookup_and_print(&mmdb, ip_address, lookup_path,
60
+ lookup_path_length));
61
+ } else {
62
+ exit(benchmark(&mmdb, iterations));
63
+ }
64
+ }
65
+
66
+ LOCAL void usage(char *program, int exit_code, const char *error)
67
+ {
68
+ if (NULL != error) {
69
+ fprintf(stderr, "\n *ERROR: %s\n", error);
70
+ }
71
+
72
+ char *usage = "\n"
73
+ " %s --file /path/to/file.mmdb --ip 1.2.3.4 [path to lookup]\n"
74
+ "\n"
75
+ " This application accepts the following options:\n"
76
+ "\n"
77
+ " --file (-f) The path to the MMDB file. Required.\n"
78
+ "\n"
79
+ " --ip (-i) The IP address to look up. Required.\n"
80
+ "\n"
81
+ " --verbose (-v) Turns on verbose output. Specifically, this causes this\n"
82
+ " application to output the database metadata.\n"
83
+ "\n"
84
+ " --version Print the program's version number and exit.\n"
85
+ "\n"
86
+ " --help (-h -?) Show usage information.\n"
87
+ "\n"
88
+ " If an IP's data entry resolves to a map or array, you can provide\n"
89
+ " a lookup path to only show part of that data.\n"
90
+ "\n"
91
+ " For example, given a JSON structure like this:\n"
92
+ "\n"
93
+ " {\n"
94
+ " \"names\": {\n"
95
+ " \"en\": \"Germany\",\n"
96
+ " \"de\": \"Deutschland\"\n"
97
+ " },\n"
98
+ " \"cities\": [ \"Berlin\", \"Frankfurt\" ]\n"
99
+ " }\n"
100
+ "\n"
101
+ " You could look up just the English name by calling mmdblookup with a lookup path of:\n"
102
+ "\n"
103
+ " mmdblookup --file ... --ip ... names en\n"
104
+ "\n"
105
+ " Or you could look up the second city in the list with:\n"
106
+ "\n"
107
+ " mmdblookup --file ... --ip ... cities 1\n"
108
+ "\n"
109
+ " Array numbering begins with zero (0).\n"
110
+ "\n"
111
+ " If you do not provide a path to lookup, all of the information for a given IP\n"
112
+ " will be shown.\n"
113
+ "\n";
114
+
115
+ fprintf(stdout, usage, program);
116
+ exit(exit_code);
117
+ }
118
+
119
+ LOCAL const char **get_options(int argc, char **argv, char **mmdb_file,
120
+ char **ip_address, int *verbose, int *iterations,
121
+ int *lookup_path_length)
122
+ {
123
+ static int help = 0;
124
+ static int version = 0;
125
+
126
+ while (1) {
127
+ static struct option options[] = {
128
+ { "file", required_argument, 0, 'f' },
129
+ { "ip", required_argument, 0, 'i' },
130
+ { "verbose", no_argument, 0, 'v' },
131
+ { "version", no_argument, 0, 'n' },
132
+ { "benchmark", required_argument, 0, 'b' },
133
+ { "help", no_argument, 0, 'h' },
134
+ { "?", no_argument, 0, 1 },
135
+ { 0, 0, 0, 0 }
136
+ };
137
+
138
+ int opt_index;
139
+ int opt_char = getopt_long(argc, argv, "f:i:b:vnh?", options,
140
+ &opt_index);
141
+
142
+ if (-1 == opt_char) {
143
+ break;
144
+ }
145
+
146
+ if ('f' == opt_char) {
147
+ *mmdb_file = optarg;
148
+ } else if ('i' == opt_char) {
149
+ *ip_address = optarg;
150
+ } else if ('v' == opt_char) {
151
+ *verbose = 1;
152
+ } else if ('n' == opt_char) {
153
+ version = 1;
154
+ } else if ('b' == opt_char) {
155
+ *iterations = strtol(optarg, NULL, 10);
156
+ } else if ('h' == opt_char || '?' == opt_char) {
157
+ help = 1;
158
+ }
159
+ }
160
+
161
+ #ifdef _WIN32
162
+ char *program = alloca(strlen(argv[0]));
163
+ _splitpath(argv[0], NULL, NULL, program, NULL);
164
+ _splitpath(argv[0], NULL, NULL, NULL, program + strlen(program));
165
+ #else
166
+ char *program = basename(argv[0]);
167
+ #endif
168
+
169
+ if (help) {
170
+ usage(program, 0, NULL);
171
+ }
172
+
173
+ if (version) {
174
+ fprintf(stdout, "\n %s version %s\n\n", program, VERSION);
175
+ exit(0);
176
+ }
177
+
178
+ if (NULL == *mmdb_file) {
179
+ usage(program, 1, "You must provide a filename with --file");
180
+ }
181
+
182
+ if (NULL == *ip_address && *iterations == 0) {
183
+ usage(program, 1, "You must provide an IP address with --ip");
184
+ }
185
+
186
+ const char **lookup_path =
187
+ malloc(sizeof(const char *) * ((argc - optind) + 1));
188
+ int i;
189
+ for (i = 0; i < argc - optind; i++) {
190
+ lookup_path[i] = argv[i + optind];
191
+ (*lookup_path_length)++;
192
+ }
193
+ lookup_path[i] = NULL;
194
+
195
+ return lookup_path;
196
+ }
197
+
198
+ LOCAL MMDB_s open_or_die(const char *fname)
199
+ {
200
+ MMDB_s mmdb;
201
+ int status = MMDB_open(fname, MMDB_MODE_MMAP, &mmdb);
202
+
203
+ if (MMDB_SUCCESS != status) {
204
+ fprintf(stderr, "\n Can't open %s - %s\n", fname,
205
+ MMDB_strerror(status));
206
+
207
+ if (MMDB_IO_ERROR == status) {
208
+ fprintf(stderr, " IO error: %s\n", strerror(errno));
209
+ }
210
+
211
+ fprintf(stderr, "\n");
212
+
213
+ exit(2);
214
+ }
215
+
216
+ return mmdb;
217
+ }
218
+
219
+ LOCAL void dump_meta(MMDB_s *mmdb)
220
+ {
221
+ const char *meta_dump = "\n"
222
+ " Database metadata\n"
223
+ " Node count: %i\n"
224
+ " Record size: %i bits\n"
225
+ " IP version: IPv%i\n"
226
+ " Binary format: %i.%i\n"
227
+ " Build epoch: %llu (%s)\n"
228
+ " Type: %s\n"
229
+ " Languages: ";
230
+
231
+ char date[40];
232
+ strftime(date, 40, "%F %T UTC",
233
+ gmtime((const time_t *)&mmdb->metadata.build_epoch));
234
+
235
+ fprintf(stdout, meta_dump,
236
+ mmdb->metadata.node_count,
237
+ mmdb->metadata.record_size,
238
+ mmdb->metadata.ip_version,
239
+ mmdb->metadata.binary_format_major_version,
240
+ mmdb->metadata.binary_format_minor_version,
241
+ mmdb->metadata.build_epoch,
242
+ date,
243
+ mmdb->metadata.database_type);
244
+
245
+ for (size_t i = 0; i < mmdb->metadata.languages.count; i++) {
246
+ fprintf(stdout, "%s", mmdb->metadata.languages.names[i]);
247
+ if (i < mmdb->metadata.languages.count - 1) {
248
+ fprintf(stdout, " ");
249
+ }
250
+ }
251
+ fprintf(stdout, "\n");
252
+
253
+ fprintf(stdout, " Description:\n");
254
+ for (size_t i = 0; i < mmdb->metadata.description.count; i++) {
255
+ fprintf(stdout, " %s: %s\n",
256
+ mmdb->metadata.description.descriptions[i]->language,
257
+ mmdb->metadata.description.descriptions[i]->description);
258
+ }
259
+ fprintf(stdout, "\n");
260
+ }
261
+
262
+ LOCAL int lookup_and_print(MMDB_s *mmdb, const char *ip_address,
263
+ const char **lookup_path,
264
+ int lookup_path_length)
265
+ {
266
+
267
+ MMDB_lookup_result_s result = lookup_or_die(mmdb, ip_address);
268
+ MMDB_entry_data_list_s *entry_data_list = NULL;
269
+
270
+ int exit_code = 0;
271
+
272
+ if (result.found_entry) {
273
+ int status;
274
+ if (lookup_path_length) {
275
+ MMDB_entry_data_s entry_data;
276
+ status = MMDB_aget_value(&result.entry, &entry_data,
277
+ lookup_path);
278
+ if (MMDB_SUCCESS == status) {
279
+ if (entry_data.offset) {
280
+ MMDB_entry_s entry =
281
+ { .mmdb = mmdb, .offset = entry_data.offset };
282
+ status = MMDB_get_entry_data_list(&entry,
283
+ &entry_data_list);
284
+ } else {
285
+ fprintf(
286
+ stdout,
287
+ "\n No data was found at the lookup path you provided\n\n");
288
+ }
289
+ }
290
+ } else {
291
+ status = MMDB_get_entry_data_list(&result.entry,
292
+ &entry_data_list);
293
+ }
294
+
295
+ if (MMDB_SUCCESS != status) {
296
+ fprintf(stderr, "Got an error looking up the entry data - %s\n",
297
+ MMDB_strerror(status));
298
+ exit_code = 5;
299
+ goto end;
300
+ }
301
+
302
+ if (NULL != entry_data_list) {
303
+ fprintf(stdout, "\n");
304
+ MMDB_dump_entry_data_list(stdout, entry_data_list, 2);
305
+ fprintf(stdout, "\n");
306
+ }
307
+ } else {
308
+ fprintf(stderr,
309
+ "\n Could not find an entry for this IP address (%s)\n\n",
310
+ ip_address);
311
+ exit_code = 6;
312
+ }
313
+
314
+ end:
315
+ MMDB_free_entry_data_list(entry_data_list);
316
+ MMDB_close(mmdb);
317
+ free(lookup_path);
318
+
319
+ return exit_code;
320
+ }
321
+
322
+ LOCAL int benchmark(MMDB_s *mmdb, int iterations)
323
+ {
324
+ char ip_address[16];
325
+ int exit_code = 0;
326
+
327
+ srand( time(NULL) );
328
+ clock_t time = clock();
329
+
330
+ for (int i = 0; i < iterations; i++) {
331
+ random_ipv4(ip_address);
332
+
333
+ MMDB_lookup_result_s result = lookup_or_die(mmdb, ip_address);
334
+ MMDB_entry_data_list_s *entry_data_list = NULL;
335
+
336
+ if (result.found_entry) {
337
+
338
+ int status = MMDB_get_entry_data_list(&result.entry,
339
+ &entry_data_list);
340
+
341
+ if (MMDB_SUCCESS != status) {
342
+ fprintf(stderr, "Got an error looking up the entry data - %s\n",
343
+ MMDB_strerror(status));
344
+ exit_code = 5;
345
+ MMDB_free_entry_data_list(entry_data_list);
346
+ goto end;
347
+ }
348
+ }
349
+
350
+ MMDB_free_entry_data_list(entry_data_list);
351
+ }
352
+
353
+ time = clock() - time;
354
+ double seconds = ((double)time / CLOCKS_PER_SEC);
355
+ fprintf(
356
+ stdout,
357
+ "\n Looked up %i addresses in %.2f seconds. %.2f lookups per second.\n\n",
358
+ iterations, seconds, iterations / seconds);
359
+
360
+ end:
361
+ MMDB_close(mmdb);
362
+
363
+ return exit_code;
364
+ }
365
+
366
+ LOCAL MMDB_lookup_result_s lookup_or_die(MMDB_s *mmdb, const char *ipstr)
367
+ {
368
+ int gai_error, mmdb_error;
369
+ MMDB_lookup_result_s result =
370
+ MMDB_lookup_string(mmdb, ipstr, &gai_error, &mmdb_error);
371
+
372
+ if (0 != gai_error) {
373
+ fprintf(stderr,
374
+ "\n Error from call to getaddrinfo for %s - %s\n\n",
375
+ ipstr, gai_strerror(gai_error));
376
+ exit(3);
377
+ }
378
+
379
+ if (MMDB_SUCCESS != mmdb_error) {
380
+ fprintf(stderr, "\n Got an error from the maxminddb library: %s\n\n",
381
+ MMDB_strerror(mmdb_error));
382
+ exit(4);
383
+ }
384
+
385
+ return result;
386
+ }
387
+
388
+ LOCAL void random_ipv4(char *ip)
389
+ {
390
+ // rand() is perfectly fine for this use case
391
+ // coverity[dont_call]
392
+ int ip_int = rand();
393
+ uint8_t *bytes = (uint8_t *)&ip_int;
394
+
395
+ snprintf(ip, 16, "%u.%u.%u.%u",
396
+ *bytes, *(bytes + 1), *(bytes + 2), *(bytes + 3));
397
+ }
@@ -0,0 +1,21 @@
1
+ #! /bin/sh
2
+
3
+ # make sure to use the installed libtool
4
+ if [ -f ltmain.sh ]; then
5
+ rm ltmain.sh
6
+ fi
7
+ autoreconf -fiv
8
+
9
+ ###################################################
10
+ # the steps below may help with outdated toolsets
11
+
12
+ # disable dependency trackeing for OS X with multiply arch option's
13
+ # automake -i --gnu --add-missing
14
+
15
+
16
+ #aclocal \
17
+ #&& automake -i --gnu --add-missing \
18
+ #&& autoconf
19
+
20
+ #LIBTOOLIZE=$( which libtoolize glibtoolize | head -1 )
21
+ #$LIBTOOLIZE -f