geoip2_c 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|