Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
libmaxminddb(3)		   Library Functions Manual	       libmaxminddb(3)

NAME
       libmaxminddb - a	library	for working with MaxMind DB files

SYNOPSIS
       #include	<maxminddb.h>

       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(
	   const MMDB_s	*const mmdb,
	   const char *const ipstr,
	   int *const gai_error,
	   int *const mmdb_error);
       MMDB_lookup_result_s MMDB_lookup_sockaddr(
	   const 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(
	   const 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(
	   const 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;

DESCRIPTION
       The libmaxminddb	library	provides functions for working with MaxMind DB
       files.	See <https://maxmind.github.io/MaxMind-DB/> 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().

       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.

       When   you   are	  done	with  the  database  handle  you  should  call
       MMDB_close().

       All publicly visible  functions,	 structures,  and  macros  begin  with
       "MMDB_".

DATA STRUCTURES
       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 re-
       fer to them without the struct prefix.

       This library provides the following data	structures:

   MMDB_s
       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  sub-
       ject to change and are intended only for	internal use.

       typedef struct MMDB_s {
	   uint32_t flags;
	   const char *filename;
	   ...
	   MMDB_metadata_s metadata;
       } MMDB_s;

         uint32_t  flags  -  the flags	this database was opened with. See the
	  MMDB_open() documentation for	more details.
         const	char *filename - the name of the file  which  was  opened,  as
	  passed to MMDB_open().
         MMDB_metadata_s metadata - the metadata for the database.

   MMDB_metadata_s and MMDB_description_s
       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_meta-
       data_as_entry_data_list() instead.

       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;

       These structures	should be mostly self-explanatory.

       The ip_version member should always be 4	or  6.	The  binary_format_ma-
       jor_version should always be 2.

       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.

   MMDB_lookup_result_s
       This structure is returned as the result	of looking up an IP address.

       typedef struct MMDB_lookup_result_s {
	   bool	found_entry;
	   MMDB_entry_s	entry;
	   uint16_t netmask;
       } MMDB_lookup_result_s;

       If  the	found_entry  member  is	 false	then the other members of this
       structure do not	contain	meaningful values. Always check	that found_en-
       try is true first.

       The entry member	is used	to look	up the data associated with the	IP ad-
       dress.

       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.

       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.

   MMDB_entry_s
       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.

   MMDB_entry_data_s
       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.

       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;

       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.

       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	inter-
       nally.

       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	deter-
       mine its	length.

       The  type member	can be compared	to one of the MMDB_DATA_TYPE_* macros.
       When type is MMDB_DATA_TYPE_MAP or MMDB_DATA_TYPE_ARRAY,	the entry rep-
       resents a collection. To	access individual items	within the collection,
       use MMDB_get_value() with the appropriate lookup	path from the original
       entry. To iterate over all items, use MMDB_get_entry_data_list().

   128-bit Integers
       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".

       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.

       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.

       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.

   Data	Type Macros
       This  library  provides a macro for every data type defined by the Max-
       Mind DB spec.

         MMDB_DATA_TYPE_UTF8_STRING
         MMDB_DATA_TYPE_DOUBLE
         MMDB_DATA_TYPE_BYTES
         MMDB_DATA_TYPE_UINT16
         MMDB_DATA_TYPE_UINT32
         MMDB_DATA_TYPE_MAP
         MMDB_DATA_TYPE_INT32
         MMDB_DATA_TYPE_UINT64
         MMDB_DATA_TYPE_UINT128
         MMDB_DATA_TYPE_ARRAY
         MMDB_DATA_TYPE_BOOLEAN
         MMDB_DATA_TYPE_FLOAT

       There are also a	few types that are for internal	use only:

         MMDB_DATA_TYPE_EXTENDED
         MMDB_DATA_TYPE_POINTER
         MMDB_DATA_TYPE_CONTAINER
         MMDB_DATA_TYPE_END_MARKER

       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.

   Pointer Values and MMDB_close()
       The  utf8_string, bytes,	and (maybe) the	uint128	members	of this	struc-
       ture are	all pointers directly into the database's data	section.  This
       can  either  be	a  calloc'd or mmap'd block of memory. In either case,
       these pointers will become invalid after	MMDB_close() is	called.

       If you need to refer to this data after that time you should  copy  the
       data with an appropriate	function (strdup, memcpy, etc.).

   MMDB_entry_data_list_s
       This  structure	encapsulates a linked list of MMDB_entry_data_s	struc-
       tures.

       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;

       This structure lets you look at entire map or array data	entry by iter-
       ating over the linked list.

   MMDB_search_node_s
       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 en-
       tire search tree	as opposed to looking up a specific IP address.

       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;

       The two record types will take one of the following values:

         MMDB_RECORD_TYPE_SEARCH_NODE	- The record points to the next	search
	  node.
         MMDB_RECORD_TYPE_EMPTY - The record is a placeholder that  indicates
	  there	is no data for the IP address. The search should end here.
         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.
         MMDB_RECORD_TYPE_INVALID  - The record is invalid. Either an invalid
	  node was looked up or	the database is	corrupt.

       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.

STATUS CODES
       This library returns (or	populates) status codes	 for  many  functions.
       These status codes are:

         MMDB_SUCCESS - everything worked
         MMDB_FILE_OPEN_ERROR - there was an error trying to open the MaxMind
	  DB file.
         MMDB_IO_ERROR	 -  an	IO  operation failed. Check errno for more de-
	  tails.
         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.
         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).

         MMDB_UNKNOWN_DATABASE_FORMAT_ERROR - The database metadata indicates
	  that its major version is not	2. This	library	can only handle	 major
	  version 2.
         MMDB_OUT_OF_MEMORY_ERROR  -  a memory	allocation call	(malloc, etc.)
	  failed.
         MMDB_INVALID_DATA_ERROR - an entry in	the data section contains  in-
	  valid	 data. For example, a uint16 field is claiming to be more than
	  2 bytes long.	 The database is probably damaged or was generated in-
	  correctly.
         MMDB_INVALID_LOOKUP_PATH_ERROR  -  The   lookup   path   passed   to
	  MMDB_get_value,  MMDB_vget_value, or MMDB_aget_value contains	an ar-
	  ray offset that is larger than LONGMAX or smaller than LONGMIN.
         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.

       All status codes	should be treated as int values.

   MMDB_strerror()
       const char *MMDB_strerror(int error_code)

       This function takes a status code and returns  an  English  string  ex-
       plaining	the status.

FUNCTIONS
       This library provides the following exported functions:

   MMDB_open()
       int MMDB_open(
	   const char *const filename,
	   uint32_t flags,
	   MMDB_s *const mmdb);

       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.

       MMDB_s mmdb;
       int status =
	   MMDB_open("/path/to/file.mmdb", MMDB_MODE_MMAP, &mmdb);
       if (MMDB_SUCCESS	!= status) { ... }
       ...
       MMDB_close(&mmdb);

       filename	must be	encoded	as UTF-8 on Windows.

       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-allo-
       cated  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  al-
       located memory is freed before returning.

       The flags currently provided are:

         MMDB_MODE_MMAP - open	the database with mmap().

       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.

       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.

   MMDB_close()
       void MMDB_close(MMDB_s *const mmdb);

       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  it-
       self! If	you allocated the structure from the heap then you are respon-
       sible for freeing it.

   MMDB_lookup_string()
       MMDB_lookup_result_s MMDB_lookup_string(
	   const MMDB_s	*const mmdb,
	   const char *const ipstr,
	   int *const gai_error,
	   int *const mmdb_error);

       This function looks up an IP address that is passed in as a null-termi-
       nated  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 ad-
       dress twice.

       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) { ... }

       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.

       When  *gai_error	 is non-zero (i.e., getaddrinfo() failed), *mmdb_error
       is set to MMDB_SUCCESS because no database error	occurred.  You	should
       always check *gai_error first.

       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.

       This function will work with IPv4 addresses even	when the database con-
       tains 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.

       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.

   MMDB_lookup_sockaddr()
       MMDB_lookup_result_s MMDB_lookup_sockaddr(
	   const MMDB_s	*const mmdb,
	   const struct	sockaddr *const	sockaddr,
	   int *const mmdb_error);

       This function looks up an IP address that has already been resolved  by
       getaddrinfo().

       Other than not calling getaddrinfo() itself, this function is identical
       to the MMDB_lookup_string() function.

       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) { ... }

   Data	Lookup Functions
       There are three functions for looking up	data associated	with an	IP ad-
       dress.

       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);

       The  three functions allow three	slightly different calling styles, but
       they all	do the same thing.

       The first parameter is a	pointer	to an  MMDB_entry_s  struct.  In  most
       cases  this will	be a pointer to	the entry field	of the MMDB_lookup_re-
       sult_s value  returned  by  MMDB_lookup_string()	 or  MMDB_lookup_sock-
       addr().

       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 type mem-
       ber.

       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.

       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.

       The lookup path allows you to navigate a	complex	 data  structure.  For
       example,	given this data:

       {
	   "names": {
	       "en": "Germany",
	       "de": "Deutschland"
	   },
	   "cities": [ "Berlin", "Frankfurt" ]
       }

       We could	look up	the English name with this code:

       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)	{ ... }

       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.

       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.

       The  MMDB_vget_value function accepts a va_list as the lookup path. The
       last element retrieved by va_arg() must be NULL.

       Finally,	the MMDB_aget_value accepts an array of	strings	as the	lookup
       path.  The last member of this array must be NULL.

       To  look	up multiple keys within	the same map, use the full lookup path
       for each	key. For example, to get both the en and de  values  from  the
       names  map,  make  separate calls with "names", "en", NULL and "names",
       "de", NULL. If you need all of the data from a complex structure	rather
       than specific values, MMDB_get_entry_data_list()	is more	efficient than
       making many individual calls.

       For each	of the three functions,	the return value is a status  code  as
       defined above.

   MMDB_get_entry_data_list()
       int MMDB_get_entry_data_list(
	   MMDB_entry_s	*start,
	   MMDB_entry_data_list_s **const entry_data_list);

       The  start  parameter  is  a pointer to an MMDB_entry_s struct. In most
       cases this will be a pointer to the entry field of the  MMDB_lookup_re-
       sult_s  value  returned	by  MMDB_lookup_string()  or MMDB_lookup_sock-
       addr().

       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().

       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);

       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:

       {
	   "names": {
	       "en": "Germany",
	       "de": "Deutschland"
	   },
	   "cities": [ "Berlin", "Frankfurt" ]
       }

       The list	will consist of	the following items:

       1.  MAP - top level map
       2.  UTF8_STRING - "names" key
       3.  MAP - map for "names" key
       4.  UTF8_STRING - "en" key
       5.  UTF8_STRING - value for "en"	key
       6.  UTF8_STRING - "de" key
       7.  UTF8_STRING - value for "de"	key
       8.  UTF8_STRING - "cities" key
       9.  ARRAY - value for "cities" key
       10. UTF8_STRING - array[0]
       11. UTF8_STRING - array[1]

       The return value	of the function	is a status code as defined above.

   MMDB_free_entry_data_list()
       void MMDB_free_entry_data_list(
	   MMDB_entry_data_list_s *const entry_data_list);

       The     MMDB_get_entry_data_list()     and     MMDB_get_metadata_as_en-
       try_data_list()	functions will allocate	the linked list	structure from
       the heap. Call this function to free the	MMDB_entry_data_list_s	struc-
       ture.

   MMDB_get_metadata_as_entry_data_list()
       int MMDB_get_metadata_as_entry_data_list(
	   const MMDB_s	*const mmdb,
	   MMDB_entry_data_list_s **const entry_data_list);

       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	conve-
       nient  way  to deal with	the metadata than using	the metadata structure
       directly.

	   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);

       The return value	of the function	is a status code as defined above.

   MMDB_dump_entry_data_list()
       int MMDB_dump_entry_data_list(
	   FILE	*const stream,
	   MMDB_entry_data_list_s *const entry_data_list,
	   int indent);

       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.).

       The  stream  must be a file handle (stdout, etc). If your platform pro-
       vides something like the	GNU open_memstream() you can use that to  cap-
       ture the	output as a string.

       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).

       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 de-
       bugging purposes.

       The return value	of the function	is a status code as defined above.

   MMDB_read_node()
       int MMDB_read_node(
	   const MMDB_s	*const mmdb,
	   uint32_t node_number,
	   MMDB_search_node_s *const node);

       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.

       The return value	is a status code. If you pass a	 node_number  that  is
       greater	than  or  equal	 to  the number	of nodes in the	database, this
       function	will return MMDB_INVALID_NODE_NUMBER_ERROR, otherwise it  will
       return MMDB_SUCCESS.

       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  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.

   MMDB_lib_version()
       const char *MMDB_lib_version(void)

       This  function  returns the library version as a	string,	something like
       "2.0.0".

