1 #ifdef __cplusplus 2 extern "C" { 3 #endif 4 5 #ifndef MAXMINDDB_H 6 #define MAXMINDDB_H 7 8 /* Request POSIX.1-2008. However, we want to remain compatible with 9 * POSIX.1-2001 (since we have been historically and see no reason to drop 10 * compatibility). By requesting POSIX.1-2008, we can conditionally use 11 * features provided by that standard if the implementation provides it. We can 12 * check for what the implementation provides by checking the _POSIX_VERSION 13 * macro after including unistd.h. If a feature is in POSIX.1-2008 but not 14 * POSIX.1-2001, check that macro before using the feature (or check for the 15 * feature directly if possible). */ 16 #ifndef _POSIX_C_SOURCE 17 #define _POSIX_C_SOURCE 200809L 18 #endif 19 20 #include "maxminddb_config.h" 21 #include <stdarg.h> 22 #include <stdbool.h> 23 #include <stdint.h> 24 #include <stdio.h> 25 #include <sys/types.h> 26 27 #ifdef _WIN32 28 #include <winsock2.h> 29 #include <ws2tcpip.h> 30 /* libmaxminddb package version from configure */ 31 #define PACKAGE_VERSION "1.4.3" 32 33 typedef ADDRESS_FAMILY sa_family_t; 34 35 #if defined(_MSC_VER) 36 /* MSVC doesn't define signed size_t, copy it from configure */ 37 #define ssize_t SSIZE_T 38 39 /* MSVC doesn't support restricted pointers */ 40 #define restrict 41 #endif 42 #else 43 #include <netdb.h> 44 #include <netinet/in.h> 45 #include <sys/socket.h> 46 #endif 47 48 #define MMDB_DATA_TYPE_EXTENDED (0) 49 #define MMDB_DATA_TYPE_POINTER (1) 50 #define MMDB_DATA_TYPE_UTF8_STRING (2) 51 #define MMDB_DATA_TYPE_DOUBLE (3) 52 #define MMDB_DATA_TYPE_BYTES (4) 53 #define MMDB_DATA_TYPE_UINT16 (5) 54 #define MMDB_DATA_TYPE_UINT32 (6) 55 #define MMDB_DATA_TYPE_MAP (7) 56 #define MMDB_DATA_TYPE_INT32 (8) 57 #define MMDB_DATA_TYPE_UINT64 (9) 58 #define MMDB_DATA_TYPE_UINT128 (10) 59 #define MMDB_DATA_TYPE_ARRAY (11) 60 #define MMDB_DATA_TYPE_CONTAINER (12) 61 #define MMDB_DATA_TYPE_END_MARKER (13) 62 #define MMDB_DATA_TYPE_BOOLEAN (14) 63 #define MMDB_DATA_TYPE_FLOAT (15) 64 65 #define MMDB_RECORD_TYPE_SEARCH_NODE (0) 66 #define MMDB_RECORD_TYPE_EMPTY (1) 67 #define MMDB_RECORD_TYPE_DATA (2) 68 #define MMDB_RECORD_TYPE_INVALID (3) 69 70 /* flags for open */ 71 #define MMDB_MODE_MMAP (1) 72 #define MMDB_MODE_MASK (7) 73 74 /* error codes */ 75 #define MMDB_SUCCESS (0) 76 #define MMDB_FILE_OPEN_ERROR (1) 77 #define MMDB_CORRUPT_SEARCH_TREE_ERROR (2) 78 #define MMDB_INVALID_METADATA_ERROR (3) 79 #define MMDB_IO_ERROR (4) 80 #define MMDB_OUT_OF_MEMORY_ERROR (5) 81 #define MMDB_UNKNOWN_DATABASE_FORMAT_ERROR (6) 82 #define MMDB_INVALID_DATA_ERROR (7) 83 #define MMDB_INVALID_LOOKUP_PATH_ERROR (8) 84 #define MMDB_LOOKUP_PATH_DOES_NOT_MATCH_DATA_ERROR (9) 85 #define MMDB_INVALID_NODE_NUMBER_ERROR (10) 86 #define MMDB_IPV6_LOOKUP_IN_IPV4_DATABASE_ERROR (11) 87 88 #if !(MMDB_UINT128_IS_BYTE_ARRAY) 89 #if MMDB_UINT128_USING_MODE 90 typedef unsigned int mmdb_uint128_t __attribute__ ((__mode__(TI))); 91 #else 92 typedef unsigned __int128 mmdb_uint128_t; 93 #endif 94 #endif 95 96 /* This is a pointer into the data section for a given IP address lookup */ 97 typedef struct MMDB_entry_s { 98 const struct MMDB_s *mmdb; 99 uint32_t offset; 100 } MMDB_entry_s; 101 102 typedef struct MMDB_lookup_result_s { 103 bool found_entry; 104 MMDB_entry_s entry; 105 uint16_t netmask; 106 } MMDB_lookup_result_s; 107 108 typedef struct MMDB_entry_data_s { 109 bool has_data; 110 union { 111 uint32_t pointer; 112 const char *utf8_string; 113 double double_value; 114 const uint8_t *bytes; 115 uint16_t uint16; 116 uint32_t uint32; 117 int32_t int32; 118 uint64_t uint64; 119 #if MMDB_UINT128_IS_BYTE_ARRAY 120 uint8_t uint128[16]; 121 #else 122 mmdb_uint128_t uint128; 123 #endif 124 bool boolean; 125 float float_value; 126 }; 127 /* This is a 0 if a given entry cannot be found. This can only happen 128 * when a call to MMDB_(v)get_value() asks for hash keys or array 129 * indices that don't exist. */ 130 uint32_t offset; 131 /* This is the next entry in the data section, but it's really only 132 * relevant for entries that part of a larger map or array 133 * struct. There's no good reason for an end user to look at this 134 * directly. */ 135 uint32_t offset_to_next; 136 /* This is only valid for strings, utf8_strings or binary data */ 137 uint32_t data_size; 138 /* This is an MMDB_DATA_TYPE_* constant */ 139 uint32_t type; 140 } MMDB_entry_data_s; 141 142 /* This is the return type when someone asks for all the entry data in a map or array */ 143 typedef struct MMDB_entry_data_list_s { 144 MMDB_entry_data_s entry_data; 145 struct MMDB_entry_data_list_s *next; 146 void *pool; 147 } MMDB_entry_data_list_s; 148 149 typedef struct MMDB_description_s { 150 const char *language; 151 const char *description; 152 } MMDB_description_s; 153 154 /* WARNING: do not add new fields to this struct without bumping the SONAME. 155 * The struct is allocated by the users of this library and increasing the 156 * size will cause existing users to allocate too little space when the shared 157 * library is upgraded */ 158 typedef struct MMDB_metadata_s { 159 uint32_t node_count; 160 uint16_t record_size; 161 uint16_t ip_version; 162 const char *database_type; 163 struct { 164 size_t count; 165 const char **names; 166 } languages; 167 uint16_t binary_format_major_version; 168 uint16_t binary_format_minor_version; 169 uint64_t build_epoch; 170 struct { 171 size_t count; 172 MMDB_description_s **descriptions; 173 } description; 174 /* See above warning before adding fields */ 175 } MMDB_metadata_s; 176 177 /* WARNING: do not add new fields to this struct without bumping the SONAME. 178 * The struct is allocated by the users of this library and increasing the 179 * size will cause existing users to allocate too little space when the shared 180 * library is upgraded */ 181 typedef struct MMDB_ipv4_start_node_s { 182 uint16_t netmask; 183 uint32_t node_value; 184 /* See above warning before adding fields */ 185 } MMDB_ipv4_start_node_s; 186 187 /* WARNING: do not add new fields to this struct without bumping the SONAME. 188 * The struct is allocated by the users of this library and increasing the 189 * size will cause existing users to allocate too little space when the shared 190 * library is upgraded */ 191 typedef struct MMDB_s { 192 uint32_t flags; 193 const char *filename; 194 ssize_t file_size; 195 const uint8_t *file_content; 196 const uint8_t *data_section; 197 uint32_t data_section_size; 198 const uint8_t *metadata_section; 199 uint32_t metadata_section_size; 200 uint16_t full_record_byte_size; 201 uint16_t depth; 202 MMDB_ipv4_start_node_s ipv4_start_node; 203 MMDB_metadata_s metadata; 204 /* See above warning before adding fields */ 205 } MMDB_s; 206 207 typedef struct MMDB_search_node_s { 208 uint64_t left_record; 209 uint64_t right_record; 210 uint8_t left_record_type; 211 uint8_t right_record_type; 212 MMDB_entry_s left_record_entry; 213 MMDB_entry_s right_record_entry; 214 } MMDB_search_node_s; 215 216 extern int MMDB_open(const char *const filename, uint32_t flags, 217 MMDB_s *const mmdb); 218 extern MMDB_lookup_result_s MMDB_lookup_string(const MMDB_s *const mmdb, 219 const char *const ipstr, 220 int *const gai_error, 221 int *const mmdb_error); 222 extern MMDB_lookup_result_s MMDB_lookup_sockaddr( 223 const MMDB_s *const mmdb, 224 const struct sockaddr *const sockaddr, 225 int *const mmdb_error); 226 extern int MMDB_read_node(const MMDB_s *const mmdb, 227 uint32_t node_number, 228 MMDB_search_node_s *const node); 229 extern int MMDB_get_value(MMDB_entry_s *const start, 230 MMDB_entry_data_s *const entry_data, 231 ...); 232 extern int MMDB_vget_value(MMDB_entry_s *const start, 233 MMDB_entry_data_s *const entry_data, 234 va_list va_path); 235 extern int MMDB_aget_value(MMDB_entry_s *const start, 236 MMDB_entry_data_s *const entry_data, 237 const char *const *const path); 238 extern int MMDB_get_metadata_as_entry_data_list( 239 const MMDB_s *const mmdb, MMDB_entry_data_list_s **const entry_data_list); 240 extern int MMDB_get_entry_data_list( 241 MMDB_entry_s *start, MMDB_entry_data_list_s **const entry_data_list); 242 extern void MMDB_free_entry_data_list( 243 MMDB_entry_data_list_s *const entry_data_list); 244 extern void MMDB_close(MMDB_s *const mmdb); 245 extern const char *MMDB_lib_version(void); 246 extern int MMDB_dump_entry_data_list(FILE *const stream, 247 MMDB_entry_data_list_s *const entry_data_list, 248 int indent); 249 extern const char *MMDB_strerror(int error_code); 250 251 #endif /* MAXMINDDB_H */ 252 253 #ifdef __cplusplus 254 } 255 #endif 256