1 /*
2  * Project    : ipv6calc
3  * File       : databases/lib/libipv6calc_db_wrapper_BuiltIn.c
4  * Version    : $Id: a7452238d6b5eae4bf8743dc977c14e574f159f6 $
5  * Copyright  : 2013-2021 by Peter Bieringer <pb (at) bieringer.de>
6  *
7  * Information:
8  *  ipv6calc BuiltIn database wrapper
9  *    - decoupling databases from main binary
10  */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <dlfcn.h>
15 #include <string.h>
16 #include <time.h>
17 
18 #include "config.h"
19 
20 #include "libipv6calcdebug.h"
21 
22 #include "libipv6calc_db_wrapper.h"
23 
24 #include "libipv6calc_db_wrapper_BuiltIn.h"
25 
26 #include "libieee.h"
27 
28 #ifdef SUPPORT_BUILTIN
29 static int builtin_asn        = 0;
30 static int builtin_cc_reg     = 0;
31 static int builtin_ipv4       = 0;
32 static int builtin_ipv6       = 0;
33 static int builtin_ieee       = 0;
34 
35 // load all built-in databases
36 #include "../as-assignment/dbasn_assignment.h"
37 #include "../cc-assignment/db_cc_reg_assignment.h"
38 
39 #ifdef SUPPORT_DB_IPV4_REG
40 #include "../ipv4-assignment/dbipv4addr_assignment.h"
41 #endif
42 
43 #ifdef SUPPORT_DB_IPV6_REG
44 #include "../ipv6-assignment/dbipv6addr_assignment.h"
45 #endif
46 
47 #ifdef SUPPORT_DB_IEEE
48 #include "../ieee-iab/dbieee_iab.h"
49 #include "../ieee-oui/dbieee_oui.h"
50 #include "../ieee-oui28/dbieee_oui28.h"
51 #include "../ieee-oui36/dbieee_oui36.h"
52 #endif
53 
54 #endif
55 
56 /* database usage map */
57 #define BUILTIN_DB_MAX_BLOCKS_32	2	// 0-63
58 static uint32_t builtin_db_usage_map[BUILTIN_DB_MAX_BLOCKS_32];
59 
60 #define BUILTIN_DB_USAGE_MAP_TAG(db)	if (db < (32 * BUILTIN_DB_MAX_BLOCKS_32)) { \
61 							DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Tag usage for db: %d", db); \
62 							builtin_db_usage_map[db / 32] |= 1 << (db % 32); \
63 						} else { \
64 							fprintf(stderr, "FIXME: unsupported db value (exceed limit): %d (%d)\n", db, 32 * BUILTIN_DB_MAX_BLOCKS_32 - 1); \
65 							exit(1); \
66 						};
67 
68 char builtin_db_usage_string[IPV6CALC_STRING_MAX] = "";
69 
70 
71 /*
72  * function initialise the BuiltIn wrapper
73  *
74  * in : (nothing)
75  * out: 0=ok, 1=error
76  */
libipv6calc_db_wrapper_BuiltIn_wrapper_init(void)77 int libipv6calc_db_wrapper_BuiltIn_wrapper_init(void) {
78 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called");
79 
80 	// add features to implemented
81 	wrapper_features_by_source_implemented[IPV6CALC_DB_SOURCE_BUILTIN] |= IPV6CALC_DB_AS_TO_REGISTRY | IPV6CALC_DB_CC_TO_REGISTRY | IPV6CALC_DB_IPV4_TO_REGISTRY | IPV6CALC_DB_IPV6_TO_REGISTRY | IPV6CALC_DB_IEEE_TO_INFO | IPV6CALC_DB_IPV4_TO_INFO | IPV6CALC_DB_IPV6_TO_INFO;
82 
83 #ifdef SUPPORT_BUILTIN
84 #ifdef SUPPORT_DB_AS_REG
85 	wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] |= IPV6CALC_DB_AS_TO_REGISTRY;
86 	builtin_asn        = 1;
87 #endif
88 
89 #ifdef SUPPORT_DB_CC_REG
90 	wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] |= IPV6CALC_DB_CC_TO_REGISTRY;
91 	builtin_cc_reg     = 1;
92 #endif
93 
94 #ifdef SUPPORT_DB_IPV4_REG
95 	wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] |= IPV6CALC_DB_IPV4_TO_REGISTRY | IPV6CALC_DB_IPV4_TO_INFO;
96 	builtin_ipv4       = 1;
97 #endif
98 
99 #ifdef SUPPORT_DB_IPV6_REG
100 	wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] |= IPV6CALC_DB_IPV6_TO_REGISTRY | IPV6CALC_DB_IPV6_TO_INFO;
101 	builtin_ipv6       = 1;
102 #endif
103 
104 #ifdef SUPPORT_DB_IEEE
105 	wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] |= IPV6CALC_DB_IEEE_TO_INFO;
106 	builtin_ieee       = 1;
107 #endif
108 
109 	wrapper_features |= wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN];
110 
111 #endif
112 
113 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished");
114 	return 0;
115 };
116 
117 
118 /*
119  * function cleanup the BuiltIn wrapper
120  *
121  * in : (nothing)
122  * out: 0=ok, 1=error
123  */
libipv6calc_db_wrapper_BuiltIn_wrapper_cleanup(void)124 int libipv6calc_db_wrapper_BuiltIn_wrapper_cleanup(void) {
125 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called");
126 
127 	// currently nothing to do
128 
129 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished");
130 	return 0;
131 };
132 
133 
134 /*
135  * function info of BuiltIn wrapper
136  *
137  * in : ptr and size of string to be filled
138  * out: modified string;
139  */
libipv6calc_db_wrapper_BuiltIn_wrapper_info(char * string,const size_t size)140 void libipv6calc_db_wrapper_BuiltIn_wrapper_info(char* string, const size_t size) {
141 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called");
142 
143 #ifdef SUPPORT_BUILTIN
144 	snprintf(string, size, "BuiltIn databases available: ASN_REG=%d IPV4_REG=%d IPV6_REG=%d IEEE=%d CC_REG=%d", builtin_asn, builtin_ipv4, builtin_ipv6, builtin_ieee, builtin_cc_reg);
145 #else
146 	snprintf(string, size, "No BuiltIn databases support compiled-in");
147 #endif
148 
149 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished");
150 	return;
151 };
152 
153 
154 /*
155  * function print database info of BuiltIn wrapper
156  *
157  * in : (void)
158  * out: (void)
159  */
libipv6calc_db_wrapper_BuiltIn_wrapper_print_db_info(const int level_verbose,const char * prefix_string)160 void libipv6calc_db_wrapper_BuiltIn_wrapper_print_db_info(const int level_verbose, const char *prefix_string) {
161 	const char *prefix = "\0";
162 
163 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called with verbose: %d", level_verbose);
164 
165 	if (prefix_string != NULL) {
166 		prefix = prefix_string;
167 	};
168 
169 	IPV6CALC_DB_FEATURE_INFO(prefix, IPV6CALC_DB_SOURCE_BUILTIN)
170 
171 #ifdef SUPPORT_BUILTIN
172 #if defined SUPPORT_DB_IPV4_REG || defined SUPPORT_DB_IPV6_REG
173 	char tempstring[IPV6CALC_STRING_MAX];
174 #endif
175 
176 	fprintf(stderr, "%sBuiltIn: info of available databases\n", prefix);
177 
178 #ifdef SUPPORT_DB_AS_REG
179 	if (wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] & IPV6CALC_DB_AS_TO_REGISTRY) {
180 		fprintf(stderr, "%sBuiltIn: %-5s: %s\n", prefix, "ASN", dbasn_registry_status);
181 	};
182 #endif
183 
184 #ifdef SUPPORT_DB_CC_REG
185 	if (wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] & IPV6CALC_DB_CC_TO_REGISTRY) {
186 		fprintf(stderr, "%sBuiltIn: %-5s: %s\n", prefix, "CC", db_cc_registry_status);
187 	};
188 #endif
189 
190 #ifdef SUPPORT_DB_IPV4_REG
191 	if (wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] & IPV6CALC_DB_IPV4_TO_REGISTRY) {
192 		strftime(tempstring, sizeof(tempstring), "%Y%m%d-%H%M%S UTC", gmtime(&dbipv4addr_registry_unixtime));
193 		fprintf(stderr, "%sBuiltIn: %-5s: %s (created: %s)\n", prefix, "IPv4", dbipv4addr_registry_status, tempstring);
194 	};
195 #endif
196 
197 #ifdef SUPPORT_DB_IPV6_REG
198 	if (wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] & IPV6CALC_DB_IPV6_TO_REGISTRY) {
199 		strftime(tempstring, sizeof(tempstring), "%Y%m%d-%H%M%S UTC", gmtime(&dbipv6addr_registry_unixtime));
200 		fprintf(stderr, "%sBuiltIn: %-5s: %s (created: %s)\n", prefix, "IPv6", dbipv6addr_registry_status, tempstring);
201 	};
202 #endif
203 
204 #ifdef SUPPORT_DB_IEEE
205 	if (wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] & IPV6CALC_DB_IEEE_TO_INFO) {
206 		fprintf(stderr, "%sBuiltIn: %-5s: %s %s %s %s\n", prefix, "IEEE", libieee_iab_status, libieee_oui_status, libieee_oui28_status, libieee_oui36_status);
207 	};
208 #endif
209 
210 #else
211 	fprintf(stderr, "%sNo BuiltIn support compiled-in\n", prefix);
212 #endif
213 
214 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished");
215 	return;
216 };
217 
218 
219 /*
220  * wrapper: string regarding used database infos
221  */
libipv6calc_db_wrapper_BuiltIn_wrapper_db_info_used(void)222 char *libipv6calc_db_wrapper_BuiltIn_wrapper_db_info_used(void) {
223 	int type, i;
224 	char tempstring[IPV6CALC_STRING_MAX];
225 #if defined SUPPORT_DB_IPV4_REG || defined SUPPORT_DB_IPV6_REG || defined SUPPORT_DB_IEEE || defined SUPPORT_DB_AS_REG || defined SUPPORT_DB_CC_REG
226 	char tempstring2[IPV6CALC_STRING_MAX];
227 #endif
228 	char *info;
229 
230 	DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called");
231 
232 	for (i = 0; i < BUILTIN_DB_MAX_BLOCKS_32; i++) {
233 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "builtin_db_usage_map[%d]=%08x", i, (unsigned int) builtin_db_usage_map[i]);
234 	};
235 
236 	for (type = 0; type < 32 * BUILTIN_DB_MAX_BLOCKS_32; type++) {
237 		if ((builtin_db_usage_map[type / 32] & (1 << (type % 32))) != 0) {
238 			DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "DB type used: %d", type);
239 
240 			info = NULL;
241 
242 			switch(type) {
243 #ifdef SUPPORT_DB_IPV4_REG
244 			    case BUILTIN_DB_IPV4_REGISTRY:
245 				snprintf(tempstring2, sizeof(tempstring2), "IPv4-REG:%s", dbipv4addr_registry_status);
246 				info = tempstring2;
247 				break;
248 #endif
249 #ifdef SUPPORT_DB_IPV6_REG
250 			    case BUILTIN_DB_IPV6_REGISTRY:
251 				snprintf(tempstring2, sizeof(tempstring2), "IPv6-REG:%s", dbipv6addr_registry_status);
252 				info = tempstring2;
253 				break;
254 #endif
255 #ifdef SUPPORT_DB_IEEE
256 			    case BUILTIN_DB_IAB:
257 				snprintf(tempstring2, sizeof(tempstring2), "IEEE:%s", libieee_iab_status);
258 				info = tempstring2;
259 				break;
260 			    case BUILTIN_DB_OUI:
261 				snprintf(tempstring2, sizeof(tempstring2), "IEEE:%s", libieee_oui_status);
262 				info = tempstring2;
263 				break;
264 			    case BUILTIN_DB_OUI28:
265 				snprintf(tempstring2, sizeof(tempstring2), "IEEE:%s", libieee_oui28_status);
266 				info = tempstring2;
267 				break;
268 			    case BUILTIN_DB_OUI36:
269 				snprintf(tempstring2, sizeof(tempstring2), "IEEE:%s", libieee_oui36_status);
270 				info = tempstring2;
271 				break;
272 #endif
273 #ifdef SUPPORT_DB_AS_REG
274 			    case BUILTIN_DB_AS_REG:
275 				snprintf(tempstring2, sizeof(tempstring2), "AS-REG:%s", dbasn_registry_status);
276 				info = tempstring2;
277 				break;
278 #endif
279 #ifdef SUPPORT_DB_CC_REG
280 			    case BUILTIN_DB_CC_REG:
281 				snprintf(tempstring2, sizeof(tempstring2), "CC-REG:%s", db_cc_registry_status);
282 				info = tempstring2;
283 				break;
284 #endif
285 			};
286 
287 			if (info == NULL) { continue; }; // NULL pointer returned
288 
289 			if (strlen(info) == 0) { continue; }; // empty string returned
290 
291 			DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "type=%d info=%s", type, info);
292 
293 			if (strlen(builtin_db_usage_string) > 0) {
294 				if (strstr(builtin_db_usage_string, info) != NULL) {
295 					DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "type=%d info=%s (skip, already displayed)", type, info);
296 					continue;
297 				}; // string already included
298 
299 				snprintf(tempstring, sizeof(tempstring), "%s / %s", builtin_db_usage_string, info);
300 			} else {
301 				snprintf(tempstring, sizeof(tempstring), "%s", info);
302 			};
303 
304 			snprintf(builtin_db_usage_string, sizeof(builtin_db_usage_string), "%s", tempstring);
305 			DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_External, "type=%d builtin_db_usage_string=%s", type, builtin_db_usage_string);
306 		};
307 	};
308 
309 	return(builtin_db_usage_string);
310 };
311 
312 
313 /*********************************************
314  * Abstract functions
315  * *******************************************/
316 
317 /* query for available features
318  * ret=-1: unknown
319  * 0 : not matching
320  * 1 : ok
321  */
libipv6calc_db_wrapper_BuiltIn_has_features(uint32_t features)322 int libipv6calc_db_wrapper_BuiltIn_has_features(uint32_t features) {
323 	int result = -1;
324 
325 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called with feature value to test: 0x%08x", features);
326 
327 	if ((wrapper_features_by_source[IPV6CALC_DB_SOURCE_BUILTIN] & features) == features) {
328 		result = 1;
329 	} else {
330 		result = 0;
331 	};
332 
333 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Return with result: %d", result);
334 	return(result);
335 };
336 
337 
338 /* query db_unixtime by feature
339  * ret=-1: unknown
340  * 0 : not matching
341  * 1 : ok
342  */
libipv6calc_db_wrapper_BuiltIn_db_unixtime_by_feature(uint32_t feature)343 time_t libipv6calc_db_wrapper_BuiltIn_db_unixtime_by_feature(uint32_t feature) {
344 	time_t result = 0;
345 
346 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called with feature value to get db_unixtime: 0x%08x", feature);
347 
348 	if ((IPV6CALC_DB_IPV4_TO_REGISTRY & feature) == feature) {
349 #ifdef SUPPORT_DB_IPV4_REG
350 		result = dbipv4addr_registry_unixtime;
351 #endif
352 	} else if ((IPV6CALC_DB_IPV6_TO_REGISTRY & feature) == feature) {
353 #ifdef SUPPORT_DB_IPV6_REG
354 		result = dbipv6addr_registry_unixtime;
355 #endif
356 	};
357 
358 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Return for feature=0x%08x db_unixtime=%ld", feature, (long int) result);
359 	return(result);
360 };
361 
362 
363 #ifdef SUPPORT_BUILTIN
364 
365 /*******************************
366  * Wrapper functions for BuiltIn
367  *******************************/
368 
369 // get registry number by AS number
libipv6calc_db_wrapper_BuiltIn_registry_num_by_as_num32(const uint32_t as_num32)370 int libipv6calc_db_wrapper_BuiltIn_registry_num_by_as_num32(const uint32_t as_num32) {
371 	int result = REGISTRY_UNKNOWN;
372 
373 	int max = MAXENTRIES_ARRAY(dbasn_assignment);
374 
375 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called with as_num32=%d max=%d", as_num32, max);
376 
377 #ifdef SUPPORT_DB_AS_REG
378 	// binary search
379 	int i, r = -1;
380 	int i_min = 0;
381 	int i_max = max;
382 	int i_old = -1;
383 
384 	i = max / 2;
385 	while (i_old != i) {
386 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Search for as_num32=%d max=%d i=%d start=%d stop=%d", as_num32, max, i, dbasn_assignment[i].asn_start, dbasn_assignment[i].asn_stop);
387 
388 		if (as_num32 < dbasn_assignment[i].asn_start) {
389 			// to high in array, jump down
390 			i_max = i;
391 		} else if (as_num32 > dbasn_assignment[i].asn_stop) {
392 			// to low in array, jump up
393 			i_min = i;
394 		} else {
395 			// hit
396 			r = i;
397 			break;
398 		};
399 
400 		i_old = i;
401 		i = (i_max - i_min) / 2 + i_min;
402 	};
403 
404 	if (r != -1) {
405 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished with success result: %d", dbasn_assignment[r].registry);
406 
407 		result = dbasn_assignment[r].registry;
408 		BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_AS_REG);
409 	} else {
410 		DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished without success");
411 
412 	};
413 #endif
414 	return(result);
415 };
416 
417 
418 // get registry number by CC index
libipv6calc_db_wrapper_BuiltIn_registry_num_by_cc_index(const uint16_t cc_index)419 int libipv6calc_db_wrapper_BuiltIn_registry_num_by_cc_index(const uint16_t cc_index) {
420 	int result = REGISTRY_UNKNOWN;
421 
422 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called with cc_index=%d", cc_index);
423 
424 	if (cc_index > COUNTRYCODE_INDEX_MAX) {
425 		goto END_libipv6calc_db_wrapper;
426 	} else if (cc_index > MAXENTRIES_ARRAY(cc_index_reg_assignment)) {
427 		goto END_libipv6calc_db_wrapper;
428 	} else if (cc_index == COUNTRYCODE_INDEX_UNKNOWN) {
429 		result = REGISTRY_IANA;
430 		goto END_libipv6calc_db_wrapper;
431 	} else if ((cc_index >= COUNTRYCODE_INDEX_UNKNOWN_REGISTRY_MAP_MIN) && (cc_index <= COUNTRYCODE_INDEX_UNKNOWN_REGISTRY_MAP_MAX)) {
432 		result = cc_index - COUNTRYCODE_INDEX_UNKNOWN_REGISTRY_MAP_MIN;
433 		goto END_libipv6calc_db_wrapper;
434 	};
435 
436 #ifdef SUPPORT_DB_CC_REG
437 	result = cc_index_reg_assignment[cc_index].registry;
438 	BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_CC_REG);
439 #endif
440 
441 END_libipv6calc_db_wrapper:
442 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Return registry=%s (%d) (cc_index=%d)", libipv6calc_registry_string_by_num(result), result, cc_index);
443 
444 	return(result);
445 };
446 
447 
448 /*
449  * Get IEEE vendor string
450  * in:  macaddrp
451  * mod: resultstring
452  * out: 0=found, 1=not found
453  */
libipv6calc_db_wrapper_BuiltIn_ieee_vendor_string_by_macaddr(char * resultstring,const size_t resultstring_length,const ipv6calc_macaddr * macaddrp)454 int libipv6calc_db_wrapper_BuiltIn_ieee_vendor_string_by_macaddr(char *resultstring, const size_t resultstring_length, const ipv6calc_macaddr *macaddrp) {
455 	int retval = 1;
456 
457 #ifdef SUPPORT_DB_IEEE
458 	int i;
459 	uint32_t idval, subidval;
460 #endif
461 
462 	DEBUGPRINT_NA(DEBUG_libieee, "called");
463 
464 	/* catch special ones */
465 	if ((macaddrp->addr[0] == 0xfc && macaddrp->addr[1] == 0xfc)) {
466 		/* Linux special OUI for ISDN-NET or PLIP interfaces */
467 		snprintf(resultstring, resultstring_length, "Linux ISDN-NET/PLIP");
468 		return (0);
469 	};
470 
471 	if ( (macaddrp->addr[0] & 0x01) != 0 ) {
472 		/* Multicast */
473 		return (1);
474 	};
475 
476 #ifdef SUPPORT_DB_IEEE
477 	idval = (macaddrp->addr[0] << 16) | (macaddrp->addr[1] << 8) | macaddrp->addr[2];
478 	subidval = (macaddrp->addr[3] << 16) | (macaddrp->addr[4] << 8) | macaddrp->addr[5];
479 
480 	/* run through IAB list */
481 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_iab); i++) {
482 		if (libieee_iab[i].id == idval) {
483 			/* major id match */
484 			if (libieee_iab[i].subid_begin <= subidval && libieee_iab[i].subid_end >= subidval) {
485 				snprintf(resultstring, resultstring_length, "%s", libieee_iab[i].string_owner);
486 				BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IAB);
487 				return (0);
488 			};
489 		};
490 	};
491 
492 	/* run through OUI36 list */
493 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_oui36); i++) {
494 		if (libieee_oui36[i].id == idval) {
495 			/* major id match */
496 			if (libieee_oui36[i].subid_begin <= subidval && libieee_oui36[i].subid_end >= subidval) {
497 				snprintf(resultstring, resultstring_length, "%s", libieee_oui36[i].string_owner);
498 				BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_OUI36);
499 				return (0);
500 			};
501 		};
502 	};
503 
504 	/* run through OUI28 list */
505 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_oui28); i++) {
506 		if (libieee_oui28[i].id == idval) {
507 			/* major id match */
508 			if (libieee_oui28[i].subid_begin <= subidval && libieee_oui28[i].subid_end >= subidval) {
509 				snprintf(resultstring, resultstring_length, "%s", libieee_oui28[i].string_owner);
510 				BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_OUI28);
511 				return (0);
512 			};
513 		};
514 	};
515 
516 	/* run through OUI list */
517 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_oui); i++) {
518 		if (libieee_oui[i].id == idval) {
519 			/* match */
520 			snprintf(resultstring, resultstring_length, "%s", libieee_oui[i].string_owner);
521 			BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_OUI);
522 			return (0);
523 		};
524 	};
525 #else
526 	snprintf(resultstring, resultstring_length, "(IEEE databases not compiled in)");
527 	return (0);
528 #endif
529 
530 	/* not found */
531    	retval = 1;
532 	return (retval);
533 };
534 
535 
536 /*
537  * Get short IEEE vendor string
538  * in:  macaddrp
539  * mod: resultstring
540  * out: 0=found, 1=not found
541  */
libipv6calc_db_wrapper_BuiltIn_ieee_vendor_string_short_by_macaddr(char * resultstring,const size_t resultstring_length,const ipv6calc_macaddr * macaddrp)542 int libipv6calc_db_wrapper_BuiltIn_ieee_vendor_string_short_by_macaddr(char *resultstring, const size_t resultstring_length, const ipv6calc_macaddr *macaddrp) {
543 	int retval = 1;
544 
545 #ifdef SUPPORT_DB_IEEE
546 	int i;
547 	uint32_t idval, subidval;
548 #endif
549 
550 	DEBUGPRINT_NA(DEBUG_libieee, "called");
551 
552 	/* catch special ones */
553 	if ((macaddrp->addr[0] == 0xfc && macaddrp->addr[1] == 0xfc)) {
554 		/* Linux special OUI for ISDN-NET or PLIP interfaces */
555 		snprintf(resultstring, resultstring_length, "Linux-ISDN-NET+PLIP");
556 		return (0);
557 	};
558 
559 	if ( (macaddrp->addr[0] & 0x01) != 0 ) {
560 		/* Multicast */
561 		return (1);
562 	};
563 
564 #ifdef SUPPORT_DB_IEEE
565 	idval = (macaddrp->addr[0] << 16) | (macaddrp->addr[1] << 8) | macaddrp->addr[2];
566 	subidval = (macaddrp->addr[3] << 16) | (macaddrp->addr[4] << 8) | macaddrp->addr[5];
567 
568 	/* run through IAB list */
569 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_iab); i++) {
570 		if (libieee_iab[i].id == idval) {
571 			/* major id match */
572 			if (libieee_iab[i].subid_begin <= subidval && libieee_iab[i].subid_end >= subidval) {
573 				snprintf(resultstring, resultstring_length, "%s", libieee_iab[i].shortstring_owner);
574 				BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IAB);
575 				return (0);
576 			};
577 		};
578 	};
579 
580 	/* run through OUI36 list */
581 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_oui36); i++) {
582 		if (libieee_oui36[i].id == idval) {
583 			/* major id match */
584 			if (libieee_oui36[i].subid_begin <= subidval && libieee_oui36[i].subid_end >= subidval) {
585 				snprintf(resultstring, resultstring_length, "%s", libieee_oui36[i].shortstring_owner);
586 				BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_OUI36);
587 				return (0);
588 			};
589 		};
590 	};
591 
592 	/* run through OUI28 list */
593 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_oui28); i++) {
594 		if (libieee_oui28[i].id == idval) {
595 			/* major id match */
596 			if (libieee_oui28[i].subid_begin <= subidval && libieee_oui28[i].subid_end >= subidval) {
597 				snprintf(resultstring, resultstring_length, "%s", libieee_oui28[i].shortstring_owner);
598 				BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_OUI28);
599 				return (0);
600 			};
601 		};
602 	};
603 
604 	/* run through OUI list */
605 	for (i = 0; i < MAXENTRIES_ARRAY(libieee_oui); i++) {
606 		if (libieee_oui[i].id == idval) {
607 			/* match */
608 			snprintf(resultstring, resultstring_length, "%s", libieee_oui[i].shortstring_owner);
609 			BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_OUI);
610 			return (0);
611 		};
612 	};
613 #else
614 	snprintf(resultstring, resultstring_length, "(IEEE databases not compiled in)");
615 	return (0);
616 #endif
617 
618 	/* not found */
619    	retval = 1;
620 	return (retval);
621 };
622 
623 
624 #ifdef SUPPORT_DB_IPV4_REG
625 /*
626  * dbipv4addr_assignment / get row (callback function for retrieving value from array)
627  */
libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_assignment(const uint32_t row,uint32_t * key_first_00_31_ptr,uint32_t * key_first_32_63_ptr,uint32_t * key_last_00_31_ptr,uint32_t * key_last_32_63_ptr)628 int libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_assignment(const uint32_t row, uint32_t *key_first_00_31_ptr, uint32_t *key_first_32_63_ptr, uint32_t *key_last_00_31_ptr, uint32_t *key_last_32_63_ptr) {
629 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called fetching row: %lu", (unsigned long int) row);
630 
631 	if (row >= MAXENTRIES_ARRAY(dbipv4addr_assignment)) {
632 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "row out of range: %lu (maximum: %lu)", (unsigned long int) row, (unsigned long int) MAXENTRIES_ARRAY(dbipv4addr_assignment) - 1);
633 		return(1);
634 	};
635 
636 	*key_first_00_31_ptr = dbipv4addr_assignment[row].first;
637 	*key_last_00_31_ptr  = dbipv4addr_assignment[row].last;
638 	*key_first_32_63_ptr = 0;
639 	*key_last_32_63_ptr  = 0;
640 
641 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Keys for row: %lu key_first_00_31_ptr=%08lx key_last_00_31_ptr=%08lxu",
642 		(unsigned long int) row,
643 		(unsigned long int) *key_first_00_31_ptr,
644 		(unsigned long int) *key_last_00_31_ptr
645 	);
646 
647 	return(0);
648 };
649 
650 
651 /*
652  * dbipv4addr_assignment_iana / get row (callback function for retrieving value from array)
653  */
libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_assignment_iana(const uint32_t row,uint32_t * key_first_00_31_ptr,uint32_t * key_first_32_63_ptr,uint32_t * key_last_00_31_ptr,uint32_t * key_last_32_63_ptr)654 int libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_assignment_iana(const uint32_t row, uint32_t *key_first_00_31_ptr, uint32_t *key_first_32_63_ptr, uint32_t *key_last_00_31_ptr, uint32_t *key_last_32_63_ptr) {
655 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called fetching row: %lu", (unsigned long int) row);
656 
657 	if (row >= MAXENTRIES_ARRAY(dbipv4addr_assignment_iana)) {
658 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "row out of range: %lu (maximum: %lu)", (unsigned long int) row, (unsigned long int) MAXENTRIES_ARRAY(dbipv4addr_assignment_iana) - 1);
659 		return(1);
660 	};
661 
662 	*key_first_00_31_ptr = dbipv4addr_assignment_iana[row].first;
663 	*key_last_00_31_ptr  = dbipv4addr_assignment_iana[row].last;
664 	*key_first_32_63_ptr = 0;
665 	*key_last_32_63_ptr  = 0;
666 
667 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Keys for row: %lu key_first_00_31_ptr=%08lx key_last_00_31_ptr=%08lxu",
668 		(unsigned long int) row,
669 		(unsigned long int) *key_first_00_31_ptr,
670 		(unsigned long int) *key_last_00_31_ptr
671 	);
672 
673 	return(0);
674 };
675 
676 
677 /*
678  * dbipv4addr_info / get row (callback function for retrieving value from array)
679  */
libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_info(const uint32_t row,uint32_t * key_first_00_31_ptr,uint32_t * key_first_32_63_ptr,uint32_t * key_last_00_31_ptr,uint32_t * key_last_32_63_ptr)680 int libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_info(const uint32_t row, uint32_t *key_first_00_31_ptr, uint32_t *key_first_32_63_ptr, uint32_t *key_last_00_31_ptr, uint32_t *key_last_32_63_ptr) {
681 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called fetching row: %lu", (unsigned long int) row);
682 
683 	if (row >= MAXENTRIES_ARRAY(dbipv4addr_info)) {
684 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "row out of range: %lu (maximum: %lu)", (unsigned long int) row, (unsigned long int) MAXENTRIES_ARRAY(dbipv4addr_info) - 1);
685 		return(1);
686 	};
687 
688 	*key_first_00_31_ptr = dbipv4addr_info[row].first;
689 	*key_last_00_31_ptr  = dbipv4addr_info[row].last;
690 	*key_first_32_63_ptr = 0;
691 	*key_last_32_63_ptr  = 0;
692 
693 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Keys for row: %lu key_first_00_31_ptr=%08lx key_last_00_31_ptr=%08lxu",
694 		(unsigned long int) row,
695 		(unsigned long int) *key_first_00_31_ptr,
696 		(unsigned long int) *key_last_00_31_ptr
697 	);
698 
699 	return(0);
700 };
701 #endif // SUPPORT_DB_IPV4_REG
702 
703 
704 /*
705  * get registry number of an IPv4 address
706  *
707  * in:  ipv4addr = IPv4 address structure
708  * out: assignment number (-1 = no result)
709  */
libipv6calc_db_wrapper_BuiltIn_registry_num_by_ipv4addr(const ipv6calc_ipv4addr * ipv4addrp)710 int libipv6calc_db_wrapper_BuiltIn_registry_num_by_ipv4addr(const ipv6calc_ipv4addr *ipv4addrp) {
711 	uint32_t ipv4 = ipv4addr_getdword(ipv4addrp);
712 
713 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Given IPv4 address: %08x", (unsigned int) ipv4);
714 
715 	int result = IPV4_ADDR_REGISTRY_UNKNOWN;
716 
717 #ifdef SUPPORT_DB_IPV4_REG
718 	int match = -1;
719 
720 	match = libipv6calc_db_wrapper_get_entry_generic(
721 		NULL,							// pointer to data
722 		IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY,			// type of data_ptr
723 		IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_FIRST_LAST,		// key type
724 		0,							// key format (not relevant)
725 		32,							// key length
726 		IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_BINARY,		// search type
727 		MAXENTRIES_ARRAY(dbipv4addr_assignment),		// number of rows
728 		ipv4,							// lookup key MSB
729 		0,							// lookup key LSB
730 		NULL,							// data ptr (not used in IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY)
731 		libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_assignment	// function pointer
732 	);
733 
734 	if (match > -1) {
735 		result = dbipv4addr_assignment[match].registry;
736 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished with success result (dbipv4addr_assignment): match=%d reg=%d", match, result);
737 		BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IPV4_REGISTRY);
738 	};
739 
740 	if (result == IPV4_ADDR_REGISTRY_UNKNOWN) {
741 		// IANA fallback
742 		DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Nothing found in dbipv4addr_assignment, fallback now to dbipv4addr_assignment_iana");
743 
744 		match = libipv6calc_db_wrapper_get_entry_generic(
745 			NULL,							// pointer to data
746 			IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY,			// type of data_ptr
747 			IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_FIRST_LAST,		// key type
748 			0,							// key format (not relevant)
749 			32,							// key length
750 			IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_BINARY,		// search type
751 			MAXENTRIES_ARRAY(dbipv4addr_assignment_iana),		// number of rows
752 			ipv4,							// lookup key MSB
753 			0,							// lookup key LSB
754 			NULL,							// data ptr (not used in IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY)
755 			libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_assignment_iana	// function pointer
756 		);
757 
758 		if (match > -1) {
759 			result = dbipv4addr_assignment_iana[match].registry;
760 			DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished with success result (dbipv4addr_assignment_iana): match=%d reg=%d", match, result);
761 			BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IPV4_REGISTRY);
762 		} else {
763 			DEBUGPRINT_NA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished without success");
764 		};
765 	};
766 #endif // SUPPORT_DB_IPV4_REG
767 
768 	return(result);
769 };
770 
771 
772 /*
773  * get info of an IPv4 address
774  *
775  * in:  ipv4addr = IPv4 address structure
776  * in:  char* and size to fill
777  * out: 0 = found, -1 = no result
778  */
libipv6calc_db_wrapper_BuiltIn_info_by_ipv4addr(const ipv6calc_ipv4addr * ipv4addrp,char * string,const size_t string_len)779 int libipv6calc_db_wrapper_BuiltIn_info_by_ipv4addr(const ipv6calc_ipv4addr *ipv4addrp, char *string, const size_t string_len) {
780 	uint32_t ipv4 = ipv4addr_getdword(ipv4addrp);
781 
782 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Given IPv4 address: %08x", (unsigned int) ipv4);
783 
784 	int result = -1;
785 
786 #ifdef SUPPORT_DB_IPV4_REG
787 	int match = -1;
788 
789 	match = libipv6calc_db_wrapper_get_entry_generic(
790 		NULL,							// pointer to data
791 		IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY,			// type of data_ptr
792 		IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_FIRST_LAST,		// key type
793 		0,							// key format (not relevant)
794 		32,							// key length
795 		IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_BINARY,		// search type
796 		MAXENTRIES_ARRAY(dbipv4addr_info),			// number of rows
797 		ipv4,							// lookup key MSB
798 		0,							// lookup key LSB
799 		NULL,							// data ptr (not used in IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY)
800 		libipv6calc_db_wrapper_BuiltIn_get_row_dbipv4addr_info	// function pointer
801 	);
802 
803 	if (match > -1) {
804 		snprintf(string, string_len, "%s", dbipv4addr_info[match].info);
805 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished with success result (dbipv4addr_info): match=%d info=\"%s\"", match, string);
806 		BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IPV4_REGISTRY);
807 		result = 0;
808 	};
809 
810 #else  // SUPPORT_DB_IPV4_REG
811 	snprintf(string, string_len, "%s", "");
812 #endif // SUPPORT_DB_IPV4_REG
813 
814 	return(result);
815 };
816 
817 
818 #ifdef SUPPORT_DB_IPV6_REG
819 /*
820  * dbipv6addr_assignment / get row (callback function for retrieving value from array)
821  */
libipv6calc_db_wrapper_BuiltIn_get_row_dbipv6addr_assignment(const uint32_t row,uint32_t * key_base_00_31_ptr,uint32_t * key_base_32_63_ptr,uint32_t * key_mask_00_31_ptr,uint32_t * key_mask_32_63_ptr)822 int libipv6calc_db_wrapper_BuiltIn_get_row_dbipv6addr_assignment(const uint32_t row, uint32_t *key_base_00_31_ptr, uint32_t *key_base_32_63_ptr, uint32_t *key_mask_00_31_ptr, uint32_t *key_mask_32_63_ptr) {
823 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called fetching row: %lu", (unsigned long int) row);
824 
825 	if (row >= MAXENTRIES_ARRAY(dbipv6addr_assignment)) {
826 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "row out of range: %lu (maximum: %lu)", (unsigned long int) row, (unsigned long int) MAXENTRIES_ARRAY(dbipv6addr_assignment) - 1);
827 		return(-1);
828 	};
829 
830 	*key_base_00_31_ptr = dbipv6addr_assignment[row].ipv6addr_00_31;
831 	*key_base_32_63_ptr = dbipv6addr_assignment[row].ipv6addr_32_63;
832 	*key_mask_00_31_ptr = dbipv6addr_assignment[row].ipv6mask_00_31;
833 	*key_mask_32_63_ptr = dbipv6addr_assignment[row].ipv6mask_32_63;
834 
835 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Keys for row: %lu key_base_00_31_ptr=%08lx key_base_32_63_ptr=%08lx key_mask_00_31_ptr=%08lxu key_mask_32_63_ptr=%08lxu seqlongest=%d",
836 		(unsigned long int) row,
837 		(unsigned long int) *key_base_00_31_ptr,
838 		(unsigned long int) *key_base_32_63_ptr,
839 		(unsigned long int) *key_mask_00_31_ptr,
840 		(unsigned long int) *key_mask_32_63_ptr,
841 		dbipv6addr_assignment[row].prefixlength
842 	);
843 
844 	return(dbipv6addr_assignment[row].prefixlength);
845 };
846 
847 
848 /*
849  * dbipv6addr_info / get row (callback function for retrieving value from array)
850  */
libipv6calc_db_wrapper_BuiltIn_get_row_dbipv6addr_info(const uint32_t row,uint32_t * key_base_00_31_ptr,uint32_t * key_base_32_63_ptr,uint32_t * key_mask_00_31_ptr,uint32_t * key_mask_32_63_ptr)851 int libipv6calc_db_wrapper_BuiltIn_get_row_dbipv6addr_info(const uint32_t row, uint32_t *key_base_00_31_ptr, uint32_t *key_base_32_63_ptr, uint32_t *key_mask_00_31_ptr, uint32_t *key_mask_32_63_ptr) {
852 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Called fetching row: %lu", (unsigned long int) row);
853 
854 	if (row >= MAXENTRIES_ARRAY(dbipv6addr_info)) {
855 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "row out of range: %lu (maximum: %lu)", (unsigned long int) row, (unsigned long int) MAXENTRIES_ARRAY(dbipv6addr_info) - 1);
856 		return(-1);
857 	};
858 
859 	*key_base_00_31_ptr = dbipv6addr_info[row].ipv6addr_00_31;
860 	*key_base_32_63_ptr = dbipv6addr_info[row].ipv6addr_32_63;
861 	*key_mask_00_31_ptr = dbipv6addr_info[row].ipv6mask_00_31;
862 	*key_mask_32_63_ptr = dbipv6addr_info[row].ipv6mask_32_63;
863 
864 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Keys for row: %lu key_base_00_31_ptr=%08lx key_base_32_63_ptr=%08lx key_mask_00_31_ptr=%08lxu key_mask_32_63_ptr=%08lxu seqlongest=%d",
865 		(unsigned long int) row,
866 		(unsigned long int) *key_base_00_31_ptr,
867 		(unsigned long int) *key_base_32_63_ptr,
868 		(unsigned long int) *key_mask_00_31_ptr,
869 		(unsigned long int) *key_mask_32_63_ptr,
870 		dbipv6addr_info[row].prefixlength
871 	);
872 
873 	return(dbipv6addr_info[row].prefixlength);
874 };
875 #endif // SUPPORT_DB_IPV6_REG
876 
877 
878 /*
879  * get registry number of an IPv6 address
880  *
881  * in:  ipv6addr = IPv6 address structure
882  * out: assignment number (-1 = no result)
883  */
libipv6calc_db_wrapper_BuiltIn_registry_num_by_ipv6addr(const ipv6calc_ipv6addr * ipv6addrp)884 int libipv6calc_db_wrapper_BuiltIn_registry_num_by_ipv6addr(const ipv6calc_ipv6addr *ipv6addrp) {
885 	uint32_t ipv6_00_31 = ipv6addr_getdword(ipv6addrp, 0);
886 	uint32_t ipv6_32_63 = ipv6addr_getdword(ipv6addrp, 1);
887 
888 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Given ipv6 prefix: %08x%08x", (unsigned int) ipv6_00_31, (unsigned int) ipv6_32_63);
889 
890 	if ((ipv6addrp->typeinfo & IPV6_NEW_ADDR_6BONE) != 0) {
891 		return(IPV6_ADDR_REGISTRY_6BONE);
892 	};
893 
894 	int result = IPV6_ADDR_REGISTRY_UNKNOWN;
895 
896 #ifdef SUPPORT_DB_IPV6_REG
897 	int match = -1;
898 
899 	match = libipv6calc_db_wrapper_get_entry_generic(
900 		NULL,							// pointer to data
901 		IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY,			// type of data_ptr
902 		IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_BASE_MASK,		// key type
903 		0,							// key format (not relevant)
904 		64,							// key length
905 		IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_SEQLONGEST,		// search type
906 		MAXENTRIES_ARRAY(dbipv6addr_assignment),		// number of rows
907 		ipv6_00_31,						// lookup key MSB
908 		ipv6_32_63,						// lookup key LSB
909 		NULL,							// data ptr (not used in IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY)
910 		libipv6calc_db_wrapper_BuiltIn_get_row_dbipv6addr_assignment	// function pointer
911 	);
912 
913 	/* result */
914 	if ( match > -1 ) {
915 		result = dbipv6addr_assignment[match].registry;
916 		BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IPV6_REGISTRY);
917 	};
918 #endif
919 	return(result);
920 };
921 
922 
923 /*
924  * get info of an IPv6 address
925  *
926  * in:  ipv6addr = IPv6 address structure
927  * in:  char* and size to fill
928  * out: 0 = found, -1 = no result
929  */
libipv6calc_db_wrapper_BuiltIn_info_by_ipv6addr(const ipv6calc_ipv6addr * ipv6addrp,char * string,const size_t string_len)930 int libipv6calc_db_wrapper_BuiltIn_info_by_ipv6addr(const ipv6calc_ipv6addr *ipv6addrp, char *string, const size_t string_len) {
931 	uint32_t ipv6_00_31 = ipv6addr_getdword(ipv6addrp, 0);
932 	uint32_t ipv6_32_63 = ipv6addr_getdword(ipv6addrp, 1);
933 
934 	DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Given ipv6 prefix: %08x%08x", (unsigned int) ipv6_00_31, (unsigned int) ipv6_32_63);
935 
936 	int result = -1;
937 
938 #ifdef SUPPORT_DB_IPV6_REG
939 	int match = -1;
940 
941 	match = libipv6calc_db_wrapper_get_entry_generic(
942 		NULL,							// pointer to data
943 		IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY,			// type of data_ptr
944 		IPV6CALC_DB_LOOKUP_DATA_KEY_TYPE_BASE_MASK,		// key type
945 		0,							// key format (not relevant)
946 		64,							// key length
947 		IPV6CALC_DB_LOOKUP_DATA_SEARCH_TYPE_BINARY,		// search type
948 		MAXENTRIES_ARRAY(dbipv6addr_info),			// number of rows
949 		ipv6_00_31,						// lookup key MSB
950 		ipv6_32_63,						// lookup key LSB
951 		NULL,							// data ptr (not used in IPV6CALC_DB_LOOKUP_DATA_PTR_TYPE_ARRAY)
952 		libipv6calc_db_wrapper_BuiltIn_get_row_dbipv6addr_info	// function pointer
953 	);
954 
955 	if (match > -1) {
956 		snprintf(string, string_len, "%s", dbipv6addr_info[match].info);
957 		DEBUGPRINT_WA(DEBUG_libipv6calc_db_wrapper_BuiltIn, "Finished with success result (dbipv6addr_info): match=%d info=\"%s\"", match, string);
958 		BUILTIN_DB_USAGE_MAP_TAG(BUILTIN_DB_IPV6_REGISTRY);
959 		result = 0;
960 	};
961 
962 #else  // SUPPORT_DB_IPV6_REG
963 	snprintf(string, string_len, "%s", "");
964 #endif // SUPPORT_DB_IPV6_REG
965 
966 	return(result);
967 };
968 
969 #endif		// SUPPORT_BUILTIN
970