1 /*
2 * Project : ipv6calc/lib
3 * File : libipv6calc.c
4 * Version : $Id: 117603045c748f630e6c2cb162a58710de4d60d8 $
5 * Copyright : 2001-2019 by Peter Bieringer <pb (at) bieringer.de>
6 *
7 * Information:
8 * Function library for some tools
9 */
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15
16 #include "config.h"
17
18 #include "ipv6calctypes.h"
19 #include "libipv6calc.h"
20 #include "libipv6calcdebug.h"
21 #include "librfc1924.h"
22 #include "librfc2874.h"
23 #include "librfc1886.h"
24
25 #include "../databases/lib/libipv6calc_db_wrapper.h"
26
27 /*
28 * function converts chars in a string to upcase
29 * in : pointer to a string
30 */
string_to_upcase(char * string)31 void string_to_upcase(char *string) {
32 int i;
33
34 if (strlen(string) > 0) {
35 for (i = 0; i < (int) strlen(string); i++) {
36 string[i] = toupper(string[i]);
37 };
38 };
39
40 return;
41 };
42
43
44 /*
45 * function converts chars in a string to lowcase
46 * in : pointer to a string
47 */
string_to_lowcase(char * string)48 void string_to_lowcase(char *string) {
49 int i;
50
51 if (strlen(string) > 0) {
52 for (i = 0; i < (int) strlen(string); i++) {
53 string[i] = tolower(string[i]);
54 };
55 };
56
57 return;
58 };
59
60
61 /*
62 * reverse string
63 * in : pointer to a string
64 */
string_to_reverse(char * string)65 void string_to_reverse(char *string) {
66 int i;
67 char helpchar;
68 size_t length;
69
70 length = strlen(string);
71
72 if (length < 2) {
73 /* nothing to do */
74 return;
75 };
76
77 for (i = 0; i < ( (int) (length >> 1)); i++) {
78 helpchar = string[i];
79 string[i] = string[length - i - 1];
80 string[length - i - 1] = helpchar;
81 };
82
83 return;
84 };
85
86
87 /*
88 * dotted-reverse string
89 * in : pointer to a string
90 */
string_to_reverse_dotted(char * string,const size_t string_length)91 void string_to_reverse_dotted(char *string, const size_t string_length) {
92 char resultstring[IPV6CALC_STRING_MAX], tempstring[IPV6CALC_STRING_MAX];
93 char *token, *cptr, **ptrptr;
94 int flag_first = 1;
95
96 ptrptr = &cptr;
97
98 /* clear result string */
99 snprintf(resultstring, sizeof(resultstring), "%s", "");
100
101 /* check for starting dot */
102 if ( string[0] == '.' ) {
103 snprintf(tempstring, sizeof(tempstring), "%s.", resultstring);
104 snprintf(resultstring, sizeof(resultstring), "%s", tempstring);
105 };
106
107 token = strtok_r(string, ".", ptrptr);
108
109 while (token != NULL) {
110 if (flag_first == 1) {
111 snprintf(tempstring, sizeof(tempstring), "%s%s", token, resultstring);
112 flag_first = 0;
113 } else {
114 snprintf(tempstring, sizeof(tempstring), "%s.%s", token, resultstring);
115 };
116 snprintf(resultstring, sizeof(resultstring), "%s", tempstring);
117
118 token = strtok_r(NULL, ".", ptrptr);
119 };
120
121 if ( string[strlen(string) - 1] == '.' ) {
122 snprintf(tempstring, sizeof(tempstring), ".%s", resultstring);
123 snprintf(resultstring, sizeof(resultstring), "%s", tempstring);
124 };
125
126 snprintf(string, string_length, ".%s", resultstring);
127
128 return;
129 };
130
131
132 /*
133 * function converts chars in a string to upcase
134 * in : pointer to a string
135 * ret: format number
136 */
libipv6calc_autodetectinput(const char * string)137 uint32_t libipv6calc_autodetectinput(const char *string) {
138 uint32_t type = FORMAT_auto_noresult;
139 int i, j = 0, result;
140 unsigned int numdots = 0, numcolons = 0, numdigits = 0, numxdigits = 0, numdashes = 0, numspaces = 0, numslashes = 0, numalnums = 0, numchar_s = 0, numpercents = 0, numcolonsdouble = 0, xdigitlen_max = 0, xdigitlen_min = 0, xdl;
141 char resultstring[IPV6CALC_STRING_MAX];
142 size_t length;
143 ipv6calc_ipv4addr ipv4addr;
144
145 length = strlen(string);
146
147 if (length == 0) {
148 /* input is empty */
149 goto END_libipv6calc_autodetectinput;
150 };
151
152 ipv4addr_clearall(&ipv4addr);
153 if (addr_to_ipv4addrstruct(string, NULL, 0, &ipv4addr) == 0) {
154 type = FORMAT_ipv4addr;
155 goto END_libipv6calc_autodetectinput;
156 }
157
158 xdl = 0;
159 for (i = 0; i < (int) length; i++) {
160 if (string[i] == '.') { numdots++; };
161 if (string[i] == ':') {
162 numcolons++;
163 if (i < (int) length + 1) {
164 /* check for double colons */
165 if (string[i+1] == ':') {
166 numcolonsdouble++;
167 numcolons++;
168 i++;
169 };
170 };
171 };
172 if (string[i] == '-') { numdashes++; };
173 if (string[i] == '/') { numslashes++; };
174 if (string[i] == ' ') { numspaces++; };
175 if (string[i] == '%') { numpercents++; };
176 if (string[i] == 's') { numchar_s++; };
177 if (isdigit((int) string[i])) { numdigits++; };
178 if (isxdigit((int) string[i])) {
179 numxdigits++;
180 xdl++;
181 } else {
182 if (xdigitlen_max == 0 && xdigitlen_min == 0) {
183 // init
184 xdigitlen_max = xdl;
185 xdigitlen_min = xdl;
186 };
187 if (xdl > xdigitlen_max) {
188 xdigitlen_max = xdl;
189 };
190 if (xdl < xdigitlen_min) {
191 xdigitlen_min = xdl;
192 };
193 xdl = 0;
194 };
195 if (isalnum((int) string[i])) { numalnums++; };
196 };
197
198 DEBUGPRINT_NA(DEBUG_libipv6calc, "Autodetection source:");
199 DEBUGPRINT_WA(DEBUG_libipv6calc, " numdots :%d", numdots);
200 DEBUGPRINT_WA(DEBUG_libipv6calc, " numcolons :%d", numcolons);
201 DEBUGPRINT_WA(DEBUG_libipv6calc, " numcolonsdouble:%d", numcolonsdouble);
202 DEBUGPRINT_WA(DEBUG_libipv6calc, " numdashes :%d", numdashes);
203 DEBUGPRINT_WA(DEBUG_libipv6calc, " numspaces :%d", numspaces);
204 DEBUGPRINT_WA(DEBUG_libipv6calc, " numslashes :%d", numslashes);
205 DEBUGPRINT_WA(DEBUG_libipv6calc, " numdigits :%d", numdigits);
206 DEBUGPRINT_WA(DEBUG_libipv6calc, " numxdigits :%d", numxdigits);
207 DEBUGPRINT_WA(DEBUG_libipv6calc, " numalnums :%d", numalnums);
208 DEBUGPRINT_WA(DEBUG_libipv6calc, " numpercents :%d", numpercents);
209 DEBUGPRINT_WA(DEBUG_libipv6calc, " numchar_s :%d", numchar_s);
210 DEBUGPRINT_WA(DEBUG_libipv6calc, " xdigit len max :%d", xdigitlen_max);
211 DEBUGPRINT_WA(DEBUG_libipv6calc, " xdigit len min :%d", xdigitlen_min);
212 DEBUGPRINT_WA(DEBUG_libipv6calc, " length :%d", (int) length);
213
214 if ( length == 20 && numdots == 0 && numcolons == 0 ) {
215 /* probably a base85 one */
216 DEBUGPRINT_NA(DEBUG_libipv6calc, " check FORMAT_base85");
217 result = librfc1924_formatcheck(string, resultstring, sizeof(resultstring));
218 if ( result == 0 ) {
219 /* ok: base85 */
220 type = FORMAT_base85;
221 goto END_libipv6calc_autodetectinput;
222 } else DEBUGPRINT_WA(DEBUG_libipv6calc, " check FORMAT_base85 not successful, result: %s", resultstring);
223 };
224
225 if ( strncmp(string, "\\[", 2) == 0 ) {
226 /* check for Bitstring label: \[x..../dd] */
227 DEBUGPRINT_NA(DEBUG_libipv6calc, " check FORMAT_bitstring");
228 result = librfc2874_formatcheck(string, resultstring, strlen(resultstring));
229 if ( result == 0 ) {
230 /* ok: bitstring label */
231 type = FORMAT_bitstring;
232 goto END_libipv6calc_autodetectinput;
233 } else DEBUGPRINT_WA(DEBUG_libipv6calc, " check FORMAT_bitstring not successful, result: %s", resultstring);
234 };
235
236 if (length == 32 && numxdigits == 32 && numdots == 0 && numcolons == 0) {
237 /* ifinet6 xxxx..xxxx */
238 type = FORMAT_ifinet6;
239 goto END_libipv6calc_autodetectinput;
240 };
241
242 if (((length == 8 && numxdigits == 8) || (length == 7 && numxdigits == 7)) && numdots == 0 && numcolons == 0) {
243 /* IPv4 hexadecimal: xxxxxxxx or xxxxxxx */
244 type = FORMAT_ipv4hex;
245 goto END_libipv6calc_autodetectinput;
246 };
247
248 if ((length >= 11 && length <= 17 && numxdigits >= 6 && numxdigits <= 12 && numdots == 0 && ( (numcolons == 5 && numdashes == 0 && numspaces == 0)
249 || (numcolons == 0 && numdashes == 5 && numspaces == 0)
250 || (numcolons == 0 && numdashes == 0 && numspaces == 5))
251 )
252 || (length == 13 && numcolons == 0 && numdashes == 1 && numspaces == 0 && numxdigits == 12)
253 || (length == 12 && numcolons == 0 && numdashes == 0 && numspaces == 0 && numxdigits == 12)
254 || (length == 14 && numdots == 2 && numxdigits ==12 && xdigitlen_min == 4 && xdigitlen_max == 4)
255 ) {
256 /* MAC 00:00:00:00:00:00 or 00-00-00-00-00-00 or "xx xx xx xx xx xx" or "xxxxxx-xxxxxx" or xxxxxxxxxxxx or xxxx.xxxx.xxxx */
257
258 if (length == 14 && numdots == 2 && numxdigits ==12 && xdigitlen_min == 4 && xdigitlen_max == 4) {
259 // xxxx.xxxx.xxxx
260 type = FORMAT_mac;
261 DEBUGPRINT_NA(DEBUG_libipv6calc, "Autodetection found type: mac");
262 goto END_libipv6calc_autodetectinput;
263 };
264
265 DEBUGPRINT_NA(DEBUG_libipv6calc, " check FORMAT_mac");
266
267 /* Check whether minimum 1 xdigit is between colons, dashes, spaces */
268 if (numcolons == 0 && numdashes == 1 && numspaces == 0 && numxdigits == 12) {
269
270 /* Check xxxxxx-xxxxxx */
271 j = 0;
272 for (i = 0; i < (int) length; i++) {
273 if (isxdigit((int) string[i])) {
274 j++;
275 if ( j > 6 ) {
276 /* more than 6 xdigits */
277 j = -1;
278 break;
279 };
280 continue;
281 } else if (string[i] == '-' ) {
282 if ( j == 0 ) {
283 /* dash follow dash */
284 j = -1;
285 break;
286 };
287 j = 0;
288 continue;
289 };
290 /* normally not reached */
291 j = -1;
292 break;
293 };
294
295 } else if (numcolons == 0 && numdashes == 0 && numspaces == 0 && numxdigits == 12) {
296 /* nothing more to check */
297 } else {
298
299 j = 0;
300 for (i = 0; i < (int) length; i++) {
301 if (isxdigit((int) string[i])) {
302 j++;
303 if ( j > 2 ) {
304 /* more than 2 xdigits */
305 j = -1;
306 break;
307 };
308 continue;
309 } else if (string[i] == ':' || string[i] == '-' || string[i] == ' ') {
310 if ( j == 0 ) {
311 /* colon/dash/space follows colon/dash/space */
312 j = -1;
313 break;
314 };
315 j = 0;
316 continue;
317 };
318 /* normally not reached */
319 j = -1;
320 break;
321 };
322
323 }; /* end of if */
324
325 if ( j != -1 ) {
326 type = FORMAT_mac;
327 DEBUGPRINT_NA(DEBUG_libipv6calc, "Autodetection found type: mac");
328 goto END_libipv6calc_autodetectinput;
329 };
330 };
331
332 if ((length >= 15 && length <= 23 && numxdigits >= 8 && numxdigits <= 16 && numdots == 0 && ( (numcolons == 7 && numdashes == 0 && numspaces == 0) || (numcolons == 0 && numdashes == 7 && numspaces == 0) || (numcolons == 0 && numdashes == 0 && numspaces == 7))) || (length == 16 && numcolons == 0 && numdashes == 0 && numspaces == 0 && numxdigits == 16)) {
333 /* EUI-64 00:00:00:00:00:00:00:00 or 00-00-00-00-00-00-00-00 or "xx xx xx xx xx xx xx xx" or xxxxxxxxxxxxxxxx */
334
335 DEBUGPRINT_NA(DEBUG_libipv6calc, " check FORMAT_eui64");
336
337 if (numcolons == 0 && numdashes == 0 && numspaces == 0 && numxdigits == 16) {
338 /* nothing more to check */
339 } else {
340
341 j = 0;
342 for (i = 0; i < (int) length; i++) {
343 if (isxdigit((int) string[i])) {
344 j++;
345 if ( j > 2 ) {
346 /* more than 2 xdigits */
347 j = -1;
348 break;
349 };
350 continue;
351 } else if (string[i] == ':' || string[i] == '-' || string[i] == ' ') {
352 if ( j == 0 ) {
353 /* colon/dash/space follows colon/dash/space */
354 j = -1;
355 break;
356 };
357 j = 0;
358 continue;
359 };
360 /* normally not reached */
361 j = -1;
362 break;
363 };
364
365 }; /* end of if */
366
367 if ( j != -1 ) {
368 type = FORMAT_eui64;
369 DEBUGPRINT_NA(DEBUG_libipv6calc, "Autodetection found type: eui64");
370 goto END_libipv6calc_autodetectinput;
371 };
372 };
373
374 if (numcolons == 0 && numdots > 0 && numslashes == 0 && numspaces == 0 && (numalnums + numdots) == length) {
375 /* check for reverse nibble string */
376 DEBUGPRINT_NA(DEBUG_libipv6calc, " check FORMAT_revnibbels_arpa");
377 result = librfc1886_formatcheck(string, resultstring, sizeof(resultstring));
378 if ( result == 0 ) {
379 /* ok: reverse nibble string */
380 type = FORMAT_revnibbles_arpa;
381 goto END_libipv6calc_autodetectinput;
382 } else DEBUGPRINT_WA(DEBUG_libipv6calc, " check FORMAT_revnibbels_arpa not successful, result: %s", resultstring);
383 };
384
385 if ((numcolons == 3) && (numcolonsdouble == 0) && numdots == 0 && numslashes == 0 && numpercents == 0 && ((numcolons + numxdigits) == length)) {
386 /* IID */
387 type = FORMAT_iid;
388 goto END_libipv6calc_autodetectinput;
389 };
390
391 if (numcolons != 0 && numdots <= 3 && numslashes <= 1 && ((numpercents == 0 && (numdots + numcolons + numxdigits + numslashes) == length) || (numpercents == 1 && (numdots + numcolons + numxdigits + numslashes + numpercents) <= length))) {
392 /* hopefully an IPv6 address */
393 /* fe80::1 */
394 /* fe80::1%eth0 */
395 type = FORMAT_ipv6addr;
396 goto END_libipv6calc_autodetectinput;
397 };
398
399 if (numcolons == 0 && numdots == 2 && numslashes == 0 && numdashes >= 3 && ((numchar_s == 0 && (numdashes + numdots + numxdigits + 10) == length) || (numchar_s == 1 && (numdashes + numdots + numxdigits + numchar_s + 10) <= length))) {
400 /* hopefully an IPv6 literal address (e.g. 2001-DB8--1.IPV6-LITERAL.NET) IPV6-LITERAL.NET has 10 chars which are not xdigit */
401 /* also supported with scope: fe80--218-8bff-fe17-a226s4.ipv6-literal.net */
402 type = FORMAT_ipv6literal;
403 goto END_libipv6calc_autodetectinput;
404 };
405
406 END_libipv6calc_autodetectinput:
407 if (type != FORMAT_auto_noresult) {
408 DEBUGPRINT_WA(DEBUG_libipv6calc, "Autodetection found type: 0x%08x", (unsigned int) type);
409 } else {
410 DEBUGPRINT_NA(DEBUG_libipv6calc, "Autodetection not successful");
411 };
412 return (type);
413 };
414
415
416 /*
417 * clear filter master structure
418 *
419 * in : *filter = filter structure
420 */
libipv6calc_filter_clear(s_ipv6calc_filter_master * filter_master)421 void libipv6calc_filter_clear(s_ipv6calc_filter_master *filter_master) {
422 ipv4addr_filter_clear(&filter_master->filter_ipv4addr);
423 ipv6addr_filter_clear(&filter_master->filter_ipv6addr);
424 macaddr_filter_clear(&filter_master->filter_macaddr);
425 return;
426 };
427
428 /*
429 * clear filter sub structure db_cc
430 *
431 * in : *filter = filter structure
432 */
libipv6calc_filter_clear_db_cc(s_ipv6calc_filter_db_cc * filter_db_cc)433 void libipv6calc_filter_clear_db_cc(s_ipv6calc_filter_db_cc *filter_db_cc) {
434 int i;
435
436 filter_db_cc->active = 0;
437 filter_db_cc->cc_must_have_max = 0;
438 filter_db_cc->cc_may_not_have_max = 0;
439
440 for (i = 0; i < IPV6CALC_FILTER_DB_CC_MAX; i++) {
441 filter_db_cc->cc_must_have[i] = 0;
442 filter_db_cc->cc_may_not_have[i] = 0;
443 };
444
445 return;
446 };
447
448
449 /*
450 * clear filter sub structure db_asn
451 *
452 * in : *filter = filter structure
453 */
libipv6calc_filter_clear_db_asn(s_ipv6calc_filter_db_asn * filter_db_asn)454 void libipv6calc_filter_clear_db_asn(s_ipv6calc_filter_db_asn *filter_db_asn) {
455 int i;
456
457 filter_db_asn->active = 0;
458 filter_db_asn->asn_must_have_max = 0;
459 filter_db_asn->asn_may_not_have_max = 0;
460
461 for (i = 0; i < IPV6CALC_FILTER_DB_ASN_MAX; i++) {
462 filter_db_asn->asn_must_have[i] = 0;
463 filter_db_asn->asn_may_not_have[i] = 0;
464 };
465
466 return;
467 };
468
469
470 /*
471 * clear filter sub structure db_registry
472 *
473 * in : *filter = filter structure
474 */
libipv6calc_filter_clear_db_registry(s_ipv6calc_filter_db_registry * filter_db_registry)475 void libipv6calc_filter_clear_db_registry(s_ipv6calc_filter_db_registry *filter_db_registry) {
476 int i;
477
478 filter_db_registry->active = 0;
479 filter_db_registry->registry_must_have_max = 0;
480 filter_db_registry->registry_may_not_have_max = 0;
481
482 for (i = 0; i < IPV6CALC_FILTER_DB_REGISTRY_MAX; i++) {
483 filter_db_registry->registry_must_have[i] = 0;
484 filter_db_registry->registry_may_not_have[i] = 0;
485 };
486
487 return;
488 };
489
490
491 /*
492 * function parses ipv6calc filter expression
493 *
494 * in : pointer to a string
495 * mod: master filter structure
496 * ret: success
497 */
libipv6calc_filter_parse(const char * expression,s_ipv6calc_filter_master * filter_master)498 int libipv6calc_filter_parse(const char *expression, s_ipv6calc_filter_master *filter_master) {
499 char tempstring[IPV6CALC_STRING_MAX] = "";
500 char *charptr, *cptr, **ptrptr;
501 ptrptr = &cptr;
502 int r, token_used, result = 0;
503
504 DEBUGPRINT_WA(DEBUG_libipv6calc, "called with: %s", expression);
505
506 snprintf(tempstring, sizeof(tempstring), "%s", expression);
507
508 /* split expression */
509 charptr = strtok_r(tempstring, ",", ptrptr);
510 while (charptr != NULL) {
511 token_used = 0;
512
513 r = ipv4addr_filter_parse(&filter_master->filter_ipv4addr, charptr);
514 if (r == 0) {
515 token_used = 1;
516 } else if (r == 2) {
517 result = 1;
518 ERRORPRINT_WA("Unrecognized filter token (ipv4.xxx): %s", charptr);
519 };
520
521 r = ipv6addr_filter_parse(&filter_master->filter_ipv6addr, charptr);
522 if (r == 0) {
523 token_used = 1;
524 } else if (r == 2) {
525 result = 1;
526 ERRORPRINT_WA("Unrecognized filter token (ipv6.xxx): %s", charptr);
527 };
528
529 // r += macaddr_filter_parse(&filter_macaddr, charptr); // missing implementation
530
531 /* overall check */
532 if ((token_used == 0) && (result != 1)) {
533 result = 1;
534 ERRORPRINT_WA("Unrecognized filter token (general): %s", charptr);
535 };
536
537 charptr = strtok_r(NULL, ",", ptrptr);
538 };
539
540 return (result);
541 };
542
543
544 /*
545 * function checks ipv6calc filter expression
546 *
547 * in: master filter structure
548 * ret: success
549 */
libipv6calc_filter_check(s_ipv6calc_filter_master * filter_master)550 int libipv6calc_filter_check(s_ipv6calc_filter_master *filter_master) {
551 int result = 0, r;
552
553 DEBUGPRINT_NA(DEBUG_libipv6calc, "called");
554
555 r = ipv4addr_filter_check(&filter_master->filter_ipv4addr);
556 if (r > 0) {
557 result = 1;
558 };
559
560 r = ipv6addr_filter_check(&filter_master->filter_ipv6addr);
561 if (r > 0) {
562 result = 1;
563 };
564
565 if (result == 1) {
566 ERRORPRINT_NA("filter check failed");
567 };
568
569 return (result);
570 };
571
572
573 /*
574 * return proper anonymization set by name
575 *
576 * in : *name = name of anonymization set
577 * *ipv6calc_anon_set = pointer to anonymization set to be filled
578 * return: 1=not found, 0=success
579 */
libipv6calc_anon_set_by_name(s_ipv6calc_anon_set * ipv6calc_anon_set,const char * name)580 int libipv6calc_anon_set_by_name(s_ipv6calc_anon_set *ipv6calc_anon_set, const char *name) {
581 int i;
582
583 if (strlen(name) == 0) {
584 fprintf(stderr, "Name of anonymization set is empty\n");
585 return 1;
586 };
587
588 DEBUGPRINT_WA(DEBUG_libipv6calc, "search for anonymization set with name: %s", name);
589
590 for (i = 0; i < MAXENTRIES_ARRAY(ipv6calc_anon_set_list); i++) {
591 DEBUGPRINT_WA(DEBUG_libipv6calc, "compare name: %s ? %s", name, ipv6calc_anon_set_list[i].name);
592
593 if ((strcmp(name, ipv6calc_anon_set_list[i].name) == 0) || (strcmp(name, ipv6calc_anon_set_list[i].name_short) == 0)) {
594 DEBUGPRINT_WA(DEBUG_libipv6calc, "hit name: %s = %s", name, ipv6calc_anon_set_list[i].name);
595
596 memcpy(ipv6calc_anon_set, &ipv6calc_anon_set_list[i], sizeof(s_ipv6calc_anon_set));
597 return 0;
598 };
599 };
600
601 return 1;
602 };
603
604
605 /*
606 * get name of anonymization settings
607 *
608 * in : s_ipv6calc_anon_set = anonymization set
609 * return: char *
610 */
libipv6calc_anon_method_name(const s_ipv6calc_anon_set * ipv6calc_anon_set)611 const char *libipv6calc_anon_method_name(const s_ipv6calc_anon_set *ipv6calc_anon_set) {
612 int i;
613
614 for (i = 0; i < MAXENTRIES_ARRAY(ipv6calc_anon_methods); i++) {
615 if (ipv6calc_anon_methods[i].method == ipv6calc_anon_set->method) {
616 return(ipv6calc_anon_methods[i].name);
617 break;
618 };
619 };
620
621 return(NULL);
622 };
623
624
625 /*
626 * create string of anonymization settings
627 *
628 * in : *string = string to be filled
629 * s_ipv6calc_anon_set = anonymization set
630 * return: void
631 */
libipv6calc_anon_infostring(char * string,const int stringlength,const s_ipv6calc_anon_set * ipv6calc_anon_set)632 void libipv6calc_anon_infostring(char *string, const int stringlength, const s_ipv6calc_anon_set *ipv6calc_anon_set) {
633 const char *method_name = libipv6calc_anon_method_name(ipv6calc_anon_set);
634
635 snprintf(string, stringlength, "set=%s,mask-ipv6=%d,mask-ipv4=%d,mask-eui64=%d,mask-mac=%d,method=%s", ipv6calc_anon_set->name, ipv6calc_anon_set->mask_ipv6, ipv6calc_anon_set->mask_ipv4, ipv6calc_anon_set->mask_eui64, ipv6calc_anon_set->mask_mac, (method_name == NULL ? "unknown" : method_name));
636
637 return;
638 };
639
640
641 /*
642 * check whether anonymization method is supported
643 *
644 * in : s_ipv6calc_anon_set = anonymization set
645 * return:
646 * 2: special check succeeded
647 * 1: no special checks needed
648 * 0: not supported
649 */
libipv6calc_anon_supported(const s_ipv6calc_anon_set * ipv6calc_anon_set)650 int libipv6calc_anon_supported(const s_ipv6calc_anon_set *ipv6calc_anon_set) {
651 /* check requirements */
652 if (ipv6calc_anon_set->method == ANON_METHOD_KEEPTYPEASNCC) {
653 // check for support
654 if (libipv6calc_db_wrapper_has_features(ANON_METHOD_KEEPTYPEASNCC_IPV4_REQ_DB | ANON_METHOD_KEEPTYPEASNCC_IPV6_REQ_DB) == 1) {
655 return(2);
656 } else {
657 if (libipv6calc_db_wrapper_has_features(IPV6CALC_DB_IPV4_TO_CC) != 1) {
658 fprintf(stderr, "ipv6calc anonymization method not supported, missing included/available database: IPv4->CountryCode\n");
659 };
660 if (libipv6calc_db_wrapper_has_features(IPV6CALC_DB_IPV6_TO_CC) != 1) {
661 fprintf(stderr, "ipv6calc anonymization method not supported, missing included/available database: IPv6->CountryCode\n");
662 };
663 if (libipv6calc_db_wrapper_has_features(IPV6CALC_DB_IPV4_TO_AS) != 1) {
664 fprintf(stderr, "ipv6calc anonymization method not supported, missing included/available database: IPv4->AutonomousSystemNumber\n");
665 };
666 if (libipv6calc_db_wrapper_has_features(IPV6CALC_DB_IPV6_TO_AS) != 1) {
667 fprintf(stderr, "ipv6calc anonymization method not supported, missing included/available database: IPv6->AutonomousSystemNumber\n");
668 };
669 return(0);
670 };
671 } else if (ipv6calc_anon_set->method == ANON_METHOD_KEEPTYPEGEONAMEID) {
672 // check for support
673 if (libipv6calc_db_wrapper_has_features(ANON_METHOD_KEEPTYPEGEONAMEID_IPV4_REQ_DB | ANON_METHOD_KEEPTYPEGEONAMEID_IPV6_REQ_DB) == 1) {
674 return(2);
675 } else {
676 if (libipv6calc_db_wrapper_has_features(IPV6CALC_DB_IPV4_TO_GEONAMEID) != 1) {
677 fprintf(stderr, "ipv6calc anonymization method not supported, missing included/available database: IPv4->GeonameID\n");
678 };
679 if (libipv6calc_db_wrapper_has_features(IPV6CALC_DB_IPV6_TO_GEONAMEID) != 1) {
680 fprintf(stderr, "ipv6calc anonymization method not supported, missing included/available database: IPv6->GeonameID\n");
681 };
682 return(0);
683 };
684 } else {
685 return(1);
686 };
687 };
688
689
690 /*
691 * return pointer to registry name by number
692 */
libipv6calc_registry_string_by_num(const int registry)693 const char *libipv6calc_registry_string_by_num(const int registry) {
694 int j = -1, i;
695
696 DEBUGPRINT_WA(DEBUG_libipv6calc, "Called with registry=%d", registry);
697
698 for (i = 0; i < MAXENTRIES_ARRAY(ipv6calc_registries); i++ ) {
699 if (ipv6calc_registries[i].number == registry) {
700 j = i;
701 break;
702 };
703 };
704
705 if (j == -1) {
706 fprintf(stderr, "ERROR - undefined registry number: %d (this should not happen)\n", registry);
707 exit(1);
708 };
709
710 return(ipv6calc_registries[j].token);
711 };
712
713
714 /*
715 * bit counter
716 */
libipv6calc_bitcount_uint32_t(const uint32_t value)717 int libipv6calc_bitcount_uint32_t(const uint32_t value) {
718 int i, count = 0;
719 uint32_t mask = 0x1;
720
721 for (i = 0; i < 32; i++) {
722 if (value & mask) {
723 count++;
724 };
725 mask = mask << 1;
726 };
727 return(count);
728 };
729
730 /*
731 * return library version numeric
732 */
libipv6calc_lib_version_numeric(void)733 uint32_t libipv6calc_lib_version_numeric(void) {
734 return(IPV6CALC_PACKAGE_VERSION_NUMERIC);
735 };
736
737 /*
738 * return library version as string
739 */
libipv6calc_lib_version_string(void)740 const char *libipv6calc_lib_version_string(void) {
741 return(IPV6CALC_PACKAGE_VERSION_STRING);
742
743 };
744
745 /*
746 * return API version numeric
747 */
libipv6calc_api_version_numeric(void)748 uint32_t libipv6calc_api_version_numeric(void) {
749 return(IPV6CALC_API_VERSION_NUMERIC);
750 };
751
752 /*
753 * return API version as string
754 */
libipv6calc_api_version_string(void)755 const char *libipv6calc_api_version_string(void) {
756 return(IPV6CALC_API_VERSION_STRING);
757 };
758