1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7 *
8 * See the COPYRIGHT file distributed with this work for additional
9 * information regarding copyright ownership.
10 */
11
12 #include <config.h>
13
14 #if HAVE_CMOCKA
15
16 #include <stdarg.h>
17 #include <stddef.h>
18 #include <setjmp.h>
19
20 #include <sched.h> /* IWYU pragma: keep */
21 #include <stdbool.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #define UNIT_TESTING
27 #include <cmocka.h>
28
29 #include <isc/print.h>
30 #include <isc/string.h>
31 #include <isc/types.h>
32 #include <isc/util.h>
33
34 #include <dns/geoip.h>
35
36 #include "dnstest.h"
37
38 #if defined(HAVE_GEOIP2)
39 #include <maxminddb.h>
40
41 #include "../geoip2.c"
42
43 /* Use GeoIP2 databases from the 'geoip2' system test */
44 #define TEST_GEOIP_DATA "../../../bin/tests/system/geoip2/data"
45 #elif defined(HAVE_GEOIP)
46 #include <GeoIP.h>
47
48 /* Use GeoIP databases from the 'geoip' system test */
49 #define TEST_GEOIP_DATA "../../../bin/tests/system/geoip/data"
50 #endif
51
52 #if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2)
53 static void load_geoip(const char *dir);
54 static void close_geoip(void);
55
56 static int
_setup(void ** state)57 _setup(void **state) {
58 isc_result_t result;
59
60 UNUSED(state);
61
62 result = dns_test_begin(NULL, false);
63 assert_int_equal(result, ISC_R_SUCCESS);
64
65 /* Use databases from the geoip system test */
66 load_geoip(TEST_GEOIP_DATA);
67
68 return (0);
69 }
70
71 static int
_teardown(void ** state)72 _teardown(void **state) {
73 UNUSED(state);
74
75 close_geoip();
76
77 dns_test_end();
78
79 return (0);
80 }
81
82 static dns_geoip_databases_t geoip;
83 #endif /* HAVE_GEOIP || HAVE_GEOIP2 */
84
85 #if defined(HAVE_GEOIP2)
86 static MMDB_s geoip_country, geoip_city, geoip_as, geoip_isp, geoip_domain;
87
88 static MMDB_s *
open_geoip2(const char * dir,const char * dbfile,MMDB_s * mmdb)89 open_geoip2(const char *dir, const char *dbfile, MMDB_s *mmdb) {
90 char pathbuf[PATH_MAX];
91 int ret;
92
93 snprintf(pathbuf, sizeof(pathbuf), "%s/%s", dir, dbfile);
94 ret = MMDB_open(pathbuf, MMDB_MODE_MMAP, mmdb);
95 if (ret == MMDB_SUCCESS) {
96 return (mmdb);
97 }
98
99 return (NULL);
100 }
101
102 static void
load_geoip(const char * dir)103 load_geoip(const char *dir) {
104 geoip.country = open_geoip2(dir, "GeoIP2-Country.mmdb",
105 &geoip_country);
106 geoip.city = open_geoip2(dir, "GeoIP2-City.mmdb", &geoip_city);
107 geoip.as = open_geoip2(dir, "GeoLite2-ASN.mmdb", &geoip_as);
108 geoip.isp = open_geoip2(dir, "GeoIP2-ISP.mmdb", &geoip_isp);
109 geoip.domain = open_geoip2(dir, "GeoIP2-Domain.mmdb", &geoip_domain);
110 }
111
112 static void
close_geoip(void)113 close_geoip(void) {
114 MMDB_close(&geoip_country);
115 MMDB_close(&geoip_city);
116 MMDB_close(&geoip_as);
117 MMDB_close(&geoip_isp);
118 MMDB_close(&geoip_domain);
119 }
120
121 #elif defined(HAVE_GEOIP)
122 /*
123 * Helper functions (mostly copied from bin/named/geoip.c)
124 */
125
126 static void
init_geoip_db(void ** dbp,GeoIPDBTypes edition,GeoIPDBTypes fallback,GeoIPOptions method,const char * name)127 init_geoip_db(void **dbp, GeoIPDBTypes edition, GeoIPDBTypes fallback,
128 GeoIPOptions method, const char *name)
129 {
130 GeoIP *db;
131
132 REQUIRE(dbp != NULL);
133
134 db = (GeoIP *)*dbp;
135
136 if (db != NULL) {
137 GeoIP_delete(db);
138 db = *dbp = NULL;
139 }
140
141 if (! GeoIP_db_avail(edition)) {
142 goto fail;
143 }
144
145 db = GeoIP_open_type(edition, method);
146 if (db == NULL) {
147 goto fail;
148 }
149
150 *dbp = db;
151 return;
152
153 fail:
154 if (fallback != 0) {
155 init_geoip_db(dbp, fallback, 0, method, name);
156 }
157 }
158
159 static void
load_geoip(const char * dir)160 load_geoip(const char *dir) {
161 GeoIPOptions method;
162
163 #ifdef _WIN32
164 method = GEOIP_STANDARD;
165 #else
166 method = GEOIP_MMAP_CACHE;
167 #endif
168
169 if (dir != NULL) {
170 char *p;
171 DE_CONST(dir, p);
172 GeoIP_setup_custom_directory(p);
173 }
174
175 init_geoip_db(&geoip.country_v4, GEOIP_COUNTRY_EDITION, 0,
176 method, "Country (IPv4)");
177 #ifdef HAVE_GEOIP_V6
178 init_geoip_db(&geoip.country_v6, GEOIP_COUNTRY_EDITION_V6, 0,
179 method, "Country (IPv6)");
180 #endif
181
182 init_geoip_db(&geoip.city_v4, GEOIP_CITY_EDITION_REV1,
183 GEOIP_CITY_EDITION_REV0, method, "City (IPv4)");
184 #if defined(HAVE_GEOIP_V6) && defined(HAVE_GEOIP_CITY_V6)
185 init_geoip_db(&geoip.city_v6, GEOIP_CITY_EDITION_REV1_V6,
186 GEOIP_CITY_EDITION_REV0_V6, method, "City (IPv6)");
187 #endif
188
189 init_geoip_db(&geoip.region, GEOIP_REGION_EDITION_REV1,
190 GEOIP_REGION_EDITION_REV0, method, "Region");
191 init_geoip_db(&geoip.isp, GEOIP_ISP_EDITION, 0,
192 method, "ISP");
193 init_geoip_db(&geoip.org, GEOIP_ORG_EDITION, 0,
194 method, "Org");
195 init_geoip_db(&geoip.as, GEOIP_ASNUM_EDITION, 0,
196 method, "AS");
197 init_geoip_db(&geoip.domain, GEOIP_DOMAIN_EDITION, 0,
198 method, "Domain");
199 init_geoip_db(&geoip.netspeed, GEOIP_NETSPEED_EDITION, 0,
200 method, "NetSpeed");
201 }
202
203 static void
close_geoip(void)204 close_geoip(void) {
205 GeoIP_cleanup();
206 }
207
208 static bool
do_lookup_int(const char * addr,uint8_t * scope,dns_geoip_subtype_t subtype,int id)209 do_lookup_int(const char *addr, uint8_t *scope,
210 dns_geoip_subtype_t subtype, int id)
211 {
212 dns_geoip_elem_t elt;
213 struct in_addr in4;
214 isc_netaddr_t na;
215
216 inet_pton(AF_INET, addr, &in4);
217 isc_netaddr_fromin(&na, &in4);
218
219 elt.subtype = subtype;
220 elt.as_int = id;
221
222 return (dns_geoip_match(&na, scope, &geoip, &elt));
223 }
224
225 #endif /* HAVE_GEOIP */
226
227 #ifdef HAVE_GEOIP2
228 static bool
229 /* Check if an MMDB entry of a given subtype exists for the given IP */
entry_exists(dns_geoip_subtype_t subtype,const char * addr)230 entry_exists(dns_geoip_subtype_t subtype, const char *addr) {
231 struct in6_addr in6;
232 struct in_addr in4;
233 isc_netaddr_t na;
234 MMDB_s *db;
235
236 if (inet_pton(AF_INET6, addr, &in6) == 1) {
237 isc_netaddr_fromin6(&na, &in6);
238 } else if (inet_pton(AF_INET, addr, &in4) == 1) {
239 isc_netaddr_fromin(&na, &in4);
240 } else {
241 INSIST(0);
242 ISC_UNREACHABLE();
243 }
244
245 db = geoip2_database(&geoip, fix_subtype(&geoip, subtype));
246
247 return (db != NULL && get_entry_for(db, &na) != NULL);
248 }
249
250 /*
251 * Baseline test - check if get_entry_for() works as expected, i.e. that its
252 * return values are consistent with the contents of the test MMDBs found in
253 * bin/tests/system/geoip2/data/ (10.53.0.1 and fd92:7065:b8e:ffff::1 should be
254 * present in all databases, 192.0.2.128 should only be present in the country
255 * database, ::1 should be absent from all databases).
256 */
257 static void
baseline(void ** state)258 baseline(void **state) {
259 dns_geoip_subtype_t subtype;
260
261 UNUSED(state);
262
263 subtype = dns_geoip_city_name;
264
265 assert_true(entry_exists(subtype, "10.53.0.1"));
266 assert_false(entry_exists(subtype, "192.0.2.128"));
267 assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1"));
268 assert_false(entry_exists(subtype, "::1"));
269
270 subtype = dns_geoip_country_name;
271
272 assert_true(entry_exists(subtype, "10.53.0.1"));
273 assert_true(entry_exists(subtype, "192.0.2.128"));
274 assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1"));
275 assert_false(entry_exists(subtype, "::1"));
276
277 subtype = dns_geoip_domain_name;
278
279 assert_true(entry_exists(subtype, "10.53.0.1"));
280 assert_false(entry_exists(subtype, "192.0.2.128"));
281 assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1"));
282 assert_false(entry_exists(subtype, "::1"));
283
284 subtype = dns_geoip_isp_name;
285
286 assert_true(entry_exists(subtype, "10.53.0.1"));
287 assert_false(entry_exists(subtype, "192.0.2.128"));
288 assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1"));
289 assert_false(entry_exists(subtype, "::1"));
290
291 subtype = dns_geoip_as_asnum;
292
293 assert_true(entry_exists(subtype, "10.53.0.1"));
294 assert_false(entry_exists(subtype, "192.0.2.128"));
295 assert_true(entry_exists(subtype, "fd92:7065:b8e:ffff::1"));
296 assert_false(entry_exists(subtype, "::1"));
297 }
298 #endif /* HAVE_GEOIP2 */
299
300 #if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2)
301 static bool
do_lookup_string(const char * addr,uint8_t * scope,dns_geoip_subtype_t subtype,const char * string)302 do_lookup_string(const char *addr, uint8_t *scope,
303 dns_geoip_subtype_t subtype, const char *string)
304 {
305 dns_geoip_elem_t elt;
306 struct in_addr in4;
307 isc_netaddr_t na;
308 int n;
309
310 n = inet_pton(AF_INET, addr, &in4);
311 assert_int_equal(n, 1);
312 isc_netaddr_fromin(&na, &in4);
313
314 elt.subtype = subtype;
315 strlcpy(elt.as_string, string, sizeof(elt.as_string));
316
317 return (dns_geoip_match(&na, scope, &geoip, &elt));
318 }
319
320 static bool
do_lookup_string_v6(const char * addr,uint8_t * scope,dns_geoip_subtype_t subtype,const char * string)321 do_lookup_string_v6(const char *addr, uint8_t *scope,
322 dns_geoip_subtype_t subtype, const char *string)
323 {
324 dns_geoip_elem_t elt;
325 struct in6_addr in6;
326 isc_netaddr_t na;
327 int n;
328
329 n = inet_pton(AF_INET6, addr, &in6);
330 assert_int_equal(n, 1);
331 isc_netaddr_fromin6(&na, &in6);
332
333 elt.subtype = subtype;
334 strlcpy(elt.as_string, string, sizeof(elt.as_string));
335
336 return (dns_geoip_match(&na, scope, &geoip, &elt));
337 }
338
339 /* GeoIP country matching */
340 static void
country(void ** state)341 country(void **state) {
342 bool match;
343 uint8_t scope;
344
345 UNUSED(state);
346
347 #ifdef HAVE_GEOIP2
348 if (geoip.country == NULL) {
349 skip();
350 }
351 #else /* HAVE_GEOIP */
352 if (geoip.country_v4 == NULL) {
353 skip();
354 }
355 #endif /* HAVE_GEOIP */
356
357 match = do_lookup_string("10.53.0.1", &scope,
358 dns_geoip_country_code, "AU");
359 assert_true(match);
360 assert_int_equal(scope, 32);
361
362 match = do_lookup_string("10.53.0.1", &scope,
363 dns_geoip_country_name, "Australia");
364 assert_true(match);
365 assert_int_equal(scope, 32);
366
367 match = do_lookup_string("192.0.2.128", &scope,
368 dns_geoip_country_code, "O1");
369 assert_true(match);
370 assert_int_equal(scope, 24);
371
372 match = do_lookup_string("192.0.2.128", &scope,
373 dns_geoip_country_name, "Other");
374 assert_true(match);
375 assert_int_equal(scope, 24);
376 }
377
378 /* GeoIP country (ipv6) matching */
379 static void
country_v6(void ** state)380 country_v6(void **state) {
381 bool match;
382 uint8_t scope;
383
384 UNUSED(state);
385
386 #ifdef HAVE_GEOIP2
387 if (geoip.country == NULL) {
388 skip();
389 }
390 #else /* HAVE_GEOIP */
391 if (geoip.country_v6 == NULL) {
392 skip();
393 }
394 #endif /* HAVE_GEOIP */
395
396 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope,
397 dns_geoip_country_code, "AU");
398 assert_true(match);
399 assert_int_equal(scope, 128);
400
401 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", &scope,
402 dns_geoip_country_name, "Australia");
403 assert_true(match);
404 assert_int_equal(scope, 128);
405 }
406
407 /* GeoIP city (ipv4) matching */
408 static void
city(void ** state)409 city(void **state) {
410 bool match;
411
412 UNUSED(state);
413
414 #ifdef HAVE_GEOIP2
415 if (geoip.city == NULL) {
416 skip();
417 }
418 #else /* HAVE_GEOIP */
419 if (geoip.city_v4 == NULL) {
420 skip();
421 }
422 #endif /* HAVE_GEOIP */
423
424 match = do_lookup_string("10.53.0.1", NULL,
425 dns_geoip_city_continentcode, "NA");
426 assert_true(match);
427
428 match = do_lookup_string("10.53.0.1", NULL,
429 dns_geoip_city_countrycode, "US");
430 assert_true(match);
431
432 match = do_lookup_string("10.53.0.1", NULL,
433 dns_geoip_city_countryname, "United States");
434 assert_true(match);
435
436 match = do_lookup_string("10.53.0.1", NULL,
437 dns_geoip_city_region, "CA");
438 assert_true(match);
439
440 match = do_lookup_string("10.53.0.1", NULL,
441 dns_geoip_city_regionname, "California");
442 assert_true(match);
443
444 match = do_lookup_string("10.53.0.1", NULL,
445 dns_geoip_city_name, "Redwood City");
446 assert_true(match);
447
448 match = do_lookup_string("10.53.0.1", NULL,
449 dns_geoip_city_postalcode, "94063");
450 assert_true(match);
451
452 #ifdef HAVE_GEOIP
453 match = do_lookup_int("10.53.0.1", NULL, dns_geoip_city_areacode, 650);
454 assert_true(match);
455
456 match = do_lookup_int("10.53.0.1", NULL, dns_geoip_city_metrocode, 807);
457 assert_true(match);
458 #endif
459 }
460
461 /* GeoIP city (ipv6) matching */
462 static void
city_v6(void ** state)463 city_v6(void **state) {
464 bool match;
465
466 UNUSED(state);
467
468 #ifdef HAVE_GEOIP2
469 if (geoip.city == NULL) {
470 skip();
471 }
472 #else /* HAVE_GEOIP */
473 if (geoip.city_v6 == NULL) {
474 skip();
475 }
476 #endif /* HAVE_GEOIP */
477
478 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
479 dns_geoip_city_continentcode, "NA");
480 assert_true(match);
481
482 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
483 dns_geoip_city_countrycode, "US");
484 assert_true(match);
485
486 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
487 dns_geoip_city_countryname,
488 "United States");
489 assert_true(match);
490
491 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
492 dns_geoip_city_region, "CA");
493 assert_true(match);
494
495 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
496 dns_geoip_city_regionname, "California");
497 assert_true(match);
498
499 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
500 dns_geoip_city_name, "Redwood City");
501 assert_true(match);
502
503 match = do_lookup_string_v6("fd92:7065:b8e:ffff::1", NULL,
504 dns_geoip_city_postalcode, "94063");
505 assert_true(match);
506 }
507
508 /* GeoIP asnum matching */
509 static void
asnum(void ** state)510 asnum(void **state) {
511 bool match;
512
513 UNUSED(state);
514
515 if (geoip.as == NULL) {
516 skip();
517 }
518
519 match = do_lookup_string("10.53.0.3", NULL,
520 dns_geoip_as_asnum, "AS100003");
521 assert_true(match);
522 }
523
524 /* GeoIP isp matching */
525 static void
isp(void ** state)526 isp(void **state) {
527 bool match;
528
529 UNUSED(state);
530
531 if (geoip.isp == NULL) {
532 skip();
533 }
534
535 match = do_lookup_string("10.53.0.1", NULL, dns_geoip_isp_name,
536 "One Systems, Inc.");
537 assert_true(match);
538 }
539
540 /* GeoIP org matching */
541 static void
org(void ** state)542 org(void **state) {
543 bool match;
544
545 UNUSED(state);
546
547 #ifdef HAVE_GEOIP2
548 if (geoip.as == NULL) {
549 skip();
550 }
551 #else /* HAVE_GEOIP */
552 if (geoip.org == NULL) {
553 skip();
554 }
555 #endif /* HAVE_GEOIP */
556
557 match = do_lookup_string("10.53.0.2", NULL, dns_geoip_org_name,
558 "Two Technology Ltd.");
559 assert_true(match);
560 }
561
562 /* GeoIP domain matching */
563 static void
domain(void ** state)564 domain(void **state) {
565 bool match;
566
567 UNUSED(state);
568
569 if (geoip.domain == NULL) {
570 skip();
571 }
572
573 match = do_lookup_string("10.53.0.5", NULL,
574 dns_geoip_domain_name, "five.es");
575 assert_true(match);
576 }
577 #endif /* HAVE_GEOIP || HAVE_GEOIP2 */
578
579 #ifdef HAVE_GEOIP
580 /* GeoIP region matching */
581 static void
region(void ** state)582 region(void **state) {
583 bool match;
584
585 UNUSED(state);
586
587 /* Use databases from the geoip system test */
588 load_geoip(TEST_GEOIP_DATA);
589
590 if (geoip.region == NULL) {
591 skip();
592 }
593
594 match = do_lookup_string("10.53.0.1", NULL,
595 dns_geoip_region_code, "CA");
596 assert_true(match);
597
598 match = do_lookup_string("10.53.0.1", NULL,
599 dns_geoip_region_name, "California");
600 assert_true(match);
601
602 match = do_lookup_string("10.53.0.1", NULL,
603 dns_geoip_region_countrycode, "US");
604 assert_true(match);
605 }
606
607 /* GeoIP netspeed matching */
608 static void
netspeed(void ** state)609 netspeed(void **state) {
610 bool match;
611
612 UNUSED(state);
613
614 /* Use databases from the geoip system test */
615 load_geoip(TEST_GEOIP_DATA);
616
617 if (geoip.netspeed == NULL) {
618 skip();
619 }
620
621 match = do_lookup_int("10.53.0.1", NULL, dns_geoip_netspeed_id, 0);
622 assert_true(match);
623
624 match = do_lookup_int("10.53.0.2", NULL, dns_geoip_netspeed_id, 1);
625 assert_true(match);
626
627 match = do_lookup_int("10.53.0.3", NULL, dns_geoip_netspeed_id, 2);
628 assert_true(match);
629
630 match = do_lookup_int("10.53.0.4", NULL, dns_geoip_netspeed_id, 3);
631 assert_true(match);
632 }
633
634 /*
635 * GeoIP best-database matching
636 * (With no specified database and a city database available, answers
637 * should come from city database. With city database unavailable, region
638 * database. Region database unavailable, country database.)
639 */
640 static void
best(void ** state)641 best(void **state) {
642 bool match;
643
644 UNUSED(state);
645
646 /* Use databases from the geoip system test */
647 load_geoip(TEST_GEOIP_DATA);
648
649 if (geoip.region == NULL) {
650 skip();
651 }
652
653 match = do_lookup_string("10.53.0.4", NULL,
654 dns_geoip_countrycode, "US");
655 assert_true(match);
656
657 match = do_lookup_string("10.53.0.4", NULL,
658 dns_geoip_countrycode3, "USA");
659 assert_true(match);
660
661 match = do_lookup_string("10.53.0.4", NULL,
662 dns_geoip_countryname, "United States");
663 assert_true(match);
664
665 match = do_lookup_string("10.53.0.4", NULL,
666 dns_geoip_regionname, "Virginia");
667 assert_true(match);
668
669 match = do_lookup_string("10.53.0.4", NULL,
670 dns_geoip_region, "VA");
671 assert_true(match);
672
673 GeoIP_delete(geoip.city_v4);
674 geoip.city_v4 = NULL;
675
676 match = do_lookup_string("10.53.0.4", NULL,
677 dns_geoip_countrycode, "AU");
678 assert_true(match);
679
680 /*
681 * Note, region doesn't support code3 or countryname, so
682 * the next two would be answered from the country database instead
683 */
684 match = do_lookup_string("10.53.0.4", NULL,
685 dns_geoip_countrycode3, "CAN");
686 assert_true(match);
687
688 match = do_lookup_string("10.53.0.4", NULL,
689 dns_geoip_countryname, "Canada");
690 assert_true(match);
691
692 GeoIP_delete(geoip.region);
693 geoip.region = NULL;
694
695 match = do_lookup_string("10.53.0.4", NULL,
696 dns_geoip_countrycode, "CA");
697 assert_true(match);
698
699 match = do_lookup_string("10.53.0.4", NULL,
700 dns_geoip_countrycode3, "CAN");
701 assert_true(match);
702
703 match = do_lookup_string("10.53.0.4", NULL,
704 dns_geoip_countryname, "Canada");
705 assert_true(match);
706 }
707 #endif /* HAVE_GEOIP */
708
709 int
main(void)710 main(void) {
711 #if defined(HAVE_GEOIP) || defined(HAVE_GEOIP2)
712 const struct CMUnitTest tests[] = {
713 #ifdef HAVE_GEOIP2
714 cmocka_unit_test_setup_teardown(baseline, _setup, _teardown),
715 #endif /* HAVE_GEOIP2 */
716 cmocka_unit_test_setup_teardown(country, _setup, _teardown),
717 cmocka_unit_test_setup_teardown(country_v6, _setup, _teardown),
718 cmocka_unit_test_setup_teardown(city, _setup, _teardown),
719 cmocka_unit_test_setup_teardown(city_v6, _setup, _teardown),
720 cmocka_unit_test_setup_teardown(asnum, _setup, _teardown),
721 cmocka_unit_test_setup_teardown(isp, _setup, _teardown),
722 cmocka_unit_test_setup_teardown(org, _setup, _teardown),
723 cmocka_unit_test_setup_teardown(domain, _setup, _teardown),
724 #ifdef HAVE_GEOIP
725 cmocka_unit_test_setup_teardown(region, _setup, _teardown),
726 cmocka_unit_test_setup_teardown(netspeed, _setup, _teardown),
727 cmocka_unit_test_setup_teardown(best, _setup, _teardown),
728 #endif /* HAVE_GEOIP */
729 };
730
731 return (cmocka_run_group_tests(tests, dns_test_init, dns_test_final));
732 #else
733 print_message("1..0 # Skip GeoIP not enabled\n");
734 #endif
735 }
736
737 #else /* HAVE_CMOCKA */
738
739 #include <stdio.h>
740
741 int
main(void)742 main(void) {
743 printf("1..0 # Skipped: cmocka not available\n");
744 return (0);
745 }
746
747 #endif /* HAVE_CMOCKA */
748