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.
- checksums.yaml +4 -4
- data/ext/geoip2/libmaxminddb/.gitignore +35 -0
- data/ext/geoip2/libmaxminddb/.gitmodules +9 -0
- data/ext/geoip2/libmaxminddb/.perltidyrc +11 -0
- data/ext/geoip2/libmaxminddb/.travis.yml +48 -0
- data/ext/geoip2/libmaxminddb/.uncrustify.cfg +78 -0
- data/ext/geoip2/libmaxminddb/AUTHORS +0 -0
- data/ext/geoip2/libmaxminddb/Changes.md +238 -0
- data/ext/geoip2/libmaxminddb/LICENSE +202 -0
- data/ext/geoip2/libmaxminddb/Makefile.am +41 -0
- data/ext/geoip2/libmaxminddb/NOTICE +13 -0
- data/ext/geoip2/libmaxminddb/README.dev.md +58 -0
- data/ext/geoip2/libmaxminddb/README.md +122 -0
- data/ext/geoip2/libmaxminddb/appveyor.yml +33 -0
- data/ext/geoip2/libmaxminddb/bin/Makefile.am +5 -0
- data/ext/geoip2/libmaxminddb/bin/mmdblookup.c +397 -0
- data/ext/geoip2/libmaxminddb/bootstrap +21 -0
- data/ext/geoip2/libmaxminddb/common.mk +7 -0
- data/ext/geoip2/libmaxminddb/configure.ac +132 -0
- data/ext/geoip2/libmaxminddb/dev-bin/make-man-pages.pl +76 -0
- data/ext/geoip2/libmaxminddb/dev-bin/ppa-release.sh +50 -0
- data/ext/geoip2/libmaxminddb/dev-bin/regen-prototypes.pl +136 -0
- data/ext/geoip2/libmaxminddb/dev-bin/regen-win32-test-projs.pl +54 -0
- data/ext/geoip2/libmaxminddb/dev-bin/release.sh +106 -0
- data/ext/geoip2/libmaxminddb/dev-bin/uncrustify-all.sh +21 -0
- data/ext/geoip2/libmaxminddb/dev-bin/valgrind-all.pl +46 -0
- data/ext/geoip2/libmaxminddb/doc/libmaxminddb.md +889 -0
- data/ext/geoip2/libmaxminddb/doc/mmdblookup.md +103 -0
- data/ext/geoip2/libmaxminddb/include/maxminddb.h +232 -0
- data/ext/geoip2/libmaxminddb/include/maxminddb_config.h.in +14 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/README.md +59 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-release.props +32 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb-x64.props +14 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.props +32 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.sln +150 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj +141 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/libmaxminddb.vcxproj.filters +26 -0
- data/ext/geoip2/libmaxminddb/projects/VS12/maxminddb_config.h +14 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/bad_pointers.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/basic_lookup.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_entry_list.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/data_types.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/dump.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/get_value_pointer_bug.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv4_start_cache.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/ipv6_lookup_in_ipv4.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/libtap.vcxproj +85 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/maxminddb_test_helper.vcxproj +107 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/metadata_pointers.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/no_map_get_value.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/read_node.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/shared.vcxproj +104 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/threads.vcxproj +103 -0
- data/ext/geoip2/libmaxminddb/projects/VS12-tests/version.vcxproj +105 -0
- data/ext/geoip2/libmaxminddb/projects/test.vcxproj.template +105 -0
- data/ext/geoip2/libmaxminddb/src/Makefile.am +9 -0
- data/ext/geoip2/libmaxminddb/src/libmaxminddb.pc.in +11 -0
- data/ext/geoip2/libmaxminddb/src/maxminddb-compat-util.h +167 -0
- data/ext/geoip2/libmaxminddb/src/maxminddb.c +2171 -0
- data/ext/geoip2/libmaxminddb/t/Makefile.am +23 -0
- data/ext/geoip2/libmaxminddb/t/bad_databases_t.c +66 -0
- data/ext/geoip2/libmaxminddb/t/bad_pointers_t.c +53 -0
- data/ext/geoip2/libmaxminddb/t/basic_lookup_t.c +172 -0
- data/ext/geoip2/libmaxminddb/t/compile_c++_t.pl +107 -0
- data/ext/geoip2/libmaxminddb/t/data_entry_list_t.c +353 -0
- data/ext/geoip2/libmaxminddb/t/data_types_t.c +439 -0
- data/ext/geoip2/libmaxminddb/t/dump_t.c +103 -0
- data/ext/geoip2/libmaxminddb/t/get_value_pointer_bug_t.c +66 -0
- data/ext/geoip2/libmaxminddb/t/get_value_t.c +249 -0
- data/ext/geoip2/libmaxminddb/t/ipv4_start_cache_t.c +36 -0
- data/ext/geoip2/libmaxminddb/t/ipv6_lookup_in_ipv4_t.c +48 -0
- data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.c +255 -0
- data/ext/geoip2/libmaxminddb/t/maxminddb_test_helper.h +69 -0
- data/ext/geoip2/libmaxminddb/t/metadata_pointers_t.c +32 -0
- data/ext/geoip2/libmaxminddb/t/metadata_t.c +226 -0
- data/ext/geoip2/libmaxminddb/t/mmdblookup_t.pl +158 -0
- data/ext/geoip2/libmaxminddb/t/no_map_get_value_t.c +32 -0
- data/ext/geoip2/libmaxminddb/t/read_node_t.c +157 -0
- data/ext/geoip2/libmaxminddb/t/threads_t.c +196 -0
- data/ext/geoip2/libmaxminddb/t/version_t.c +10 -0
- data/geoip2_c.gemspec +1 -1
- data/lib/geoip2/version.rb +1 -1
- 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,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
|