1377 lines
44 KiB
HTML
1377 lines
44 KiB
HTML
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
|
<HTML><HEAD><TITLE>Man page of libmaxminddb</TITLE>
|
|
</HEAD><BODY>
|
|
<H1>libmaxminddb</H1>
|
|
Section: (3)<BR>Updated: <BR><A HREF="#index">Index</A>
|
|
<A HREF="/cgi-bin/man/man2html">Return to Main Contents</A><HR>
|
|
|
|
|
|
<A NAME="lbAB"> </A>
|
|
<H2>NAME</H2>
|
|
|
|
<P>
|
|
|
|
libmaxminddb - a library for working with MaxMind DB files
|
|
<A NAME="lbAC"> </A>
|
|
<H2>SYNOPSIS</H2>
|
|
|
|
<DL COMPACT>
|
|
<DT id="1"><DD>
|
|
<PRE>
|
|
|
|
#include <<A HREF="file:///usr/include/maxminddb.h">maxminddb.h</A>>
|
|
|
|
int MMDB_open(
|
|
const char *const filename,
|
|
uint32_t flags,
|
|
MMDB_s *const mmdb);
|
|
void MMDB_close(MMDB_s *const mmdb);
|
|
|
|
MMDB_lookup_result_s MMDB_lookup_string(
|
|
MMDB_s *const mmdb,
|
|
const char *const ipstr,
|
|
int *const gai_error,
|
|
int *const mmdb_error);
|
|
MMDB_lookup_result_s MMDB_lookup_sockaddr(
|
|
MMDB_s *const mmdb,
|
|
const struct sockaddr *const
|
|
sockaddr,
|
|
int *const mmdb_error);
|
|
|
|
int MMDB_get_value(
|
|
MMDB_entry_s *const start,
|
|
MMDB_entry_data_s *const entry_data,
|
|
...);
|
|
int MMDB_vget_value(
|
|
MMDB_entry_s *const start,
|
|
MMDB_entry_data_s *const entry_data,
|
|
va_list va_path);
|
|
int MMDB_aget_value(
|
|
MMDB_entry_s *const start,
|
|
MMDB_entry_data_s *const entry_data,
|
|
const char *const *const path);
|
|
|
|
int MMDB_get_entry_data_list(
|
|
MMDB_entry_s *start,
|
|
MMDB_entry_data_list_s **const entry_data_list);
|
|
void MMDB_free_entry_data_list(
|
|
MMDB_entry_data_list_s *const entry_data_list);
|
|
int MMDB_get_metadata_as_entry_data_list(
|
|
MMDB_s *const mmdb,
|
|
MMDB_entry_data_list_s **const entry_data_list);
|
|
int MMDB_dump_entry_data_list(
|
|
FILE *const stream,
|
|
MMDB_entry_data_list_s *const entry_data_list,
|
|
int indent);
|
|
|
|
int MMDB_read_node(
|
|
MMDB_s *const mmdb,
|
|
uint32_t node_number,
|
|
MMDB_search_node_s *const node);
|
|
|
|
const char *MMDB_lib_version(void);
|
|
const char *MMDB_strerror(int error_code);
|
|
|
|
typedef struct MMDB_lookup_result_s {
|
|
bool found_entry;
|
|
MMDB_entry_s entry;
|
|
uint16_t netmask;
|
|
} MMDB_lookup_result_s;
|
|
|
|
typedef struct MMDB_entry_data_s {
|
|
bool has_data;
|
|
union {
|
|
uint32_t pointer;
|
|
const char *utf8_string;
|
|
double double_value;
|
|
const uint8_t *bytes;
|
|
uint16_t uint16;
|
|
uint32_t uint32;
|
|
int32_t int32;
|
|
uint64_t uint64;
|
|
{mmdb_uint128_t or uint8_t[16]} uint128;
|
|
bool boolean;
|
|
float float_value;
|
|
};
|
|
...
|
|
uint32_t data_size;
|
|
uint32_t type;
|
|
} MMDB_entry_data_s;
|
|
|
|
typedef struct MMDB_entry_data_list_s {
|
|
MMDB_entry_data_s entry_data;
|
|
struct MMDB_entry_data_list_s *next;
|
|
} MMDB_entry_data_list_s;
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<A NAME="lbAD"> </A>
|
|
<H2>DESCRIPTION</H2>
|
|
|
|
<P>
|
|
|
|
The libmaxminddb library provides functions for working MaxMind DB
|
|
files.
|
|
See <A HREF="http://maxmind.github.io/MaxMind-DB/">http://maxmind.github.io/MaxMind-DB/</A> for the MaxMind DB format
|
|
specification.
|
|
The database and results are all represented by different data
|
|
structures.
|
|
Databases are opened by calling MMDB_open().
|
|
You can look up IP addresses as a string with
|
|
MMDB_lookup_string() or as a pointer to a sockaddr
|
|
structure with MMDB_lookup_sockaddr().
|
|
<P>
|
|
|
|
If the lookup finds the IP address in the database, it returns a
|
|
MMDB_lookup_result_s structure.
|
|
If that structure indicates that the database has data for the IP, there
|
|
are a number of functions that can be used to fetch that data.
|
|
These include MMDB_get_value() and
|
|
MMDB_get_entry_data_list().
|
|
See the function documentation below for more details.
|
|
<P>
|
|
|
|
When you are done with the database handle you should call
|
|
MMDB_close().
|
|
<P>
|
|
|
|
All publicly visible functions, structures, and macros begin with
|
|
"MMDB_".
|
|
<A NAME="lbAE"> </A>
|
|
<H2>DATA STRUCTURES</H2>
|
|
|
|
<P>
|
|
|
|
All data structures exported by this library's maxminddb.h
|
|
header are typedef'd in the form
|
|
typedef struct foo_s { ... } foo_s so you can refer to
|
|
them without the struct prefix.
|
|
<P>
|
|
|
|
This library provides the following data structures:
|
|
<A NAME="lbAF"> </A>
|
|
<H3>MMDB_s</H3>
|
|
|
|
<P>
|
|
|
|
This is the handle for a MaxMind DB file.
|
|
We only document some of this structure's fields intended for public
|
|
use.
|
|
All other fields are subject to change and are intended only for
|
|
internal use.
|
|
<DL COMPACT>
|
|
<DT id="2"><DD>
|
|
<PRE>
|
|
|
|
typedef struct MMDB_s {
|
|
uint32_t flags;
|
|
const char *filename;
|
|
...
|
|
MMDB_metadata_s metadata;
|
|
} MMDB_s;
|
|
|
|
</PRE>
|
|
|
|
<DT id="3">•<DD>
|
|
uint32_t flags - the flags this database was opened with.
|
|
See the MMDB_open() documentation for more details.
|
|
<DT id="4">•<DD>
|
|
const char *filename - the name of the file which was
|
|
opened, as passed to MMDB_open().
|
|
<DT id="5">•<DD>
|
|
MMDB_metadata_s metadata - the metadata for the database.
|
|
</DL>
|
|
<A NAME="lbAG"> </A>
|
|
<H3>MMDB_metadata_s and MMDB_description_s</H3>
|
|
|
|
<P>
|
|
|
|
This structure can be retrieved from the MMDB_s structure.
|
|
It contains the metadata read from the database file.
|
|
Note that you may find it more convenient to access this metadata by
|
|
calling MMDB_get_metadata_as_entry_data_list() instead.
|
|
<DL COMPACT>
|
|
<DT id="6"><DD>
|
|
<PRE>
|
|
|
|
typedef struct MMDB_metadata_s {
|
|
uint32_t node_count;
|
|
uint16_t record_size;
|
|
uint16_t ip_version;
|
|
const char *database_type;
|
|
struct {
|
|
size_t count;
|
|
const char **names;
|
|
} languages;
|
|
uint16_t binary_format_major_version;
|
|
uint16_t binary_format_minor_version;
|
|
uint64_t build_epoch;
|
|
struct {
|
|
size_t count;
|
|
MMDB_description_s **descriptions;
|
|
} description;
|
|
} MMDB_metadata_s;
|
|
|
|
typedef struct MMDB_description_s {
|
|
const char *language;
|
|
const char *description;
|
|
} MMDB_description_s;
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
These structures should be mostly self-explanatory.
|
|
<P>
|
|
|
|
The ip_version member should always be 4 or
|
|
6.
|
|
The binary_format_major_version should always be 2.
|
|
<P>
|
|
|
|
There is no requirement that the database metadata include languages or
|
|
descriptions, so the count for these parts of the metadata can
|
|
be zero.
|
|
All of the other MMDB_metadata_s fields should be populated.
|
|
<A NAME="lbAH"> </A>
|
|
<H3>MMDB_lookup_result_s</H3>
|
|
|
|
<P>
|
|
|
|
This structure is returned as the result of looking up an IP address.
|
|
<DL COMPACT>
|
|
<DT id="7"><DD>
|
|
<PRE>
|
|
|
|
typedef struct MMDB_lookup_result_s {
|
|
bool found_entry;
|
|
MMDB_entry_s entry;
|
|
uint16_t netmask;
|
|
} MMDB_lookup_result_s;
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
If the found_entry member is false then the other members of
|
|
this structure do not contain meaningful values.
|
|
Always check that found_entry is true first.
|
|
<P>
|
|
|
|
The entry member is used to look up the data associated with
|
|
the IP address.
|
|
<P>
|
|
|
|
The netmask member tells you what subnet the IP address belongs
|
|
to in this database.
|
|
For example, if you look up the address 1.1.1.1 in an IPv4
|
|
database and the returned netmask is 16, then the address is
|
|
part of the 1.1.0.0/16 subnet.
|
|
<P>
|
|
|
|
If the database is an IPv6 database, the returned netmask is always an
|
|
IPv6 prefix length (from 0-128), even if that database also
|
|
contains IPv4 networks.
|
|
If you look up an IPv4 address and would like to turn the netmask into
|
|
an IPv4 netmask value, you can simply subtract 96 from the
|
|
value.
|
|
<A NAME="lbAI"> </A>
|
|
<H3>MMDB_result_s</H3>
|
|
|
|
<P>
|
|
|
|
You don't really need to dig around in this structure.
|
|
You'll get this from a MMDB_lookup_result_s structure and
|
|
pass it to various functions.
|
|
<A NAME="lbAJ"> </A>
|
|
<H3>MMDB_entry_data_s</H3>
|
|
|
|
<P>
|
|
|
|
This structure is used to return a single data section entry for an IP.
|
|
These entries can in turn point to other entries, as is the case for
|
|
things like maps and arrays.
|
|
Some members of this structure are not documented as they are only for
|
|
internal use.
|
|
<DL COMPACT>
|
|
<DT id="8"><DD>
|
|
<PRE>
|
|
|
|
typedef struct MMDB_entry_data_s {
|
|
bool has_data;
|
|
union {
|
|
uint32_t pointer;
|
|
const char *utf8_string;
|
|
double double_value;
|
|
const uint8_t *bytes;
|
|
uint16_t uint16;
|
|
uint32_t uint32;
|
|
int32_t int32;
|
|
uint64_t uint64;
|
|
{mmdb_uint128_t or uint8_t[16]} uint128;
|
|
bool boolean;
|
|
float float_value;
|
|
};
|
|
...
|
|
uint32_t data_size;
|
|
uint32_t type;
|
|
} MMDB_entry_data_s;
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
The has_data member is true if data was found for a given
|
|
lookup.
|
|
See MMDB_get_value() for more details.
|
|
If this member is false then none of the other values in the structure
|
|
are meaningful.
|
|
<P>
|
|
|
|
The union at the beginning of the structure defines the actual data.
|
|
To determine which union member is populated you should look at the
|
|
type member.
|
|
The pointer member of the union should never be populated in
|
|
any data returned by the API.
|
|
Pointers should always be resolved internally.
|
|
<P>
|
|
|
|
The data_size member is only relevant for utf8_string
|
|
and bytes data.
|
|
utf8_string is not null terminated and data_size
|
|
must be used to determine its length.
|
|
<P>
|
|
|
|
The type member can be compared to one of the
|
|
MMDB_DTYPE_* macros.
|
|
<A NAME="lbAK"> </A>
|
|
<H3>128-bit Integers</H3>
|
|
|
|
<P>
|
|
|
|
The handling of uint128 data depends on how your platform
|
|
supports 128-bit integers, if it does so at all.
|
|
With GCC 4.4 and 4.5 we can write
|
|
unsigned int __attribute__ ((__mode__ (TI))).
|
|
With newer versions of GCC (4.6+) and clang (3.2+) we can simply write
|
|
"unsigned __int128".
|
|
<P>
|
|
|
|
In order to work around these differences, this library defines an
|
|
mmdb_uint128_t type.
|
|
This type is defined in the maxminddb.h header so you can use
|
|
it in your own code.
|
|
<P>
|
|
|
|
With older compilers, we can't use an integer so we instead use a 16
|
|
byte array of uint8_t values.
|
|
This is the raw data from the database.
|
|
<P>
|
|
|
|
This library provides a public macro MMDB_UINT128_IS_BYTE_ARRAY
|
|
macro.
|
|
If this is true (1), then uint128 values are returned as a byte
|
|
array, if it is false then they are returned as a
|
|
mmdb_uint128_t integer.
|
|
<A NAME="lbAL"> </A>
|
|
<H3>Data Type Macros</H3>
|
|
|
|
<P>
|
|
|
|
This library provides a macro for every data type defined by the MaxMind
|
|
DB spec.
|
|
<DL COMPACT>
|
|
<DT id="9">•<DD>
|
|
MMDB_DATA_TYPE_UTF8_STRING
|
|
<DT id="10">•<DD>
|
|
MMDB_DATA_TYPE_DOUBLE
|
|
<DT id="11">•<DD>
|
|
MMDB_DATA_TYPE_BYTES
|
|
<DT id="12">•<DD>
|
|
MMDB_DATA_TYPE_UINT16
|
|
<DT id="13">•<DD>
|
|
MMDB_DATA_TYPE_UINT32
|
|
<DT id="14">•<DD>
|
|
MMDB_DATA_TYPE_MAP
|
|
<DT id="15">•<DD>
|
|
MMDB_DATA_TYPE_INT32
|
|
<DT id="16">•<DD>
|
|
MMDB_DATA_TYPE_UINT64
|
|
<DT id="17">•<DD>
|
|
MMDB_DATA_TYPE_UINT128
|
|
<DT id="18">•<DD>
|
|
MMDB_DATA_TYPE_ARRAY
|
|
<DT id="19">•<DD>
|
|
MMDB_DATA_TYPE_BOOLEAN
|
|
<DT id="20">•<DD>
|
|
MMDB_DATA_TYPE_FLOAT
|
|
</DL>
|
|
<P>
|
|
|
|
There are also a few types that are for internal use only:
|
|
<DL COMPACT>
|
|
<DT id="21">•<DD>
|
|
MMDB_DATA_TYPE_EXTENDED
|
|
<DT id="22">•<DD>
|
|
MMDB_DATA_TYPE_POINTER
|
|
<DT id="23">•<DD>
|
|
MMDB_DATA_TYPE_CONTAINER
|
|
<DT id="24">•<DD>
|
|
MMDB_DATA_TYPE_END_MARKER
|
|
</DL>
|
|
<P>
|
|
|
|
If you see one of these in returned data then something has gone very
|
|
wrong.
|
|
The database is damaged or was generated incorrectly or there is a bug
|
|
in the libmaxminddb code.
|
|
<A NAME="lbAM"> </A>
|
|
<H3>Pointer Values and MMDB_close()</H3>
|
|
|
|
<P>
|
|
|
|
The utf8_string, bytes, and (maybe) the
|
|
uint128 members of this structure are all pointers directly
|
|
into the database's data section.
|
|
This can either be a malloc'd or mmap'd block
|
|
of memory.
|
|
In either case, these pointers will become invalid after
|
|
MMDB_close() is called.
|
|
<P>
|
|
|
|
If you need to refer to this data after that time you should copy the
|
|
data with an appropriate function (strdup, memcpy,
|
|
etc.).
|
|
<A NAME="lbAN"> </A>
|
|
<H3>MMDB_entry_data_list_s</H3>
|
|
|
|
<P>
|
|
|
|
This structure encapsulates a linked list of MMDB_entry_data_s
|
|
structures.
|
|
<DL COMPACT>
|
|
<DT id="25"><DD>
|
|
<PRE>
|
|
|
|
typedef struct MMDB_entry_data_list_s {
|
|
MMDB_entry_data_s entry_data;
|
|
struct MMDB_entry_data_list_s *next;
|
|
} MMDB_entry_data_list_s;
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This structure lets you look at entire map or array data entry by
|
|
iterating over the linked list.
|
|
<A NAME="lbAO"> </A>
|
|
<H3>MMDB_search_node_s</H3>
|
|
|
|
<P>
|
|
|
|
This structure encapsulates the two records in a search node.
|
|
This is really only useful if you want to write code that iterates over
|
|
the entire search tree as opposed to looking up a specific IP address.
|
|
<DL COMPACT>
|
|
<DT id="26"><DD>
|
|
<PRE>
|
|
|
|
typedef struct MMDB_search_node_s {
|
|
uint64_t left_record;
|
|
uint64_t right_record;
|
|
uint8_t left_record_type;
|
|
uint8_t right_record_type;
|
|
MMDB_entry_s left_record_entry;
|
|
MMDB_entry_s right_record_entry;
|
|
} MMDB_search_node_s;
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
The two record types will take one of the following values:
|
|
<DL COMPACT>
|
|
<DT id="27">•<DD>
|
|
MMDB_RECORD_TYPE_SEARCH_NODE - The record points to the next
|
|
search node.
|
|
<DT id="28">•<DD>
|
|
MMDB_RECORD_TYPE_EMPTY - The record is a placeholder that
|
|
indicates there is no data for the IP address.
|
|
The search should end here.
|
|
<DT id="29">•<DD>
|
|
MMDB_RECORD_TYPE_DATA - The record is for data in the data
|
|
section of the database.
|
|
Use the entry for the record when looking up the data for the record.
|
|
<DT id="30">•<DD>
|
|
MMDB_RECORD_TYPE_INVALID - The record is invalid.
|
|
Either an invalid node was looked up or the database is corrupt.
|
|
</DL>
|
|
<P>
|
|
|
|
The MMDB_entry_s for the record is only valid if the type is
|
|
MMDB_RECORD_TYPE_DATA.
|
|
Attempts to use an entry for other record types will result in an error
|
|
or invalid data.
|
|
<A NAME="lbAP"> </A>
|
|
<H2>STATUS CODES</H2>
|
|
|
|
<P>
|
|
|
|
This library returns (or populates) status codes for many functions.
|
|
These status codes are:
|
|
<DL COMPACT>
|
|
<DT id="31">•<DD>
|
|
MMDB_SUCCESS - everything worked
|
|
<DT id="32">•<DD>
|
|
MMDB_FILE_OPEN_ERROR - there was an error trying to open the
|
|
MaxMind DB file.
|
|
<DT id="33">•<DD>
|
|
MMDB_IO_ERROR - an IO operation failed.
|
|
Check errno for more details.
|
|
<DT id="34">•<DD>
|
|
MMDB_CORRUPT_SEARCH_TREE_ERROR - looking up an IP address in
|
|
the search tree gave us an impossible result.
|
|
The database is damaged or was generated incorrectly or there is a bug
|
|
in the libmaxminddb code.
|
|
<DT id="35">•<DD>
|
|
MMDB_INVALID_METADATA_ERROR - something in the database is
|
|
wrong.
|
|
This includes missing metadata keys as well as impossible values (like
|
|
an ip_version of 7).
|
|
<DT id="36">•<DD>
|
|
MMDB_UNKNOWN_DATABASE_FORMAT_ERROR - The database metadata
|
|
indicates that it's major version is not 2.
|
|
This library can only handle major version 2.
|
|
<DT id="37">•<DD>
|
|
MMDB_OUT_OF_MEMORY_ERROR - a memory allocation call
|
|
(malloc, etc.) failed.
|
|
<DT id="38">•<DD>
|
|
MMDB_INVALID_DATA_ERROR - an entry in the data section
|
|
contains invalid data.
|
|
For example, a uint16 field is claiming to be more than 2 bytes
|
|
long.
|
|
The database is probably damaged or was generated incorrectly.
|
|
<DT id="39">•<DD>
|
|
MMDB_INVALID_LOOKUP_PATH_ERROR - The lookup path passed to
|
|
MMDB_get_value, MMDB_vget_value, or
|
|
MMDB_aget_value contains an array offset that is larger than
|
|
LONG_MAX or smaller than LONG_MIN.
|
|
<DT id="40">•<DD>
|
|
MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR - The lookup path
|
|
passed to MMDB_get_value,MMDB_vget_value, or
|
|
MMDB_aget_value does not match the data structure for the
|
|
entry.
|
|
There are number of reasons this can happen.
|
|
The lookup path could include a key not in a map.
|
|
The lookup path could include an array index larger than an array or
|
|
smaller than the minimum offset from the end of an array.
|
|
It can also happen when the path expects to find a map or array where
|
|
none exist.
|
|
</DL>
|
|
<P>
|
|
|
|
All status codes should be treated as int values.
|
|
<A NAME="lbAQ"> </A>
|
|
<H3>MMDB_strerror()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="41"><DD>
|
|
<PRE>
|
|
|
|
const char *MMDB_strerror(int error_code)
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function takes a status code and returns an English string
|
|
explaining the status.
|
|
<A NAME="lbAR"> </A>
|
|
<H2>FUNCTIONS</H2>
|
|
|
|
<P>
|
|
|
|
This library provides the following exported functions:
|
|
<A NAME="lbAS"> </A>
|
|
<H3>MMDB_open()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="42"><DD>
|
|
<PRE>
|
|
|
|
int MMDB_open(
|
|
const char *const filename,
|
|
uint32_t flags,
|
|
MMDB_s *const mmdb);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function opens a handle to a MaxMind DB file.
|
|
Its return value is a status code as defined above.
|
|
Always check this call's return value.
|
|
<DL COMPACT>
|
|
<DT id="43"><DD>
|
|
<PRE>
|
|
|
|
MMDB_s mmdb;
|
|
int status =
|
|
MMDB_open("/path/to/file.mmdb", MMDB_MODE_MMAP, &mmdb);
|
|
if (MMDB_SUCCESS != status) { ... }
|
|
...
|
|
MMDB_close(&mmdb);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
filename must be encoded as UTF-8 on Windows.
|
|
<P>
|
|
|
|
The MMDB_s structure you pass in can be on the stack or
|
|
allocated from the heap.
|
|
However, if the open is successful it will contain heap-allocated data,
|
|
so you need to close it with MMDB_close().
|
|
If the status returned is not MMDB_SUCCESS then this library
|
|
makes sure that all allocated memory is freed before returning.
|
|
<P>
|
|
|
|
The flags currently provided are:
|
|
<DL COMPACT>
|
|
<DT id="44">•<DD>
|
|
MMDB_MODE_MMAP - open the database with mmap().
|
|
</DL>
|
|
<P>
|
|
|
|
Passing in other values for flags may yield unpredictable
|
|
results.
|
|
In the future we may add additional flags that you can bitwise-or
|
|
together with the mode, as well as additional modes.
|
|
<P>
|
|
|
|
You can also pass 0 as the flags value in which case
|
|
the database will be opened with the default flags.
|
|
However, these defaults may change in future releases.
|
|
The current default is MMDB_MODE_MMAP.
|
|
<A NAME="lbAT"> </A>
|
|
<H3>MMDB_close()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="45"><DD>
|
|
<PRE>
|
|
|
|
void MMDB_close(MMDB_s *const mmdb);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This frees any allocated or mmap'd memory that is held from the
|
|
MMDB_s structure.
|
|
It does not free the memory allocated for the structure itself!
|
|
If you allocated the structure from the heap then you are responsible
|
|
for freeing it.
|
|
<A NAME="lbAU"> </A>
|
|
<H3>MMDB_lookup_string()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="46"><DD>
|
|
<PRE>
|
|
|
|
MMDB_lookup_result_s MMDB_lookup_string(
|
|
MMDB_s *const mmdb,
|
|
const char *const ipstr,
|
|
int *const gai_error,
|
|
int *const mmdb_error);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function looks up an IP address that is passed in as a
|
|
null-terminated string.
|
|
Internally it calls getaddrinfo() to resolve the address into a
|
|
binary form.
|
|
It then calls MMDB_lookup_sockaddr() to look the address up in
|
|
the database.
|
|
If you have already resolved an address you can call
|
|
MMDB_lookup_sockaddr() directly, rather than resolving the
|
|
address twice.
|
|
<DL COMPACT>
|
|
<DT id="47"><DD>
|
|
<PRE>
|
|
|
|
int gai_error, mmdb_error;
|
|
MMDB_lookup_result_s result =
|
|
MMDB_lookup_string(&mmdb, "1.2.3.4", &gai_error, &mmdb_error);
|
|
if (0 != gai_error) { ... }
|
|
if (MMDB_SUCCESS != mmdb_error) { ... }
|
|
|
|
if (result.found_entry) { ... }
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function always returns an MMDB_lookup_result_s structure,
|
|
but you should also check the gai_error and mmdb_error
|
|
parameters.
|
|
If either of these indicates an error then the returned structure is
|
|
meaningless.
|
|
<P>
|
|
|
|
If no error occurred you still need to make sure that the
|
|
found_entry member in the returned result is true.
|
|
If it's not, this means that the IP address does not have an entry
|
|
in the database.
|
|
<P>
|
|
|
|
This function will work with IPv4 addresses even when the database
|
|
contains data for both IPv4 and IPv6 addresses.
|
|
The IPv4 address will be looked up as '::xxx.xxx.xxx.xxx' rather
|
|
than being remapped to the ::ffff:xxx.xxx.xxx.xxx block
|
|
allocated for IPv4-mapped IPv6 addresses.
|
|
<P>
|
|
|
|
If you pass an IPv6 address to a database with only IPv4 data then the
|
|
found_entry member will be false, but the mmdb_error
|
|
status will still be MMDB_SUCCESS.
|
|
<A NAME="lbAV"> </A>
|
|
<H3>MMDB_lookup_sockaddr()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="48"><DD>
|
|
<PRE>
|
|
|
|
MMDB_lookup_result_s MMDB_lookup_sockaddr(
|
|
MMDB_s *const mmdb,
|
|
const struct sockaddr *const sockaddr,
|
|
int *const mmdb_error);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function looks up an IP address that has already been resolved by
|
|
getaddrinfo().
|
|
<P>
|
|
|
|
Other than not calling getaddrinfo() itself, this function is
|
|
identical to the MMDB_lookup_string() function.
|
|
<DL COMPACT>
|
|
<DT id="49"><DD>
|
|
<PRE>
|
|
|
|
int mmdb_error;
|
|
MMDB_lookup_result_s result =
|
|
MMDB_lookup_sockaddr(&mmdb, address->ai_addr, &mmdb_error);
|
|
if (MMDB_SUCCESS != mmdb_error) { ... }
|
|
|
|
if (result.found_entry) { ... }
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<A NAME="lbAW"> </A>
|
|
<H3>Data Lookup Functions</H3>
|
|
|
|
<P>
|
|
|
|
There are three functions for looking up data associated with an IP
|
|
address.
|
|
<DL COMPACT>
|
|
<DT id="50"><DD>
|
|
<PRE>
|
|
|
|
int MMDB_get_value(
|
|
MMDB_entry_s *const start,
|
|
MMDB_entry_data_s *const entry_data,
|
|
...);
|
|
int MMDB_vget_value(
|
|
MMDB_entry_s *const start,
|
|
MMDB_entry_data_s *const entry_data,
|
|
va_list va_path);
|
|
int MMDB_aget_value(
|
|
MMDB_entry_s *const start,
|
|
MMDB_entry_data_s *const entry_data,
|
|
const char *const *const path);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
The three functions allow three slightly different calling styles, but
|
|
they all do the same thing.
|
|
<P>
|
|
|
|
The first parameter is an MMDB_entry_s value.
|
|
In most cases this will come from the MMDB_lookup_result_s
|
|
value returned by MMDB_lookup_string() or
|
|
MMDB_lookup_sockaddr().
|
|
<P>
|
|
|
|
The second parameter is a reference to an MMDB_entry_data_s
|
|
structure.
|
|
This will be populated with the data that is being looked up, if any is
|
|
found.
|
|
If nothing is found, then the has_data member of this structure
|
|
will be false.
|
|
If has_data is true then you can look at the data_type
|
|
member.
|
|
<P>
|
|
|
|
The final parameter is a lookup path.
|
|
The path consists of a set of strings representing either map keys (e.g,
|
|
"city") or array indexes (e.g., "0", "1", "-1") to use in the lookup.
|
|
<P>
|
|
|
|
Negative array indexes will be treated as an offset from the end of the
|
|
array.
|
|
For instance, "-1" refers to the last element of the array.
|
|
<P>
|
|
|
|
The lookup path allows you to navigate a complex data structure.
|
|
For example, given this data:
|
|
<DL COMPACT>
|
|
<DT id="51"><DD>
|
|
<PRE>
|
|
|
|
{
|
|
"names": {
|
|
"en": "Germany",
|
|
"de": "Deutschland"
|
|
},
|
|
"cities": [ "Berlin", "Frankfurt" ]
|
|
}
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
We could look up the English name with this code:
|
|
<DL COMPACT>
|
|
<DT id="52"><DD>
|
|
<PRE>
|
|
|
|
MMDB_lookup_result_s result =
|
|
MMDB_lookup_sockaddr(&mmdb, address->ai_addr, &mmdb_error);
|
|
MMDB_entry_data_s entry_data;
|
|
int status =
|
|
MMDB_get_value(&result.entry, &entry_data,
|
|
"names", "en", NULL);
|
|
if (MMDB_SUCCESS != status) { ... }
|
|
if (entry_data.has_data) { ... }
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
If we wanted to find the first city the lookup path would be
|
|
"cities", "0".
|
|
If you don't provide a lookup path at all, you'll get the entry
|
|
which corresponds to the top level map.
|
|
The lookup path must always end with NULL, regardless of which
|
|
function you call.
|
|
<P>
|
|
|
|
The MMDB_get_value function takes a variable number of
|
|
arguments.
|
|
All of the arguments after the MMDB_entry_data_s * structure
|
|
pointer are the lookup path.
|
|
The last argument must be NULL.
|
|
<P>
|
|
|
|
The MMDB_vget_value function accepts a va_list as the
|
|
lookup path.
|
|
The last element retrieved by va_arg() must be NULL.
|
|
<P>
|
|
|
|
Finally, the MMDB_aget_value accepts an array of strings as the
|
|
lookup path.
|
|
The last member of this array must be NULL.
|
|
<P>
|
|
|
|
If you want to get all of the entry data at once you can call
|
|
MMDB_get_entry_data_list() instead.
|
|
<P>
|
|
|
|
For each of the three functions, the return value is a status code as
|
|
defined above.
|
|
<A NAME="lbAX"> </A>
|
|
<H3>MMDB_get_entry_data_list()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="53"><DD>
|
|
<PRE>
|
|
|
|
int MMDB_get_entry_data_list(
|
|
MMDB_entry_s *start,
|
|
MMDB_entry_data_list_s **const entry_data_list);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function allows you to get all of the data for a complex data
|
|
structure at once, rather than looking up each piece using repeated
|
|
calls to MMDB_get_value().
|
|
<DL COMPACT>
|
|
<DT id="54"><DD>
|
|
<PRE>
|
|
|
|
MMDB_lookup_result_s result =
|
|
MMDB_lookup_sockaddr(&mmdb, address->ai_addr, &mmdb_error);
|
|
MMDB_entry_data_list_s *entry_data_list, *first;
|
|
int status =
|
|
MMDB_get_entry_data_list(&result.entry, &entry_data_list);
|
|
if (MMDB_SUCCESS != status) { ... }
|
|
// save this so we can free this data later
|
|
first = entry_data_list;
|
|
|
|
while (1) {
|
|
MMDB_entry_data_list_s *next = entry_data_list = entry_data_list->next;
|
|
if (NULL == next) {
|
|
break;
|
|
}
|
|
|
|
switch (next->entry_data.type) {
|
|
case MMDB_DATA_TYPE_MAP: { ... }
|
|
case MMDB_DATA_TYPE_UTF8_STRING: { ... }
|
|
...
|
|
}
|
|
|
|
}
|
|
|
|
MMDB_free_entry_data_list(first);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
It's up to you to interpret the entry_data_list data
|
|
structure.
|
|
The list is linked in a depth-first traversal.
|
|
Let's use this structure as an example:
|
|
<DL COMPACT>
|
|
<DT id="55"><DD>
|
|
<PRE>
|
|
|
|
{
|
|
"names": {
|
|
"en": "Germany",
|
|
"de": "Deutschland"
|
|
},
|
|
"cities": [ "Berlin", "Frankfurt" ]
|
|
}
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
The list will consist of the following items:
|
|
<DL COMPACT>
|
|
<DT id="56"> 1.<DD>
|
|
MAP - top level map
|
|
<DT id="57"> 2.<DD>
|
|
UTF8_STRING - "names" key
|
|
<DT id="58"> 3.<DD>
|
|
MAP - map for "names" key
|
|
<DT id="59"> 4.<DD>
|
|
UTF8_STRING - "en" key
|
|
<DT id="60"> 5.<DD>
|
|
UTF8_STRING - value for "en" key
|
|
<DT id="61"> 6.<DD>
|
|
UTF8_STRING - "de" key
|
|
<DT id="62"> 7.<DD>
|
|
UTF8_STRING - value for "de" key
|
|
<DT id="63"> 8.<DD>
|
|
UTF8_STRING - "cities" key
|
|
<DT id="64"> 9.<DD>
|
|
ARRAY - value for "cities" key
|
|
<DT id="65">10.<DD>
|
|
UTF8_STRING - array[0]
|
|
<DT id="66">11.<DD>
|
|
UTF8_STRING - array[1]
|
|
</DL>
|
|
<P>
|
|
|
|
The return value of the function is a status code as defined above.
|
|
<A NAME="lbAY"> </A>
|
|
<H3>MMDB_free_entry_data_list()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="67"><DD>
|
|
<PRE>
|
|
|
|
void MMDB_free_entry_data_list(
|
|
MMDB_entry_data_list_s *const entry_data_list);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
The MMDB_get_entry_data_list() and
|
|
MMDB_get_metadata_as_entry_data_list() functions will allocate
|
|
the linked list structure from the heap.
|
|
Call this function to free the MMDB_entry_data_list_s
|
|
structure.
|
|
<A NAME="lbAZ"> </A>
|
|
<H3>MMDB_get_metadata_as_entry_data_list()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="68"><DD>
|
|
<PRE>
|
|
|
|
int MMDB_get_metadata_as_entry_data_list(
|
|
MMDB_s *const mmdb,
|
|
MMDB_entry_data_list_s **const entry_data_list);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function allows you to retrieve the database metadata as a linked
|
|
list of MMDB_entry_data_list_s structures.
|
|
This can be a more convenient way to deal with the metadata than using
|
|
the metadata structure directly.
|
|
<DL COMPACT>
|
|
<DT id="69"><DD>
|
|
<PRE>
|
|
|
|
MMDB_entry_data_list_s *entry_data_list, *first;
|
|
int status =
|
|
MMDB_get_metadata_as_entry_data_list(&mmdb, &entry_data_list);
|
|
if (MMDB_SUCCESS != status) { ... }
|
|
first = entry_data_list;
|
|
... // do something with the data
|
|
MMDB_free_entry_data_list(first);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
The return value of the function is a status code as defined above.
|
|
<A NAME="lbBA"> </A>
|
|
<H3>MMDB_dump_entry_data_list()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="70"><DD>
|
|
<PRE>
|
|
|
|
int MMDB_dump_entry_data_list(
|
|
FILE *const stream,
|
|
MMDB_entry_data_list_s *const entry_data_list,
|
|
int indent);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function takes a linked list of MMDB_entry_data_list_s
|
|
structures and stringifies it to the given stream.
|
|
The indent parameter is the starting indent level for the
|
|
generated output.
|
|
It is incremented for nested data structures (maps, array, etc.).
|
|
<P>
|
|
|
|
The stream must be a file handle (stdout, etc).
|
|
If your platform provides something like the GNU
|
|
open_memstream() you can use that to capture the output as a
|
|
string.
|
|
<P>
|
|
|
|
The output is formatted in a JSON-ish fashion, but values are marked
|
|
with their data type (except for maps and arrays which are shown with
|
|
"{}" and "[]" respectively).
|
|
<P>
|
|
|
|
The specific output format may change in future releases, so you should
|
|
not rely on the specific formatting produced by this function.
|
|
It is intended to be used to show data to users in a readable way and
|
|
for debugging purposes.
|
|
<P>
|
|
|
|
The return value of the function is a status code as defined above.
|
|
<A NAME="lbBB"> </A>
|
|
<H3>MMDB_read_node()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="71"><DD>
|
|
<PRE>
|
|
|
|
int MMDB_read_node(
|
|
MMDB_s *const mmdb,
|
|
uint32_t node_number,
|
|
MMDB_search_node_s *const node);
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This reads a specific node in the search tree.
|
|
The third argument is a reference to an MMDB_search_node_s
|
|
structure that will be populated by this function.
|
|
<P>
|
|
|
|
The return value is a status code.
|
|
If you pass a node_number that is greater than the number of
|
|
nodes in the database, this function will return
|
|
MMDB_INVALID_NODE_NUMBER_ERROR, otherwise it will return
|
|
MMDB_SUCCESS.
|
|
<P>
|
|
|
|
The first node in the search tree is always node 0.
|
|
If you wanted to iterate over the whole search tree, you would start by
|
|
reading node 0 and then following the the records that make up this
|
|
node, based on the type of each record.
|
|
If the type is MMDB_RECORD_TYPE_SEARCH_NODE then the record
|
|
contains an integer for the next node to look up.
|
|
<A NAME="lbBC"> </A>
|
|
<H3>MMDB_lib_version()</H3>
|
|
|
|
<DL COMPACT>
|
|
<DT id="72"><DD>
|
|
<PRE>
|
|
|
|
const char *MMDB_lib_version(void)
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
This function returns the library version as a string, something like
|
|
"2.0.0".
|
|
<A NAME="lbBD"> </A>
|
|
<H2>EXAMPLE</H2>
|
|
|
|
<DL COMPACT>
|
|
<DT id="73"><DD>
|
|
<PRE>
|
|
|
|
#include <<A HREF="file:///usr/include/errno.h">errno.h</A>>
|
|
#include <<A HREF="file:///usr/include/maxminddb.h">maxminddb.h</A>>
|
|
#include <<A HREF="file:///usr/include/stdlib.h">stdlib.h</A>>
|
|
#include <<A HREF="file:///usr/include/string.h">string.h</A>>
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
char *filename = argv[1];
|
|
char *ip_address = argv[2];
|
|
|
|
MMDB_s mmdb;
|
|
int status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb);
|
|
|
|
if (MMDB_SUCCESS != status) {
|
|
fprintf(stderr, "\n Can't open %s - %s\n",
|
|
filename, MMDB_strerror(status));
|
|
|
|
if (MMDB_IO_ERROR == status) {
|
|
fprintf(stderr, " IO error: %s\n", strerror(errno));
|
|
}
|
|
<A HREF="/cgi-bin/man/man2html?1+exit">exit</A>(1);
|
|
}
|
|
|
|
int gai_error, mmdb_error;
|
|
MMDB_lookup_result_s result =
|
|
MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error);
|
|
|
|
if (0 != gai_error) {
|
|
fprintf(stderr,
|
|
"\n Error from getaddrinfo for %s - %s\n\n",
|
|
ip_address, gai_strerror(gai_error));
|
|
<A HREF="/cgi-bin/man/man2html?2+exit">exit</A>(2);
|
|
}
|
|
|
|
if (MMDB_SUCCESS != mmdb_error) {
|
|
fprintf(stderr,
|
|
"\n Got an error from libmaxminddb: %s\n\n",
|
|
MMDB_strerror(mmdb_error));
|
|
<A HREF="/cgi-bin/man/man2html?3+exit">exit</A>(3);
|
|
}
|
|
|
|
MMDB_entry_data_list_s *entry_data_list = NULL;
|
|
|
|
int exit_code = 0;
|
|
if (result.found_entry) {
|
|
int status = MMDB_get_entry_data_list(&result.entry,
|
|
&entry_data_list);
|
|
|
|
if (MMDB_SUCCESS != status) {
|
|
fprintf(
|
|
stderr,
|
|
"Got an error looking up the entry data - %s\n",
|
|
MMDB_strerror(status));
|
|
exit_code = 4;
|
|
goto end;
|
|
}
|
|
|
|
if (NULL != entry_data_list) {
|
|
MMDB_dump_entry_data_list(stdout, entry_data_list, 2);
|
|
}
|
|
} else {
|
|
fprintf(
|
|
stderr,
|
|
"\n No entry for this IP address (%s) was found\n\n",
|
|
ip_address);
|
|
exit_code = 5;
|
|
}
|
|
|
|
end:
|
|
MMDB_free_entry_data_list(entry_data_list);
|
|
MMDB_close(&mmdb);
|
|
exit(exit_code);
|
|
}
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<A NAME="lbBE"> </A>
|
|
<H2>THREAD SAFETY</H2>
|
|
|
|
<P>
|
|
|
|
This library is thread safe when compiled and linked with a thread-safe
|
|
malloc and free implementation.
|
|
<A NAME="lbBF"> </A>
|
|
<H2>INSTALLATION AND SOURCE</H2>
|
|
|
|
<P>
|
|
|
|
You can download the latest release of libmaxminddb from
|
|
GitHub (<A HREF="https://github.com/maxmind/libmaxminddb/releases).">https://github.com/maxmind/libmaxminddb/releases).</A>
|
|
<P>
|
|
|
|
Our GitHub repo (<A HREF="https://github.com/maxmind/libmaxminddb)">https://github.com/maxmind/libmaxminddb)</A> is publicly
|
|
available.
|
|
Please fork it!
|
|
<A NAME="lbBG"> </A>
|
|
<H2>BUG REPORTS AND PULL REQUESTS</H2>
|
|
|
|
<P>
|
|
|
|
Please report all issues to our GitHub issue
|
|
tracker (<A HREF="https://github.com/maxmind/libmaxminddb/issues).">https://github.com/maxmind/libmaxminddb/issues).</A>
|
|
We welcome bug reports and pull requests.
|
|
Please note that pull requests are greatly preferred over patches.
|
|
<A NAME="lbBH"> </A>
|
|
<H2>AUTHORS</H2>
|
|
|
|
<P>
|
|
|
|
This library was written by Boris Zentner (<A HREF="mailto:bzentner@maxmind.com">bzentner@maxmind.com</A>) and
|
|
Dave Rolsky (<A HREF="mailto:drolsky@maxmind.com">drolsky@maxmind.com</A>).
|
|
<A NAME="lbBI"> </A>
|
|
<H2>COPYRIGHT AND LICENSE</H2>
|
|
|
|
<P>
|
|
|
|
Copyright 2013-2014 MaxMind, Inc.
|
|
<P>
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
<DL COMPACT>
|
|
<DT id="74"><DD>
|
|
<PRE>
|
|
|
|
<A HREF="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</A>
|
|
|
|
</PRE>
|
|
|
|
</DL>
|
|
<P>
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
<A NAME="lbBJ"> </A>
|
|
<H2>SEE ALSO</H2>
|
|
|
|
<P>
|
|
|
|
<A HREF="/cgi-bin/man/man2html?1+mmdblookup">mmdblookup</A>(1)
|
|
<P>
|
|
|
|
<HR>
|
|
<A NAME="index"> </A><H2>Index</H2>
|
|
<DL>
|
|
<DT id="75"><A HREF="#lbAB">NAME</A><DD>
|
|
<DT id="76"><A HREF="#lbAC">SYNOPSIS</A><DD>
|
|
<DT id="77"><A HREF="#lbAD">DESCRIPTION</A><DD>
|
|
<DT id="78"><A HREF="#lbAE">DATA STRUCTURES</A><DD>
|
|
<DL>
|
|
<DT id="79"><A HREF="#lbAF">MMDB_s</A><DD>
|
|
<DT id="80"><A HREF="#lbAG">MMDB_metadata_s and MMDB_description_s</A><DD>
|
|
<DT id="81"><A HREF="#lbAH">MMDB_lookup_result_s</A><DD>
|
|
<DT id="82"><A HREF="#lbAI">MMDB_result_s</A><DD>
|
|
<DT id="83"><A HREF="#lbAJ">MMDB_entry_data_s</A><DD>
|
|
<DT id="84"><A HREF="#lbAK">128-bit Integers</A><DD>
|
|
<DT id="85"><A HREF="#lbAL">Data Type Macros</A><DD>
|
|
<DT id="86"><A HREF="#lbAM">Pointer Values and MMDB_close()</A><DD>
|
|
<DT id="87"><A HREF="#lbAN">MMDB_entry_data_list_s</A><DD>
|
|
<DT id="88"><A HREF="#lbAO">MMDB_search_node_s</A><DD>
|
|
</DL>
|
|
<DT id="89"><A HREF="#lbAP">STATUS CODES</A><DD>
|
|
<DL>
|
|
<DT id="90"><A HREF="#lbAQ">MMDB_strerror()</A><DD>
|
|
</DL>
|
|
<DT id="91"><A HREF="#lbAR">FUNCTIONS</A><DD>
|
|
<DL>
|
|
<DT id="92"><A HREF="#lbAS">MMDB_open()</A><DD>
|
|
<DT id="93"><A HREF="#lbAT">MMDB_close()</A><DD>
|
|
<DT id="94"><A HREF="#lbAU">MMDB_lookup_string()</A><DD>
|
|
<DT id="95"><A HREF="#lbAV">MMDB_lookup_sockaddr()</A><DD>
|
|
<DT id="96"><A HREF="#lbAW">Data Lookup Functions</A><DD>
|
|
<DT id="97"><A HREF="#lbAX">MMDB_get_entry_data_list()</A><DD>
|
|
<DT id="98"><A HREF="#lbAY">MMDB_free_entry_data_list()</A><DD>
|
|
<DT id="99"><A HREF="#lbAZ">MMDB_get_metadata_as_entry_data_list()</A><DD>
|
|
<DT id="100"><A HREF="#lbBA">MMDB_dump_entry_data_list()</A><DD>
|
|
<DT id="101"><A HREF="#lbBB">MMDB_read_node()</A><DD>
|
|
<DT id="102"><A HREF="#lbBC">MMDB_lib_version()</A><DD>
|
|
</DL>
|
|
<DT id="103"><A HREF="#lbBD">EXAMPLE</A><DD>
|
|
<DT id="104"><A HREF="#lbBE">THREAD SAFETY</A><DD>
|
|
<DT id="105"><A HREF="#lbBF">INSTALLATION AND SOURCE</A><DD>
|
|
<DT id="106"><A HREF="#lbBG">BUG REPORTS AND PULL REQUESTS</A><DD>
|
|
<DT id="107"><A HREF="#lbBH">AUTHORS</A><DD>
|
|
<DT id="108"><A HREF="#lbBI">COPYRIGHT AND LICENSE</A><DD>
|
|
<DT id="109"><A HREF="#lbBJ">SEE ALSO</A><DD>
|
|
</DL>
|
|
<HR>
|
|
This document was created by
|
|
<A HREF="/cgi-bin/man/man2html">man2html</A>,
|
|
using the manual pages.<BR>
|
|
Time: 00:05:47 GMT, March 31, 2021
|
|
</BODY>
|
|
</HTML>
|