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.
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,889 @@
1
+ # NAME
2
+
3
+ libmaxminddb - a library for working with MaxMind DB files
4
+
5
+ # SYNOPSIS
6
+
7
+ ```c
8
+ #include <maxminddb.h>
9
+
10
+ int MMDB_open(
11
+ const char *const filename,
12
+ uint32_t flags,
13
+ MMDB_s *const mmdb);
14
+ void MMDB_close(MMDB_s *const mmdb);
15
+
16
+ MMDB_lookup_result_s MMDB_lookup_string(
17
+ MMDB_s *const mmdb,
18
+ const char *const ipstr,
19
+ int *const gai_error,
20
+ int *const mmdb_error);
21
+ MMDB_lookup_result_s MMDB_lookup_sockaddr(
22
+ MMDB_s *const mmdb,
23
+ const struct sockaddr *const
24
+ sockaddr,
25
+ int *const mmdb_error);
26
+
27
+ int MMDB_get_value(
28
+ MMDB_entry_s *const start,
29
+ MMDB_entry_data_s *const entry_data,
30
+ ...);
31
+ int MMDB_vget_value(
32
+ MMDB_entry_s *const start,
33
+ MMDB_entry_data_s *const entry_data,
34
+ va_list va_path);
35
+ int MMDB_aget_value(
36
+ MMDB_entry_s *const start,
37
+ MMDB_entry_data_s *const entry_data,
38
+ const char *const *const path);
39
+
40
+ int MMDB_get_entry_data_list(
41
+ MMDB_entry_s *start,
42
+ MMDB_entry_data_list_s **const entry_data_list);
43
+ void MMDB_free_entry_data_list(
44
+ MMDB_entry_data_list_s *const entry_data_list);
45
+ int MMDB_get_metadata_as_entry_data_list(
46
+ MMDB_s *const mmdb,
47
+ MMDB_entry_data_list_s **const entry_data_list);
48
+ int MMDB_dump_entry_data_list(
49
+ FILE *const stream,
50
+ MMDB_entry_data_list_s *const entry_data_list,
51
+ int indent);
52
+
53
+ int MMDB_read_node(
54
+ MMDB_s *const mmdb,
55
+ uint32_t node_number,
56
+ MMDB_search_node_s *const node);
57
+
58
+ const char *MMDB_lib_version(void);
59
+ const char *MMDB_strerror(int error_code);
60
+
61
+ typedef struct MMDB_lookup_result_s {
62
+ bool found_entry;
63
+ MMDB_entry_s entry;
64
+ uint16_t netmask;
65
+ } MMDB_lookup_result_s;
66
+
67
+ typedef struct MMDB_entry_data_s {
68
+ bool has_data;
69
+ union {
70
+ uint32_t pointer;
71
+ const char *utf8_string;
72
+ double double_value;
73
+ const uint8_t *bytes;
74
+ uint16_t uint16;
75
+ uint32_t uint32;
76
+ int32_t int32;
77
+ uint64_t uint64;
78
+ {mmdb_uint128_t or uint8_t[16]} uint128;
79
+ bool boolean;
80
+ float float_value;
81
+ };
82
+ ...
83
+ uint32_t data_size;
84
+ uint32_t type;
85
+ } MMDB_entry_data_s;
86
+
87
+ typedef struct MMDB_entry_data_list_s {
88
+ MMDB_entry_data_s entry_data;
89
+ struct MMDB_entry_data_list_s *next;
90
+ } MMDB_entry_data_list_s;
91
+ ```
92
+
93
+ # DESCRIPTION
94
+
95
+ The libmaxminddb library provides functions for working MaxMind DB files. See
96
+ http://maxmind.github.io/MaxMind-DB/ for the MaxMind DB format specification.
97
+ The database and results are all represented by different data structures.
98
+ Databases are opened by calling `MMDB_open()`. You can look up IP addresses as
99
+ a string with `MMDB_lookup_string()` or as a pointer to a `sockaddr`
100
+ structure with `MMDB_lookup_sockaddr()`.
101
+
102
+ If the lookup finds the IP address in the database, it returns a
103
+ `MMDB_lookup_result_s` structure. If that structure indicates that the database
104
+ has data for the IP, there are a number of functions that can be used to fetch
105
+ that data. These include `MMDB_get_value()` and `MMDB_get_entry_data_list()`.
106
+ See the function documentation below for more details.
107
+
108
+ When you are done with the database handle you should call `MMDB_close()`.
109
+
110
+ All publicly visible functions, structures, and macros begin with "MMDB_".
111
+
112
+ # DATA STRUCTURES
113
+
114
+ All data structures exported by this library's `maxminddb.h` header are
115
+ typedef'd in the form `typedef struct foo_s { ... } foo_s` so you can refer to
116
+ them without the `struct` prefix.
117
+
118
+ This library provides the following data structures:
119
+
120
+ ## `MMDB_s`
121
+
122
+ This is the handle for a MaxMind DB file. We only document some of this
123
+ structure's fields intended for public use. All other fields are subject to
124
+ change and are intended only for internal use.
125
+
126
+ ```c
127
+ typedef struct MMDB_s {
128
+ uint32_t flags;
129
+ const char *filename;
130
+ ...
131
+ MMDB_metadata_s metadata;
132
+ } MMDB_s;
133
+ ```
134
+
135
+ * `uint32_t flags` - the flags this database was opened with. See the
136
+ `MMDB_open()` documentation for more details.
137
+ * `const char *filename` - the name of the file which was opened, as passed to
138
+ `MMDB_open()`.
139
+ * `MMDB_metadata_s metadata` - the metadata for the database.
140
+
141
+ ## `MMDB_metadata_s` and `MMDB_description_s`
142
+
143
+ This structure can be retrieved from the `MMDB_s` structure. It contains the
144
+ metadata read from the database file. Note that you may find it more convenient
145
+ to access this metadata by calling `MMDB_get_metadata_as_entry_data_list()`
146
+ instead.
147
+
148
+ ```c
149
+ typedef struct MMDB_metadata_s {
150
+ uint32_t node_count;
151
+ uint16_t record_size;
152
+ uint16_t ip_version;
153
+ const char *database_type;
154
+ struct {
155
+ size_t count;
156
+ const char **names;
157
+ } languages;
158
+ uint16_t binary_format_major_version;
159
+ uint16_t binary_format_minor_version;
160
+ uint64_t build_epoch;
161
+ struct {
162
+ size_t count;
163
+ MMDB_description_s **descriptions;
164
+ } description;
165
+ } MMDB_metadata_s;
166
+
167
+ typedef struct MMDB_description_s {
168
+ const char *language;
169
+ const char *description;
170
+ } MMDB_description_s;
171
+ ```
172
+
173
+ These structures should be mostly self-explanatory.
174
+
175
+ The `ip_version` member should always be `4` or `6`. The
176
+ `binary_format_major_version` should always be `2`.
177
+
178
+ There is no requirement that the database metadata include languages or
179
+ descriptions, so the `count` for these parts of the metadata can be zero. All
180
+ of the other `MMDB_metadata_s` fields should be populated.
181
+
182
+ ## `MMDB_lookup_result_s`
183
+
184
+ This structure is returned as the result of looking up an IP address.
185
+
186
+ ```c
187
+ typedef struct MMDB_lookup_result_s {
188
+ bool found_entry;
189
+ MMDB_entry_s entry;
190
+ uint16_t netmask;
191
+ } MMDB_lookup_result_s;
192
+ ```
193
+
194
+ If the `found_entry` member is false then the other members of this structure
195
+ do not contain meaningful values. Always check that `found_entry` is true
196
+ first.
197
+
198
+ The `entry` member is used to look up the data associated with the IP address.
199
+
200
+ The `netmask` member tells you what subnet the IP address belongs to in this
201
+ database. For example, if you look up the address `1.1.1.1` in an IPv4 database
202
+ and the returned `netmask` is 16, then the address is part of the `1.1.0.0/16`
203
+ subnet.
204
+
205
+ If the database is an IPv6 database, the returned netmask is always an IPv6
206
+ prefix length (from 0-128), even if that database *also* contains IPv4
207
+ networks. If you look up an IPv4 address and would like to turn the netmask
208
+ into an IPv4 netmask value, you can simply subtract `96` from the value.
209
+
210
+ ## `MMDB_result_s`
211
+
212
+ You don't really need to dig around in this structure. You'll get this from a
213
+ `MMDB_lookup_result_s` structure and pass it to various functions.
214
+
215
+ ## `MMDB_entry_data_s`
216
+
217
+ This structure is used to return a single data section entry for an IP. These
218
+ entries can in turn point to other entries, as is the case for things like maps
219
+ and arrays. Some members of this structure are not documented as they are only
220
+ for internal use.
221
+
222
+ ```c
223
+ typedef struct MMDB_entry_data_s {
224
+ bool has_data;
225
+ union {
226
+ uint32_t pointer;
227
+ const char *utf8_string;
228
+ double double_value;
229
+ const uint8_t *bytes;
230
+ uint16_t uint16;
231
+ uint32_t uint32;
232
+ int32_t int32;
233
+ uint64_t uint64;
234
+ {mmdb_uint128_t or uint8_t[16]} uint128;
235
+ bool boolean;
236
+ float float_value;
237
+ };
238
+ ...
239
+ uint32_t data_size;
240
+ uint32_t type;
241
+ } MMDB_entry_data_s;
242
+ ```
243
+
244
+ The `has_data` member is true if data was found for a given lookup. See
245
+ `MMDB_get_value()` for more details. If this member is false then none of the
246
+ other values in the structure are meaningful.
247
+
248
+ The union at the beginning of the structure defines the actual data. To
249
+ determine which union member is populated you should look at the `type` member.
250
+ The `pointer` member of the union should never be populated in any data
251
+ returned by the API. Pointers should always be resolved internally.
252
+
253
+ The `data_size` member is only relevant for `utf8_string` and `bytes` data.
254
+ `utf8_string` is not null terminated and `data_size` _must_ be used to
255
+ determine its length.
256
+
257
+ The `type` member can be compared to one of the `MMDB_DTYPE_*` macros.
258
+
259
+ ### 128-bit Integers
260
+
261
+ The handling of `uint128` data depends on how your platform supports 128-bit
262
+ integers, if it does so at all. With GCC 4.4 and 4.5 we can write `unsigned
263
+ int __attribute__ ((__mode__ (TI)))`. With newer versions of GCC (4.6+) and
264
+ clang (3.2+) we can simply write "unsigned __int128".
265
+
266
+ In order to work around these differences, this library defines an
267
+ `mmdb_uint128_t` type. This type is defined in the `maxminddb.h` header so you
268
+ can use it in your own code.
269
+
270
+ With older compilers, we can't use an integer so we instead use a 16 byte
271
+ array of `uint8_t` values. This is the raw data from the database.
272
+
273
+ This library provides a public macro `MMDB_UINT128_IS_BYTE_ARRAY` macro. If
274
+ this is true (1), then `uint128` values are returned as a byte array, if it is
275
+ false then they are returned as a `mmdb_uint128_t` integer.
276
+
277
+ ### Data Type Macros
278
+
279
+ This library provides a macro for every data type defined by the MaxMind DB
280
+ spec.
281
+
282
+ * `MMDB_DATA_TYPE_UTF8_STRING`
283
+ * `MMDB_DATA_TYPE_DOUBLE`
284
+ * `MMDB_DATA_TYPE_BYTES`
285
+ * `MMDB_DATA_TYPE_UINT16`
286
+ * `MMDB_DATA_TYPE_UINT32`
287
+ * `MMDB_DATA_TYPE_MAP`
288
+ * `MMDB_DATA_TYPE_INT32`
289
+ * `MMDB_DATA_TYPE_UINT64`
290
+ * `MMDB_DATA_TYPE_UINT128`
291
+ * `MMDB_DATA_TYPE_ARRAY`
292
+ * `MMDB_DATA_TYPE_BOOLEAN`
293
+ * `MMDB_DATA_TYPE_FLOAT`
294
+
295
+ There are also a few types that are for internal use only:
296
+
297
+ * `MMDB_DATA_TYPE_EXTENDED`
298
+ * `MMDB_DATA_TYPE_POINTER`
299
+ * `MMDB_DATA_TYPE_CONTAINER`
300
+ * `MMDB_DATA_TYPE_END_MARKER`
301
+
302
+ If you see one of these in returned data then something has gone very wrong.
303
+ The database is damaged or was generated incorrectly or there is a bug in the
304
+ libmaxminddb code.
305
+
306
+ ### Pointer Values and `MMDB_close()`
307
+
308
+ The `utf8_string`, `bytes`, and (maybe) the `uint128` members of this structure
309
+ are all pointers directly into the database's data section. This can either be
310
+ a `malloc`'d or `mmap`'d block of memory. In either case, these pointers will
311
+ become invalid after `MMDB_close()` is called.
312
+
313
+ If you need to refer to this data after that time you should copy the data
314
+ with an appropriate function (`strdup`, `memcpy`, etc.).
315
+
316
+ ## `MMDB_entry_data_list_s`
317
+
318
+ This structure encapsulates a linked list of `MMDB_entry_data_s` structures.
319
+
320
+ ```c
321
+ typedef struct MMDB_entry_data_list_s {
322
+ MMDB_entry_data_s entry_data;
323
+ struct MMDB_entry_data_list_s *next;
324
+ } MMDB_entry_data_list_s;
325
+ ```
326
+
327
+ This structure lets you look at entire map or array data entry by iterating
328
+ over the linked list.
329
+
330
+ ## `MMDB_search_node_s`
331
+
332
+ This structure encapsulates the two records in a search node. This is really
333
+ only useful if you want to write code that iterates over the entire search
334
+ tree as opposed to looking up a specific IP address.
335
+
336
+ ```c
337
+ typedef struct MMDB_search_node_s {
338
+ uint64_t left_record;
339
+ uint64_t right_record;
340
+ uint8_t left_record_type;
341
+ uint8_t right_record_type;
342
+ MMDB_entry_s left_record_entry;
343
+ MMDB_entry_s right_record_entry;
344
+ } MMDB_search_node_s;
345
+ ```
346
+
347
+ The two record types will take one of the following values:
348
+
349
+ * `MMDB_RECORD_TYPE_SEARCH_NODE` - The record points to the next search node.
350
+ * `MMDB_RECORD_TYPE_EMPTY` - The record is a placeholder that indicates there
351
+ is no data for the IP address. The search should end here.
352
+ * `MMDB_RECORD_TYPE_DATA` - The record is for data in the data section of the
353
+ database. Use the entry for the record when looking up the data for the
354
+ record.
355
+ * `MMDB_RECORD_TYPE_INVALID` - The record is invalid. Either an invalid node
356
+ was looked up or the database is corrupt.
357
+
358
+ The `MMDB_entry_s` for the record is only valid if the type is
359
+ `MMDB_RECORD_TYPE_DATA`. Attempts to use an entry for other record types will
360
+ result in an error or invalid data.
361
+
362
+ # STATUS CODES
363
+
364
+ This library returns (or populates) status codes for many functions. These
365
+ status codes are:
366
+
367
+ * `MMDB_SUCCESS` - everything worked
368
+ * `MMDB_FILE_OPEN_ERROR` - there was an error trying to open the MaxMind DB
369
+ file.
370
+ * `MMDB_IO_ERROR` - an IO operation failed. Check `errno` for more details.
371
+ * `MMDB_CORRUPT_SEARCH_TREE_ERROR` - looking up an IP address in the search
372
+ tree gave us an impossible result. The database is damaged or was generated
373
+ incorrectly or there is a bug in the libmaxminddb code.
374
+ * `MMDB_INVALID_METADATA_ERROR` - something in the database is wrong. This
375
+ includes missing metadata keys as well as impossible values (like an
376
+ `ip_version` of 7).
377
+ * `MMDB_UNKNOWN_DATABASE_FORMAT_ERROR` - The database metadata indicates that
378
+ it's major version is not 2. This library can only handle major version 2.
379
+ * `MMDB_OUT_OF_MEMORY_ERROR` - a memory allocation call (`malloc`, etc.)
380
+ failed.
381
+ * `MMDB_INVALID_DATA_ERROR` - an entry in the data section contains invalid
382
+ data. For example, a `uint16` field is claiming to be more than 2 bytes long.
383
+ The database is probably damaged or was generated incorrectly.
384
+ * `MMDB_INVALID_LOOKUP_PATH_ERROR` - The lookup path passed to
385
+ `MMDB_get_value`, `MMDB_vget_value`, or `MMDB_aget_value` contains an array
386
+ offset that is negative integer or an integer larger than LONG_MAX.
387
+ * `MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR` - The lookup path passed to
388
+ `MMDB_get_value`,`MMDB_vget_value`, or `MMDB_aget_value` does not match the
389
+ data structure for the entry. There are number of reasons this can
390
+ happen. The lookup path could include a key not in a map. The lookup path
391
+ could include an array index larger than an array. It can also happen when
392
+ the path expects to find a map or array where none exist.
393
+
394
+ All status codes should be treated as `int` values.
395
+
396
+ ## `MMDB_strerror()`
397
+
398
+ ```c
399
+ const char *MMDB_strerror(int error_code)
400
+ ```
401
+
402
+ This function takes a status code and returns an English string explaining the
403
+ status.
404
+
405
+ # FUNCTIONS
406
+
407
+ This library provides the following exported functions:
408
+
409
+ ## `MMDB_open()`
410
+
411
+ ```c
412
+ int MMDB_open(
413
+ const char *const filename,
414
+ uint32_t flags,
415
+ MMDB_s *const mmdb);
416
+ ```
417
+
418
+ This function opens a handle to a MaxMind DB file. Its return value is a
419
+ status code as defined above. Always check this call's return value.
420
+
421
+ ```c
422
+ MMDB_s mmdb;
423
+ int status =
424
+ MMDB_open("/path/to/file.mmdb", MMDB_MODE_MMAP, &mmdb);
425
+ if (MMDB_SUCCESS != status) { ... }
426
+ ...
427
+ MMDB_close(&mmdb);
428
+ ```
429
+
430
+ The `MMDB_s` structure you pass in can be on the stack or allocated from the
431
+ heap. However, if the open is successful it will contain heap-allocated data,
432
+ so you need to close it with `MMDB_close()`. If the status returned is not
433
+ `MMDB_SUCCESS` then this library makes sure that all allocated memory is freed
434
+ before returning.
435
+
436
+ The flags currently provided are:
437
+
438
+ * `MMDB_MODE_MMAP` - open the database with `mmap()`.
439
+
440
+ Passing in other values for `flags` may yield unpredictable results. In the
441
+ future we may add additional flags that you can bitwise-or together with the
442
+ mode, as well as additional modes.
443
+
444
+ You can also pass `0` as the `flags` value in which case the database will be
445
+ opened with the default flags. However, these defaults may change in future
446
+ releases. The current default is `MMDB_MODE_MMAP`.
447
+
448
+ ## `MMDB_close()`
449
+
450
+ ```c
451
+ void MMDB_close(MMDB_s *const mmdb);
452
+ ```
453
+
454
+ This frees any allocated or mmap'd memory that is held from the `MMDB_s`
455
+ structure. *It does not free the memory allocated for the structure itself!*
456
+ If you allocated the structure from the heap then you are responsible for
457
+ freeing it.
458
+
459
+ ## `MMDB_lookup_string()`
460
+
461
+ ```c
462
+ MMDB_lookup_result_s MMDB_lookup_string(
463
+ MMDB_s *const mmdb,
464
+ const char *const ipstr,
465
+ int *const gai_error,
466
+ int *const mmdb_error);
467
+ ```
468
+
469
+ This function looks up an IP address that is passed in as a null-terminated
470
+ string. Internally it calls `getaddrinfo()` to resolve the address into a
471
+ binary form. It then calls `MMDB_lookup_sockaddr()` to look the address up in
472
+ the database. If you have already resolved an address you can call
473
+ `MMDB_lookup_sockaddr()` directly, rather than resolving the address twice.
474
+
475
+ ```c
476
+ int gai_error, mmdb_error;
477
+ MMDB_lookup_result_s result =
478
+ MMDB_lookup_string(&mmdb, "1.2.3.4", &gai_error, &mmdb_error);
479
+ if (0 != gai_error) { ... }
480
+ if (MMDB_SUCCESS != mmdb_error) { ... }
481
+
482
+ if (result.found_entry) { ... }
483
+ ```
484
+
485
+ This function always returns an `MMDB_lookup_result_s` structure, but you
486
+ should also check the `gai_error` and `mmdb_error` parameters. If either of
487
+ these indicates an error then the returned structure is meaningless.
488
+
489
+ If no error occurred you still need to make sure that the `found_entry` member
490
+ in the returned result is true. If it's not, this means that the IP address
491
+ does not have an entry in the database.
492
+
493
+ This function will work with IPv4 addresses even when the database contains
494
+ data for both IPv4 and IPv6 addresses. The IPv4 address will be looked up as
495
+ '::xxx.xxx.xxx.xxx' rather than being remapped to the `::ffff:xxx.xxx.xxx.xxx`
496
+ block allocated for IPv4-mapped IPv6 addresses.
497
+
498
+ If you pass an IPv6 address to a database with only IPv4 data then the
499
+ `found_entry` member will be false, but the `mmdb_error` status will still be
500
+ `MMDB_SUCCESS`.
501
+
502
+ ## `MMDB_lookup_sockaddr()`
503
+
504
+ ```c
505
+ MMDB_lookup_result_s MMDB_lookup_sockaddr(
506
+ MMDB_s *const mmdb,
507
+ const struct sockaddr *const sockaddr,
508
+ int *const mmdb_error);
509
+ ```
510
+
511
+ This function looks up an IP address that has already been resolved by
512
+ `getaddrinfo()`.
513
+
514
+ Other than not calling `getaddrinfo()` itself, this function is identical to
515
+ the `MMDB_lookup_string()` function.
516
+
517
+ ```c
518
+ int mmdb_error;
519
+ MMDB_lookup_result_s result =
520
+ MMDB_lookup_sockaddr(&mmdb, address->ai_addr, &mmdb_error);
521
+ if (MMDB_SUCCESS != mmdb_error) { ... }
522
+
523
+ if (result.found_entry) { ... }
524
+ ```
525
+
526
+ ## Data Lookup Functions
527
+
528
+ There are three functions for looking up data associated with an IP address.
529
+
530
+ ```c
531
+ int MMDB_get_value(
532
+ MMDB_entry_s *const start,
533
+ MMDB_entry_data_s *const entry_data,
534
+ ...);
535
+ int MMDB_vget_value(
536
+ MMDB_entry_s *const start,
537
+ MMDB_entry_data_s *const entry_data,
538
+ va_list va_path);
539
+ int MMDB_aget_value(
540
+ MMDB_entry_s *const start,
541
+ MMDB_entry_data_s *const entry_data,
542
+ const char *const *const path);
543
+ ```
544
+
545
+ The three functions allow three slightly different calling styles, but they
546
+ all do the same thing.
547
+
548
+ The first parameter is an `MMDB_entry_s` value. In most cases this will come
549
+ from the `MMDB_lookup_result_s` value returned by `MMDB_lookup_string()` or
550
+ `MMDB_lookup_sockaddr()`.
551
+
552
+ The second parameter is a reference to an `MMDB_entry_data_s` structure. This
553
+ will be populated with the data that is being looked up, if any is found. If
554
+ nothing is found, then the `has_data` member of this structure will be false.
555
+ If `has_data` is true then you can look at the `data_type` member.
556
+
557
+ The final parameter is a lookup path. The path consists of a set of strings
558
+ representing either map keys (e.g, "city") or array indexes (e.g., "0", "1")
559
+ to use in the lookup. This allow you to navigate a complex data structure. For
560
+ example, given this example:
561
+
562
+ ```js
563
+ {
564
+ "names": {
565
+ "en": "Germany",
566
+ "de": "Deutschland"
567
+ },
568
+ "cities": [ "Berlin", "Frankfurt" ]
569
+ }
570
+ ```
571
+
572
+ We could look up the English name with this code:
573
+
574
+ ```c
575
+ MMDB_lookup_result_s result =
576
+ MMDB_lookup_sockaddr(&mmdb, address->ai_addr, &mmdb_error);
577
+ MMDB_entry_data_s entry_data;
578
+ int status =
579
+ MMDB_get_value(&result.entry, &entry_data,
580
+ "names", "en", NULL);
581
+ if (MMDB_SUCCESS != status) { ... }
582
+ if (entry_data.has_data) { ... }
583
+ ```
584
+
585
+ If we wanted to find the first city the lookup path would be `"cities",
586
+ "0"`. If you don't provide a lookup path at all, you'll get the entry which
587
+ corresponds to the top level map. The lookup path must always end with `NULL`,
588
+ regardless of which function you call.
589
+
590
+ The `MMDB_get_value` function takes a variable number of arguments. All of the
591
+ arguments after the `MMDB_entry_data_s *` structure pointer are the lookup
592
+ path. The last argument must be `NULL`.
593
+
594
+ The `MMDB_vget_value` function accepts a `va_list` as the lookup path. The
595
+ last element retrieved by `va_arg()` must be `NULL`.
596
+
597
+ Finally, the `MMDB_aget_value` accepts an array of strings as the lookup
598
+ path. The last member of this array must be `NULL`.
599
+
600
+ If you want to get all of the entry data at once you can call
601
+ `MMDB_get_entry_data_list()` instead.
602
+
603
+ For each of the three functions, the return value is a status code as
604
+ defined above.
605
+
606
+ ## `MMDB_get_entry_data_list()`
607
+
608
+ ```c
609
+ int MMDB_get_entry_data_list(
610
+ MMDB_entry_s *start,
611
+ MMDB_entry_data_list_s **const entry_data_list);
612
+ ```
613
+
614
+ This function allows you to get all of the data for a complex data structure
615
+ at once, rather than looking up each piece using repeated calls to
616
+ `MMDB_get_value()`.
617
+
618
+ ```c
619
+ MMDB_lookup_result_s result =
620
+ MMDB_lookup_sockaddr(&mmdb, address->ai_addr, &mmdb_error);
621
+ MMDB_entry_data_list_s *entry_data_list, *first;
622
+ int status =
623
+ MMDB_get_entry_data_list(&result.entry, &entry_data_list);
624
+ if (MMDB_SUCCESS != status) { ... }
625
+ // save this so we can free this data later
626
+ first = entry_data_list;
627
+
628
+ while (1) {
629
+ MMDB_entry_data_list_s *next = entry_data_list = entry_data_list->next;
630
+ if (NULL == next) {
631
+ break;
632
+ }
633
+
634
+ switch (next->entry_data.type) {
635
+ case MMDB_DATA_TYPE_MAP: { ... }
636
+ case MMDB_DATA_TYPE_UTF8_STRING: { ... }
637
+ ...
638
+ }
639
+
640
+ }
641
+
642
+ MMDB_free_entry_data_list(first);
643
+ ```
644
+
645
+ It's up to you to interpret the `entry_data_list` data structure. The list is
646
+ linked in a depth-first traversal. Let's use this structure as an example:
647
+
648
+ ```js
649
+ {
650
+ "names": {
651
+ "en": "Germany",
652
+ "de": "Deutschland"
653
+ },
654
+ "cities": [ "Berlin", "Frankfurt" ]
655
+ }
656
+ ```
657
+
658
+ The list will consist of the following items:
659
+
660
+ 1. MAP - top level map
661
+ 2. UTF8_STRING - "names" key
662
+ 3. MAP - map for "names" key
663
+ 4. UTF8_STRING - "en" key
664
+ 5. UTF8_STRING - value for "en" key
665
+ 6. UTF8_STRING - "de" key
666
+ 7. UTF8_STRING - value for "de" key
667
+ 8. UTF8_STRING - "cities" key
668
+ 9. ARRAY - value for "cities" key
669
+ 10. UTF8_STRING - array[0]
670
+ 11. UTF8_STRING - array[1]
671
+
672
+ The return value of the function is a status code as defined above.
673
+
674
+ ## `MMDB_free_entry_data_list()`
675
+
676
+ ```c
677
+ void MMDB_free_entry_data_list(
678
+ MMDB_entry_data_list_s *const entry_data_list);
679
+ ```
680
+
681
+ The `MMDB_get_entry_data_list()` and `MMDB_get_metadata_as_entry_data_list()`
682
+ functions will allocate the linked list structure from the heap. Call this
683
+ function to free the `MMDB_entry_data_list_s` structure.
684
+
685
+ ## `MMDB_get_metadata_as_entry_data_list()`
686
+
687
+ ```c
688
+ int MMDB_get_metadata_as_entry_data_list(
689
+ MMDB_s *const mmdb,
690
+ MMDB_entry_data_list_s **const entry_data_list);
691
+ ```
692
+
693
+ This function allows you to retrieve the database metadata as a linked list of
694
+ `MMDB_entry_data_list_s` structures. This can be a more convenient way to deal
695
+ with the metadata than using the metadata structure directly.
696
+
697
+ ```c
698
+ MMDB_entry_data_list_s *entry_data_list, *first;
699
+ int status =
700
+ MMDB_get_metadata_as_entry_data_list(&mmdb, &entry_data_list);
701
+ if (MMDB_SUCCESS != status) { ... }
702
+ first = entry_data_list;
703
+ ... // do something with the data
704
+ MMDB_free_entry_data_list(first);
705
+ ```
706
+
707
+ The return value of the function is a status code as defined above.
708
+
709
+ ## `MMDB_dump_entry_data_list()`
710
+
711
+ ```c
712
+ int MMDB_dump_entry_data_list(
713
+ FILE *const stream,
714
+ MMDB_entry_data_list_s *const entry_data_list,
715
+ int indent);
716
+ ```
717
+
718
+ This function takes a linked list of `MMDB_entry_data_list_s` structures and
719
+ stringifies it to the given `stream`. The `indent` parameter is the starting
720
+ indent level for the generated output. It is incremented for nested data
721
+ structures (maps, array, etc.).
722
+
723
+ The `stream` must be a file handle (`stdout`, etc). If your platform provides
724
+ something like the GNU `open_memstream()` you can use that to capture the
725
+ output as a string.
726
+
727
+ The output is formatted in a JSON-ish fashion, but values are marked with their
728
+ data type (except for maps and arrays which are shown with "{}" and "[]"
729
+ respectively).
730
+
731
+ The specific output format may change in future releases, so you should not
732
+ rely on the specific formatting produced by this function. It is intended to be
733
+ used to show data to users in a readable way and for debugging purposes.
734
+
735
+ The return value of the function is a status code as defined above.
736
+
737
+ ## `MMDB_read_node()`
738
+
739
+ ```c
740
+ int MMDB_read_node(
741
+ MMDB_s *const mmdb,
742
+ uint32_t node_number,
743
+ MMDB_search_node_s *const node);
744
+ ```
745
+
746
+ This reads a specific node in the search tree. The third argument is a
747
+ reference to an `MMDB_search_node_s` structure that will be populated by this
748
+ function.
749
+
750
+ The return value is a status code. If you pass a `node_number` that is greater
751
+ than the number of nodes in the database, this function will return
752
+ `MMDB_INVALID_NODE_NUMBER_ERROR`, otherwise it will return `MMDB_SUCCESS`.
753
+
754
+ The first node in the search tree is always node 0. If you wanted to iterate
755
+ over the whole search tree, you would start by reading node 0 and then
756
+ following the the records that make up this node, based on the type of each
757
+ record. If the type is `MMDB_RECORD_TYPE_SEARCH_NODE` then the record contains
758
+ an integer for the next node to look up.
759
+
760
+ ## `MMDB_lib_version()`
761
+
762
+ ```c
763
+ const char *MMDB_lib_version(void)
764
+ ```
765
+
766
+ This function returns the library version as a string, something like "2.0.0".
767
+
768
+ # EXAMPLE
769
+
770
+ ```c
771
+ #include <errno.h>
772
+ #include <maxminddb.h>
773
+ #include <stdlib.h>
774
+ #include <string.h>
775
+
776
+ int main(int argc, char **argv)
777
+ {
778
+ char *filename = argv[1];
779
+ char *ip_address = argv[2];
780
+
781
+ MMDB_s mmdb;
782
+ int status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb);
783
+
784
+ if (MMDB_SUCCESS != status) {
785
+ fprintf(stderr, "\n Can't open %s - %s\n",
786
+ filename, MMDB_strerror(status));
787
+
788
+ if (MMDB_IO_ERROR == status) {
789
+ fprintf(stderr, " IO error: %s\n", strerror(errno));
790
+ }
791
+ exit(1);
792
+ }
793
+
794
+ int gai_error, mmdb_error;
795
+ MMDB_lookup_result_s result =
796
+ MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error);
797
+
798
+ if (0 != gai_error) {
799
+ fprintf(stderr,
800
+ "\n Error from getaddrinfo for %s - %s\n\n",
801
+ ip_address, gai_strerror(gai_error));
802
+ exit(2);
803
+ }
804
+
805
+ if (MMDB_SUCCESS != mmdb_error) {
806
+ fprintf(stderr,
807
+ "\n Got an error from libmaxminddb: %s\n\n",
808
+ MMDB_strerror(mmdb_error));
809
+ exit(3);
810
+ }
811
+
812
+ MMDB_entry_data_list_s *entry_data_list = NULL;
813
+
814
+ int exit_code = 0;
815
+ if (result.found_entry) {
816
+ int status = MMDB_get_entry_data_list(&result.entry,
817
+ &entry_data_list);
818
+
819
+ if (MMDB_SUCCESS != status) {
820
+ fprintf(
821
+ stderr,
822
+ "Got an error looking up the entry data - %s\n",
823
+ MMDB_strerror(status));
824
+ exit_code = 4;
825
+ goto end;
826
+ }
827
+
828
+ if (NULL != entry_data_list) {
829
+ MMDB_dump_entry_data_list(stdout, entry_data_list, 2);
830
+ }
831
+ } else {
832
+ fprintf(
833
+ stderr,
834
+ "\n No entry for this IP address (%s) was found\n\n",
835
+ ip_address);
836
+ exit_code = 5;
837
+ }
838
+
839
+ end:
840
+ MMDB_free_entry_data_list(entry_data_list);
841
+ MMDB_close(&mmdb);
842
+ exit(exit_code);
843
+ }
844
+ ```
845
+
846
+ # THREAD SAFETY
847
+
848
+ This library is thread safe when compiled and linked with a thread-safe
849
+ `malloc` and `free` implementation.
850
+
851
+ # INSTALLATION AND SOURCE
852
+
853
+ You can download the latest release of libmaxminddb
854
+ [from GitHub](https://github.com/maxmind/libmaxminddb/releases).
855
+
856
+ [Our GitHub repo](https://github.com/maxmind/libmaxminddb) is publicly
857
+ available. Please fork it!
858
+
859
+ # BUG REPORTS AND PULL REQUESTS
860
+
861
+ Please report all issues to
862
+ [our GitHub issue tracker](https://github.com/maxmind/libmaxminddb/issues). We
863
+ welcome bug reports and pull requests. Please note that pull requests are
864
+ greatly preferred over patches.
865
+
866
+ # AUTHORS
867
+
868
+ This library was written by Boris Zentner (bzentner@maxmind.com) and Dave
869
+ Rolsky (drolsky@maxmind.com).
870
+
871
+ # COPYRIGHT AND LICENSE
872
+
873
+ Copyright 2013-2014 MaxMind, Inc.
874
+
875
+ Licensed under the Apache License, Version 2.0 (the "License");
876
+ you may not use this file except in compliance with the License.
877
+ You may obtain a copy of the License at
878
+
879
+ http://www.apache.org/licenses/LICENSE-2.0
880
+
881
+ Unless required by applicable law or agreed to in writing, software
882
+ distributed under the License is distributed on an "AS IS" BASIS,
883
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
884
+ See the License for the specific language governing permissions and
885
+ limitations under the License.
886
+
887
+ # SEE ALSO
888
+
889
+ mmdblookup(1)