1 /*
2  * Project    : ipv6calc
3  * File       : databases/lib/libipv6calc_db_wrapper.h
4  * Version    : $Id: 051d9d28476004cf1b05e010d7b7ad3cfbe7a9d0 $
5  * Copyright  : 2013-2020 by Peter Bieringer <pb (at) bieringer.de>
6  *
7  * Information:
8  *  Header file for libipv6calc_db_wrapper.c
9  */
10 
11 #ifdef HAVE_BERKELEY_DB_SUPPORT
12 #include <db.h>
13 #endif // HAVE_BERKELEY_DB_SUPPORT
14 
15 #include "ipv6calctypes.h"
16 #include "libmac.h"
17 #include "libipv4addr.h"
18 #include "libipv6addr.h"
19 
20 #ifndef _libipv6calc_db_wrapper_h
21 
22 #define _libipv6calc_db_wrapper_h 1
23 
24 extern uint32_t wrapper_features;
25 extern uint32_t wrapper_features_by_source[];
26 extern uint32_t wrapper_features_by_source_implemented[];
27 
28 #define IPV6CALC_PROTO_IPV4				4
29 #define IPV6CALC_PROTO_IPV6				6
30 
31 // define generic feature numbers (max: 24)
32 #define IPV6CALC_DB_FEATURE_NUM_MIN			0
33 #define IPV6CALC_DB_FEATURE_NUM_AS_TO_REGISTRY		0
34 #define IPV6CALC_DB_FEATURE_NUM_CC_TO_REGISTRY		1
35 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_REGISTRY	2
36 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_REGISTRY	3
37 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_AS		4
38 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_AS		5
39 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_CC		6
40 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_CC		7
41 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_COUNTRY		8
42 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_COUNTRY		9
43 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_CITY		10
44 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_CITY		11
45 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_REGION		12
46 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_REGION		13
47 #define IPV6CALC_DB_FEATURE_NUM_IEEE_TO_INFO		14
48 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_INFO		15
49 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_INFO		16
50 #define IPV6CALC_DB_FEATURE_NUM_IPV4_TO_GEONAMEID	17
51 #define IPV6CALC_DB_FEATURE_NUM_IPV6_TO_GEONAMEID	18
52 #define IPV6CALC_DB_FEATURE_NUM_MAX			IPV6CALC_DB_FEATURE_NUM_IPV6_TO_GEONAMEID
53 
54 // define generic features
55 #define IPV6CALC_DB_AS_TO_REGISTRY		(1 << IPV6CALC_DB_FEATURE_NUM_AS_TO_REGISTRY)
56 #define IPV6CALC_DB_CC_TO_REGISTRY		(1 << IPV6CALC_DB_FEATURE_NUM_CC_TO_REGISTRY)
57 #define IPV6CALC_DB_IPV4_TO_REGISTRY		(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_REGISTRY)
58 #define IPV6CALC_DB_IPV6_TO_REGISTRY		(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_REGISTRY)
59 
60 #define IPV6CALC_DB_IPV4_TO_AS			(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_AS)
61 #define IPV6CALC_DB_IPV6_TO_AS			(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_AS)
62 
63 #define IPV6CALC_DB_IPV4_TO_CC			(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_CC)
64 #define IPV6CALC_DB_IPV6_TO_CC			(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_CC)
65 
66 #define IPV6CALC_DB_IPV4_TO_COUNTRY		(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_COUNTRY)
67 #define IPV6CALC_DB_IPV6_TO_COUNTRY		(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_COUNTRY)
68 
69 #define IPV6CALC_DB_IPV4_TO_CITY		(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_CITY)
70 #define IPV6CALC_DB_IPV6_TO_CITY		(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_CITY)
71 
72 #define IPV6CALC_DB_IPV4_TO_REGION		(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_REGION)
73 #define IPV6CALC_DB_IPV6_TO_REGION		(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_REGION)
74 
75 #define IPV6CALC_DB_IEEE_TO_INFO		(1 << IPV6CALC_DB_FEATURE_NUM_IEEE_TO_INFO)
76 
77 #define IPV6CALC_DB_IPV4_TO_INFO		(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_INFO)
78 #define IPV6CALC_DB_IPV6_TO_INFO		(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_INFO)
79 
80 #define IPV6CALC_DB_IPV4_TO_GEONAMEID		(1 << IPV6CALC_DB_FEATURE_NUM_IPV4_TO_GEONAMEID)
81 #define IPV6CALC_DB_IPV6_TO_GEONAMEID		(1 << IPV6CALC_DB_FEATURE_NUM_IPV6_TO_GEONAMEID)
82 
83 // define combination of generic features
84 #define IPV6CALC_DB_IP_TO_AS			(IPV6CALC_DB_IPV4_TO_AS        | IPV6CALC_DB_IPV6_TO_AS       )
85 #define IPV6CALC_DB_IP_TO_COUNTRY		(IPV6CALC_DB_IPV4_TO_COUNTRY   | IPV6CALC_DB_IPV6_TO_COUNTRY  )
86 #define IPV6CALC_DB_IP_TO_CC			(IPV6CALC_DB_IPV4_TO_CC        | IPV6CALC_DB_IPV6_TO_CC       )
87 #define IPV6CALC_DB_IP_TO_CITY			(IPV6CALC_DB_IPV4_TO_CITY      | IPV6CALC_DB_IPV6_TO_CITY     )
88 #define IPV6CALC_DB_IP_TO_REGION		(IPV6CALC_DB_IPV4_TO_REGION    | IPV6CALC_DB_IPV6_TO_REGION   )
89 #define IPV6CALC_DB_IP_TO_GEONAMEID		(IPV6CALC_DB_IPV4_TO_GEONAMEID | IPV6CALC_DB_IPV6_TO_GEONAMEID)
90 
91 // define database specific generic features
92 #define IPV6CALC_DB_GEOIP_IPV4			0x01000000
93 #define IPV6CALC_DB_GEOIP_IPV6			0x02000000
94 #define IPV6CALC_DB_GEOIP			(IPV6CALC_DB_GEOIP_IPV4 | IPV6CALC_DB_GEOIP_IPV6)
95 
96 #define IPV6CALC_DB_IP2LOCATION_IPV4		0x04000000
97 #define IPV6CALC_DB_IP2LOCATION_IPV6		0x08000000
98 
99 #define IPV6CALC_DB_DBIP_IPV4			0x10000000
100 #define IPV6CALC_DB_DBIP_IPV6			0x20000000
101 #define IPV6CALC_DB_DBIP			(IPV6CALC_DB_DBIP_IPV4 | IPV6CALC_DB_DBIP_IPV6)
102 
103 #define IPV6CALC_DB_EXTERNAL_IPV4		0x40000000
104 #define IPV6CALC_DB_EXTERNAL_IPV6		0x80000000
105 
106 
107 static const s_formatoption ipv6calc_db_features[] = {
108 	{ IPV6CALC_DB_GEOIP_IPV4	, "GeoIP"		, "GeoIPv4 database"},
109 	{ IPV6CALC_DB_GEOIP_IPV6	, "GeoIPv6"		, "GeoIPv6 database"},
110 	{ IPV6CALC_DB_IP2LOCATION_IPV4	, "IP2Location"		, "IP2Location IPv4 database"},
111 	{ IPV6CALC_DB_IP2LOCATION_IPV6	, "IP2Location6"	, "IP2Location IPv6 database"},
112 	{ IPV6CALC_DB_DBIP_IPV4		, "DBIPv4"		, "db-ip.com IPv4 database"},
113 	{ IPV6CALC_DB_DBIP_IPV6		, "DBIPv6"		, "db-ip.com IPv6 database"},
114 	{ IPV6CALC_DB_AS_TO_REGISTRY	, "DB_AS_REG"		, "AS-Number to Registry database"},
115 	{ IPV6CALC_DB_IPV4_TO_REGISTRY	, "DB_IPV4_REG"		, "IPv4 to Registry database"},
116 	{ IPV6CALC_DB_IPV6_TO_REGISTRY	, "DB_IPV6_REG"		, "IPv6 to Registry database"},
117 	{ IPV6CALC_DB_IPV4_TO_AS	, "DB_IPV4_AS"		, "IPv4 to AS database" },
118 	{ IPV6CALC_DB_IPV6_TO_AS	, "DB_IPV6_AS"		, "IPv6 to AS database" },
119 	{ IPV6CALC_DB_IPV4_TO_CC	, "DB_IPV4_CC"		, "IPv4 to CountryCode database" },
120 	{ IPV6CALC_DB_IPV6_TO_CC	, "DB_IPV6_CC"		, "IPv6 to CountryCode database" },
121 	{ IPV6CALC_DB_IPV4_TO_COUNTRY	, "DB_IPV4_COUNTRY"	, "IPv4 to Country database" },
122 	{ IPV6CALC_DB_IPV6_TO_COUNTRY	, "DB_IPV6_COUNTRY"	, "IPv6 to Country database" },
123 	{ IPV6CALC_DB_IPV4_TO_CITY	, "DB_IPV4_CITY"	, "IPv4 to City database" },
124 	{ IPV6CALC_DB_IPV6_TO_CITY	, "DB_IPV6_CITY"	, "IPv6 to City database" },
125 	{ IPV6CALC_DB_IPV4_TO_REGION	, "DB_IPV4_REGION"	, "IPv4 to Region database" },
126 	{ IPV6CALC_DB_IPV6_TO_REGION	, "DB_IPV6_REGION"	, "IPv6 to Region database" },
127 	{ IPV6CALC_DB_CC_TO_REGISTRY	, "DB_CC_REG"		, "CountryCode to Registry database" },
128 	{ IPV6CALC_DB_IEEE_TO_INFO	, "DB_IEEE"		, "IEEE/OUI/OUI28/OUI36 Vendor database" },
129 	{ IPV6CALC_DB_IPV4_TO_INFO	, "DB_IPV4_INFO"	, "IPv4 additional information" },
130 	{ IPV6CALC_DB_IPV6_TO_INFO	, "DB_IPV6_INFO"	, "IPv6 additional information" },
131 	{ IPV6CALC_DB_IPV4_TO_GEONAMEID	, "DB_IPV4_GEONAMEID"	, "IPv4 GeonameID" },
132 	{ IPV6CALC_DB_IPV6_TO_GEONAMEID	, "DB_IPV6_GEONAMEID"	, "IPv6 GeonameID" },
133 };
134 
135 // data sources
136 #define IPV6CALC_DB_SOURCE_UNKNOWN		0
137 
138 #define IPV6CALC_DB_SOURCE_MIN			1
139 
140 #define IPV6CALC_DB_SOURCE_GEOIP2		1
141 #define IPV6CALC_DB_SOURCE_IP2LOCATION		2
142 #define IPV6CALC_DB_SOURCE_DBIP2		3
143 #define IPV6CALC_DB_SOURCE_GEOIP		4
144 #define IPV6CALC_DB_SOURCE_DBIP			5
145 #define IPV6CALC_DB_SOURCE_EXTERNAL		6
146 #define IPV6CALC_DB_SOURCE_BUILTIN		7
147 
148 #define IPV6CALC_DB_SOURCE_MAX			7
149 
150 #define IPV6CALC_DB_PRIO_MAX			IPV6CALC_DB_SOURCE_MAX
151 
152 typedef struct {
153 	const unsigned int number;
154 	const char *name;
155 	const char *shortname;
156 } s_data_sources;
157 
158 static const s_data_sources data_sources[] = {
159 	{ IPV6CALC_DB_SOURCE_GEOIP	, "GeoIP"      , "GeoIP"       },
160 	{ IPV6CALC_DB_SOURCE_GEOIP2	, "GeoIP(MaxMindDB)"    , "GeoIP2"      },
161 	{ IPV6CALC_DB_SOURCE_IP2LOCATION, "IP2Location", "IP2Location" },
162 	{ IPV6CALC_DB_SOURCE_DBIP	, "db-ip.com"  , "DBIP"        },
163 	{ IPV6CALC_DB_SOURCE_DBIP2	, "db-ip.com(MaxMindDB)", "DBIP2"       },
164 	{ IPV6CALC_DB_SOURCE_EXTERNAL	, "External"   , "External"    },
165 	{ IPV6CALC_DB_SOURCE_BUILTIN	, "BuiltIn"    , "BuiltIn"     },
166 };
167 
168 // database names and descriptions
169 typedef struct {
170 	const unsigned int number;
171 	const char        *filename;
172 	const char        *description;
173 	const uint32_t     features;
174 } db_file_desc;
175 
176 typedef struct {
177 	const unsigned int number;
178 	const char        *filename;
179 	const char        *description;
180 	const uint32_t     features;
181 	const uint32_t     internal;
182 } db_file_desc2;
183 
184 
185 // abstract structure for geolocation information
186 // string limits taken from from https://db-ip.com/db/
187 // and IP2Location
188 #define IPV6CALC_DB_SIZE_COUNTRY_CODE	2+1
189 #define IPV6CALC_DB_SIZE_COUNTRY_LONG	80+1
190 #define IPV6CALC_DB_SIZE_CONTINENT_CODE	2+1
191 #define IPV6CALC_DB_SIZE_CONTINENT_LONG	80+1
192 #define IPV6CALC_DB_SIZE_STATEPROV	80+1
193 #define IPV6CALC_DB_SIZE_DISTRICT	80+1
194 #define IPV6CALC_DB_SIZE_CITY		80+1
195 #define IPV6CALC_DB_SIZE_ZIPCODE	20+1
196 #define IPV6CALC_DB_SIZE_WEATHERSTATIONCODE	20+1
197 #define IPV6CALC_DB_SIZE_WEATHERSTATIONNAME	80+1
198 #define IPV6CALC_DB_SIZE_TIMEZONE_NAME	64+1
199 #define IPV6CALC_DB_SIZE_ISP_NAME	128+1
200 #define IPV6CALC_DB_SIZE_CONN_TYPE	20+1
201 #define IPV6CALC_DB_SIZE_ORG_NAME	128+1
202 #define IPV6CALC_DB_SIZE_DOMAIN		20+1
203 #define IPV6CALC_DB_SIZE_DMA_CODE	8+1
204 #define IPV6CALC_DB_SIZE_IDD_CODE	8+1
205 #define IPV6CALC_DB_SIZE_AREA_CODE	8+1
206 #define IPV6CALC_DB_SIZE_MOBILENETWORKCODE	80+1
207 #define IPV6CALC_DB_SIZE_MOBILECOUNTRYCODE	8+1
208 #define IPV6CALC_DB_SIZE_MOBILE_BRAND	80+1
209 #define IPV6CALC_DB_SIZE_USAGE_TYPE	80+1
210 
211 #define IPV6CALC_DB_GEO_ELEVATION_UNKNOWN -20000
212 #define IPV6CALC_DB_GEO_TIMEZONE_UNKNOWN  99
213 #define IPV6CALC_DB_GEO_GEONAMEID_UNKNOWN  0
214 
215 // range: 0..7 (for anonymization)
216 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_UNKNOWN    0
217 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_CONTINENT  1
218 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_COUNTRY    2
219 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_STATEPROV  3
220 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_DISTRICT   4
221 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_CITY       5
222 
223 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_FLAG_24BIT	0x10000
224 #define IPV6CALC_DB_GEO_GEONAMEID_TYPE_FLAG_MASK	0xf0000
225 
226 typedef struct
227 {
228 	char     country_code[IPV6CALC_DB_SIZE_COUNTRY_CODE];
229 	char     country_long[IPV6CALC_DB_SIZE_COUNTRY_LONG];
230 	char     continent_code[IPV6CALC_DB_SIZE_CONTINENT_CODE];
231 	char     continent_long[IPV6CALC_DB_SIZE_CONTINENT_LONG];
232 	char     stateprov[IPV6CALC_DB_SIZE_STATEPROV];
233 	char     district[IPV6CALC_DB_SIZE_CITY];
234 	char     city[IPV6CALC_DB_SIZE_CITY];
235 	char     zipcode[IPV6CALC_DB_SIZE_ZIPCODE];
236 	char     weatherstationcode[IPV6CALC_DB_SIZE_WEATHERSTATIONCODE];
237 	char     weatherstationname[IPV6CALC_DB_SIZE_WEATHERSTATIONNAME];
238 	char     dma_code[IPV6CALC_DB_SIZE_DMA_CODE];
239 	char     idd_code[IPV6CALC_DB_SIZE_IDD_CODE];
240 	char     area_code[IPV6CALC_DB_SIZE_AREA_CODE];
241 	double   latitude;
242 	double   longitude;
243 	float    elevation;
244 	uint16_t accuracy_radius;
245 	uint32_t geoname_id;
246 	uint32_t continent_geoname_id;
247 	uint32_t country_geoname_id;
248 	uint32_t stateprov_geoname_id;
249 	uint32_t district_geoname_id;
250 	uint32_t asn;
251 	float    timezone_offset;
252 	char     timezone_name[IPV6CALC_DB_SIZE_TIMEZONE_NAME];
253 	char     isp_name[IPV6CALC_DB_SIZE_ISP_NAME];
254 	char     connection_type[IPV6CALC_DB_SIZE_CONN_TYPE];
255 	char     organization_name[IPV6CALC_DB_SIZE_ORG_NAME];
256 	char     domain[IPV6CALC_DB_SIZE_DOMAIN];
257 	char     mobile_network_code[IPV6CALC_DB_SIZE_MOBILENETWORKCODE];
258 	char     mobile_country_code[IPV6CALC_DB_SIZE_MOBILECOUNTRYCODE];
259 	char     mobile_brand[IPV6CALC_DB_SIZE_MOBILE_BRAND];
260 	char     usage_type[IPV6CALC_DB_SIZE_USAGE_TYPE];
261 } libipv6calc_db_wrapper_geolocation_record;
262 
263 static const s_data_sources geonameid_types[] = {
264 	{ IPV6CALC_DB_GEO_GEONAMEID_TYPE_CONTINENT	, "Continent" , "Continent"  },
265 	{ IPV6CALC_DB_GEO_GEONAMEID_TYPE_COUNTRY	, "Country"   , "Country"    },
266 	{ IPV6CALC_DB_GEO_GEONAMEID_TYPE_STATEPROV	, "Region"    , "Region"     },
267 	{ IPV6CALC_DB_GEO_GEONAMEID_TYPE_DISTRICT	, "District"  , "District"   },
268 	{ IPV6CALC_DB_GEO_GEONAMEID_TYPE_CITY		, "City"      , "City"       },
269 };
270 
271 // define internal API versions
272 #define IPV6CALC_DB_API_GEOIP		1
273 #define IPV6CALC_DB_API_IP2LOCATION	1
274 #define IPV6CALC_DB_API_DBIP		1
275 #define IPV6CALC_DB_API_IEEE		1
276 #define IPV6CALC_DB_API_REGISTRIES	1
277 
278 #define IPV6CALC_DL_STATUS_OK		1
279 #define IPV6CALC_DL_STATUS_UNKNOWN	0
280 #define IPV6CALC_DL_STATUS_ERROR	-1
281 
282 // db-info macro
283 #define IPV6CALC_DB_FEATURE_INFO(prefix, data_source) \
284         fprintf(stderr, "%s%s: features available/implemented: 0x%08x/0x%08x", \
285 		prefix, \
286 		libipv6calc_db_wrapper_get_data_source_name_by_number(data_source), \
287 		wrapper_features_by_source[data_source], \
288 		wrapper_features_by_source_implemented[data_source]); \
289 	if (strlen(prefix) == 0) { \
290 		int wrapper_features_by_source_bitcount = libipv6calc_bitcount_uint32_t(wrapper_features_by_source[data_source]); \
291 		int wrapper_features_by_source_implemented_bitcount = libipv6calc_bitcount_uint32_t(wrapper_features_by_source_implemented[data_source]); \
292 		if (wrapper_features_by_source_implemented_bitcount == 0) { \
293 			fprintf(stderr, " (NONE)"); \
294 		} else { \
295 			fprintf(stderr, " (%d%%)", (wrapper_features_by_source_bitcount * 100) / wrapper_features_by_source_implemented_bitcount); \
296 		}; \
297 	}; \
298 	fprintf(stderr, "\n");
299 
300 // AS Number handling
301 #define ASNUM_AS_UNKNOWN 0
302 #define ASNUM_AS_TRANS   23456  // special 16-bit AS number for compatibility
303 
304 // CountryCode handling
305 #define COUNTRYCODE_LETTER1_MAX          26     // A-Z
306 #define COUNTRYCODE_LETTER2_MAX          36     // 0-9A-Z
307 #define COUNTRYCODE_INDEX_LETTER_MAX     (COUNTRYCODE_LETTER1_MAX * COUNTRYCODE_LETTER2_MAX - 1)
308 #define COUNTRYCODE_INDEX_MAX            1023	// 0x3ff
309 #define COUNTRYCODE_INDEX_UNKNOWN        1022	// 0x3fe
310 #define COUNTRYCODE_INDEX_LISP		 1021	// 0x3fd
311 
312 #define COUNTRYCODE_INDEX_UNKNOWN_REGISTRY_MAP_MAX   (COUNTRYCODE_INDEX_UNKNOWN - 1)
313 #define COUNTRYCODE_INDEX_UNKNOWN_REGISTRY_MAP_MIN   (COUNTRYCODE_INDEX_UNKNOWN - 16)
314 
315 // macros for mapping index to chars
316 #define COUNTRYCODE_INDEX_TO_CHAR1(index)  ((index % COUNTRYCODE_LETTER1_MAX) + 'A')
317 #define COUNTRYCODE_INDEX_TO_CHAR2(index)  ((index / COUNTRYCODE_LETTER1_MAX) > 9) ? ((index / COUNTRYCODE_LETTER1_MAX) - 10 + 'A') : ((index / COUNTRYCODE_LETTER1_MAX) + '0')
318 
319 
320 // generic database lookup function
321 #define IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY		1	 // array
322 
323 #ifdef HAVE_BERKELEY_DB_SUPPORT
324 #define IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_BDB		2	 // Berkeley DB
325 #endif // HAVE_BERKELEY_DB_SUPPORT
326 
327 // data storage type
328 #define IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_FIRST_LAST	1	 // key is first-last
329 #define IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_BASE_MASK	2	 // key is base/mask
330 
331 // data search type
332 #define IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_BINARY	1	 // binary search
333 #define IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_SEQLONGEST	2	 // sequential longest match
334 
335 // Berkeley DB  lookup function
336 #ifdef HAVE_BERKELEY_DB_SUPPORT
337 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_DEC_32x2		0
338 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_DEC_32x4		1
339 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_HEX_32x2		2
340 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_HEX_32x4		3
341 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_HEX_WITH_VALUE_32x2	4
342 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_HEX_WITH_VALUE_32x4	5
343 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_HEX_WITH_PREFIX_32x2	6
344 #define IPV6CALC_DB_LOOKUP_DATA_DBD_FORMAT_SEMICOLON_SEP_HEX_WITH_PREFIX_32x4	7
345 
346 // database info/data
347 typedef struct {
348 	DB *db_info_ptr;
349 	DB *db_data_ptr;
350 	long int db_data_max;
351 } s_db_info_data;
352 
353 #endif // HAVE_BERKELEY_DB_SUPPORT
354 
355 #define IPV6CALC_DB_LIB_VERSION_CHECK_EXIT(version_numeric, version_string) \
356 	if (version_numeric != libipv6calc_db_lib_version_numeric()) { \
357 		ERRORPRINT_WA("Database library version is not matching: has:%s required:%s", libipv6calc_db_lib_version_string(), version_string); \
358 		exit(1); \
359 	};
360 
361 #endif // _libipv6calc_db_wrapper_h
362 
363 
364 extern int  libipv6calc_db_wrapper_init(const char *prefix_string);
365 extern int  libipv6calc_db_wrapper_cleanup(void);
366 extern void libipv6calc_db_wrapper_info(char *string, const size_t size);
367 extern void libipv6calc_db_wrapper_features(char *string, const size_t size);
368 extern void libipv6calc_db_wrapper_capabilities(char *string, const size_t size);
369 extern void libipv6calc_db_wrapper_features_help(void);
370 extern void libipv6calc_db_wrapper_print_db_info(const int level_verbose, const char *prefix_string);
371 extern void libipv6calc_db_wrapper_print_features_verbose(const int level_verbose);
372 extern int  libipv6calc_db_wrapper_has_features(uint32_t features);
373 extern int  libipv6calc_db_wrapper_options(const int opt, const char *optarg, const struct option longopts[]);
374 extern const char *libipv6calc_db_wrapper_get_data_source_name_by_number(const unsigned int number);
375 
376 
377 /* functional wrappers */
378 
379 // CountryCode Text/Number
380 extern int         libipv6calc_db_wrapper_country_code_by_addr(char *string, const int length, const ipv6calc_ipaddr *ipaddrp, unsigned int *data_source_ptr);
381 extern int         libipv6calc_db_wrapper_country_code_by_cc_index(char *string, const int length, const uint16_t cc_index);
382 extern uint16_t    libipv6calc_db_wrapper_cc_index_by_addr(const ipv6calc_ipaddr *ipaddrp, unsigned int *data_source_ptr);
383 
384 // Autonomous System Text/Number
385 extern uint32_t    libipv6calc_db_wrapper_as_num32_by_addr(const ipv6calc_ipaddr *ipaddrp, unsigned int *data_source_ptr);
386 
387 extern uint32_t    libipv6calc_db_wrapper_as_num32_comp17(const uint32_t as_num32);
388 extern uint32_t    libipv6calc_db_wrapper_as_num32_decomp17(const uint32_t as_num32_comp17);
389 
390 // GeonameID
391 extern uint32_t    libipv6calc_db_wrapper_GeonameID_by_addr(const ipv6calc_ipaddr *ipaddrp, unsigned int *data_source_ptr, unsigned int *GeonameID_type_ptr);
392 
393 // Registries
394 extern int         libipv6calc_db_wrapper_registry_num_by_as_num32(const uint32_t as_num32);
395 extern int         libipv6calc_db_wrapper_registry_num_by_cc_index(const uint16_t cc_index);
396 extern int         libipv6calc_db_wrapper_registry_num_by_ipaddr(const ipv6calc_ipaddr *ipaddrp);
397 extern int         libipv6calc_db_wrapper_registry_string_by_ipaddr(const ipv6calc_ipaddr *ipaddrp, char *resultstring, const size_t resultstring_length);
398 
399 // IEEE
400 extern int libipv6calc_db_wrapper_ieee_vendor_string_by_macaddr(char *resultstring, const size_t resultstring_length, const ipv6calc_macaddr *macaddrp);
401 extern int libipv6calc_db_wrapper_ieee_vendor_string_short_by_macaddr(char *resultstring, const size_t resultstring_length, const ipv6calc_macaddr *macaddrp);
402 
403 // IPv4 Registry
404 extern int libipv6calc_db_wrapper_registry_string_by_ipv4addr(const ipv6calc_ipv4addr *ipv4addrp, char *resultstring, const size_t resultstring_length);
405 extern int libipv6calc_db_wrapper_registry_num_by_ipv4addr(const ipv6calc_ipv4addr *ipv4addrp);
406 extern int libipv6calc_db_wrapper_info_by_ipv4addr(const ipv6calc_ipv4addr *ipv4addrp, char *string, const size_t string_len);
407 
408 // IPv6 Registry
409 extern int libipv6calc_db_wrapper_registry_string_by_ipv6addr(const ipv6calc_ipv6addr *ipv6addrp, char *resultstring, const size_t resultstring_length);
410 extern int libipv6calc_db_wrapper_registry_num_by_ipv6addr(const ipv6calc_ipv6addr *ipv6addrp);
411 extern int libipv6calc_db_wrapper_info_by_ipv6addr(const ipv6calc_ipv6addr *ipv6addrp, char *string, const size_t string_len);
412 
413 // geolocation record
414 extern void libipv6calc_db_wrapper_geolocation_record_clear(libipv6calc_db_wrapper_geolocation_record *recordp);
415 
416 #ifdef HAVE_BERKELEY_DB_SUPPORT
417 extern int libipv6calc_db_wrapper_bdb_get_data_by_key(DB *dbp, char *token, char *value, const size_t value_size);
418 #endif // HAVE_BERKELEY_DB_SUPPORT
419 
420 // generic DB lookup
421 extern long int libipv6calc_db_wrapper_get_entry_generic(
422 	void 		*db_ptr,		// pointer to database in case of IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_BDB, otherwise NULL
423 	const uint8_t	data_ptr_type,		// type of data_ptr
424 	const uint8_t	data_key_type,		// key type
425 	const uint8_t   data_key_format,        // key format
426 	const uint8_t	data_key_length,	// key length
427 	const uint8_t	data_search_type,	// search type
428 	const uint32_t	data_num_rows,		// number of rows
429 	const uint32_t	lookup_key_00_31,	// lookup key MSB
430 	const uint32_t	lookup_key_32_63,	// lookup key LSB
431 	void            *data_ptr,		// pointer to DB data in case of IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_BDB, otherwise NULL
432 	int  (*get_array_row)()			// function to get array row
433 	);
434 
435 /* filter powered by database */
436 extern int libipv6calc_db_cc_filter_parse(s_ipv6calc_filter_db_cc *filter, const char *token, const int negate_flag);
437 extern int libipv6calc_db_cc_filter_check(const s_ipv6calc_filter_db_cc *filter, const int proto);
438 extern int libipv6calc_db_cc_filter(const uint16_t cc_index, const s_ipv6calc_filter_db_cc *filter);
439 
440 extern int libipv6calc_db_asn_filter_parse(s_ipv6calc_filter_db_asn *filter, const char *token, const int negate_flag);
441 extern int libipv6calc_db_asn_filter_check(const s_ipv6calc_filter_db_asn *filter, const int proto);
442 extern int libipv6calc_db_asn_filter(const uint32_t asn, const s_ipv6calc_filter_db_asn *filter);
443 
444 extern int libipv6calc_db_registry_filter_parse(s_ipv6calc_filter_db_registry *filter, const char *token, const int negate_flag);
445 extern int libipv6calc_db_registry_filter_check(const s_ipv6calc_filter_db_registry *filter, const int proto);
446 extern int libipv6calc_db_registry_filter(const uint32_t registry, const s_ipv6calc_filter_db_registry *filter);
447 
448 extern       uint32_t libipv6calc_db_lib_version_numeric(void);
449 extern const char    *libipv6calc_db_lib_version_string(void);
450 extern       uint32_t libipv6calc_db_api_version_numeric(void);
451 extern const char    *libipv6calc_db_api_version_string(void);
452