EXAMPLE
       #include	<errno.h>
       #include	<maxminddb.h>
       #include	<stdlib.h>
       #include	<string.h>

       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));
	       }
	       exit(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));
	       exit(2);
	   }

	   if (MMDB_SUCCESS != mmdb_error) {
	       fprintf(stderr,
		       "\n  Got	an error from libmaxminddb: %s\n\n",
		       MMDB_strerror(mmdb_error));
	       exit(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);
       }

REQUIREMENTS
       libmaxminddb requires a minimum of POSIX.1-2001 support.	If not	speci-
       fied  at	 compilation time, it defaults to requesting POSIX.1-2008 sup-
       port.

THREAD SAFETY
       This library is thread safe when	compiled and linked with a thread-safe
       malloc and free implementation.

INSTALLATION AND SOURCE
       You can	download  the  latest  release	of  libmaxminddb  from	GitHub
       <https://github.com/maxmind/libmaxminddb/releases>.

       Our  GitHub  repo <https://github.com/maxmind/libmaxminddb> is publicly
       available. Please fork it!

BUG REPORTS AND	PULL REQUESTS
       Please	report	 all   issues	to   our    GitHub    issue    tracker
       <https://github.com/maxmind/libmaxminddb/issues>.  We  welcome  bug re-
       ports and pull requests.	Please note that  pull	requests  are  greatly
       preferred over patches.

AUTHORS
       This  library was written by Boris Zentner (<bzentner@maxmind.com>) and
       Dave Rolsky (<drolsky@maxmind.com>).

COPYRIGHT AND LICENSE
       Copyright 2013-2026 MaxMind, Inc.

       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

       https://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed  to	in  writing,  software
       distributed under the License is	distributed on an "AS IS" BASIS, WITH-
       OUT  WARRANTIES	OR  CONDITIONS OF ANY KIND, either express or implied.
       See the License for the specific	 language  governing  permissions  and
       limitations under the License.

SEE ALSO
       mmdblookup(1)

							       libmaxminddb(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=MMDB_lookup_string&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help