]> git.ipfire.org Git - people/ms/libloc.git/blame - src/test-network.c
importer: Drop EDROP as it has been merged into DROP
[people/ms/libloc.git] / src / test-network.c
CommitLineData
3b5f4af2
MT
1/*
2 libloc - A library to determine the location of someone on the Internet
3
4 Copyright (C) 2017 IPFire Development Team <info@ipfire.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15*/
16
fc692a58 17#include <arpa/inet.h>
f3e02bc5 18#include <errno.h>
3b5f4af2
MT
19#include <stdio.h>
20#include <stddef.h>
21#include <stdlib.h>
22#include <string.h>
37317e4f 23#include <syslog.h>
3b5f4af2 24
c12a1385 25#include <libloc/libloc.h>
0b1fef38 26#include <libloc/address.h>
c12a1385
MT
27#include <libloc/database.h>
28#include <libloc/network.h>
f69e0c8b 29#include <libloc/private.h>
c12a1385 30#include <libloc/writer.h>
3b5f4af2 31
8da88dda
MT
32static int test_reverse_pointers(struct loc_ctx* ctx) {
33 const struct test {
34 const char* network;
35 const char* rp;
36 } tests[] = {
37 // IPv6
38 { "::1/128", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." },
39 { "2001:db8::/32", "*.8.b.d.0.1.0.0.2.ip6.arpa." },
40
41 // IPv4
42 { "10.0.0.0/32", "0.0.0.10.in-addr.arpa." },
43 { "10.0.0.0/24", "*.0.0.10.in-addr.arpa." },
44 { "10.0.0.0/16", "*.0.10.in-addr.arpa." },
45 { "10.0.0.0/8", "*.10.in-addr.arpa." },
46 { "10.0.0.0/0", "*.in-addr.arpa." },
47 { "10.0.0.0/1", NULL, },
48 { NULL, NULL },
49 };
50
51 struct loc_network* network = NULL;
52 char* rp = NULL;
53 int r;
54
55 for (const struct test* test = tests; test->network; test++) {
56 // Create a new network
57 r = loc_network_new_from_string(ctx, &network, test->network);
58 if (r)
59 return r;
60
61 // Fetch the reverse pointer
62 rp = loc_network_reverse_pointer(network, NULL);
63
64 // No RP expected and got none
65 if (!test->rp && !rp)
66 continue;
67
68 // Got a result when expecting none
69 else if (!test->rp && rp) {
70 fprintf(stderr, "Got an RP for %s when expecting none\n", test->network);
71 return EXIT_FAILURE;
72
73 // Got nothing when expecting a result
74 } else if (test->rp && !rp) {
75 fprintf(stderr, "Got no RP for %s when expecting one\n", test->network);
76 return EXIT_FAILURE;
77
78 // Compare values
79 } else if (strcmp(test->rp, rp) != 0) {
80 fprintf(stderr, "Got an unexpected RP for %s: Got %s, expected %s\n",
81 test->network, rp, test->rp);
82 return EXIT_FAILURE;
83 }
84
85 loc_network_unref(network);
86 if (rp)
87 free(rp);
88 }
89
90 return 0;
91}
92
3b5f4af2
MT
93int main(int argc, char** argv) {
94 int err;
95
96 struct loc_ctx* ctx;
97 err = loc_new(&ctx);
98 if (err < 0)
99 exit(EXIT_FAILURE);
100
37317e4f
MT
101 // Enable debug logging
102 loc_set_log_priority(ctx, LOG_DEBUG);
103
7933f5bf 104#if 0
3b5f4af2
MT
105 struct loc_network_tree* tree;
106 err = loc_network_tree_new(ctx, &tree);
107 if (err) {
108 fprintf(stderr, "Could not create the network tree\n");
109 exit(EXIT_FAILURE);
110 }
7933f5bf 111#endif
3b5f4af2 112
fc692a58
MT
113 struct in6_addr address;
114 err = inet_pton(AF_INET6, "2001:db8::1", &address);
115 if (err != 1) {
116 fprintf(stderr, "Could not parse IP address\n");
117 exit(EXIT_FAILURE);
118 }
119
3b5f4af2
MT
120 // Create a network
121 struct loc_network* network1;
2b9338ea 122 err = loc_network_new_from_string(ctx, &network1, "2001:db8::1/32");
3b5f4af2
MT
123 if (err) {
124 fprintf(stderr, "Could not create the network\n");
125 exit(EXIT_FAILURE);
126 }
127
e8ebd079 128 err = loc_network_set_country_code(network1, "DE");
3b5f4af2
MT
129 if (err) {
130 fprintf(stderr, "Could not set country code\n");
131 exit(EXIT_FAILURE);
132 }
133
7933f5bf 134#if 0
3b5f4af2
MT
135 // Adding network to the tree
136 err = loc_network_tree_add_network(tree, network1);
137 if (err) {
138 fprintf(stderr, "Could not add network to the tree\n");
139 exit(EXIT_FAILURE);
140 }
7933f5bf 141#endif
3b5f4af2 142
2b9338ea 143 // Check if the first and last addresses are correct
0a0a289a 144 const char* string = loc_network_format_first_address(network1);
2b9338ea
MT
145 if (!string) {
146 fprintf(stderr, "Did get NULL instead of a string for the first address\n");
147 exit(EXIT_FAILURE);
148 }
149
150 if (strcmp(string, "2001:db8::") != 0) {
151 fprintf(stderr, "Got an incorrect first address: %s\n", string);
152 exit(EXIT_FAILURE);
153 }
154
155 string = loc_network_format_last_address(network1);
156 if (!string) {
157 fprintf(stderr, "Did get NULL instead of a string for the last address\n");
158 exit(EXIT_FAILURE);
159 }
160
161 if (strcmp(string, "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff") != 0) {
162 fprintf(stderr, "Got an incorrect last address: %s\n", string);
163 exit(EXIT_FAILURE);
164 }
165
0258d3c9 166 err = loc_network_matches_address(network1, &address);
fc692a58
MT
167 if (!err) {
168 fprintf(stderr, "Network1 does not match address\n");
169 exit(EXIT_FAILURE);
170 }
171
c051bfad
MT
172 struct loc_network* network2;
173 err = loc_network_new_from_string(ctx, &network2, "2001:db8:ffff::/48");
174 if (err) {
175 fprintf(stderr, "Could not create the network\n");
176 exit(EXIT_FAILURE);
177 }
178
e8ebd079 179 err = loc_network_set_country_code(network2, "DE");
c051bfad
MT
180 if (err) {
181 fprintf(stderr, "Could not set country code\n");
182 exit(EXIT_FAILURE);
183 }
184
7933f5bf 185#if 0
c051bfad
MT
186 // Adding network to the tree
187 err = loc_network_tree_add_network(tree, network2);
188 if (err) {
189 fprintf(stderr, "Could not add network to the tree\n");
190 exit(EXIT_FAILURE);
191 }
192
3b5f4af2
MT
193 // Dump the tree
194 err = loc_network_tree_dump(tree);
195 if (err) {
196 fprintf(stderr, "Error dumping tree: %d\n", err);
197 exit(EXIT_FAILURE);
198 }
199
940f9c2b
MT
200 size_t nodes = loc_network_tree_count_nodes(tree);
201 printf("The tree has %zu nodes\n", nodes);
7933f5bf 202#endif
940f9c2b 203
850e7516 204 // Check equals function
da101d55
MT
205 err = loc_network_cmp(network1, network1);
206 if (err) {
850e7516
MT
207 fprintf(stderr, "Network is not equal with itself\n");
208 exit(EXIT_FAILURE);
209 }
210
da101d55
MT
211 err = loc_network_cmp(network1, network2);
212 if (!err) {
850e7516
MT
213 fprintf(stderr, "Networks equal unexpectedly\n");
214 exit(EXIT_FAILURE);
215 }
216
43554dc4 217 // Check subnet function
a5967330
MT
218 err = loc_network_is_subnet(network1, network2);
219 if (!err) {
43554dc4
MT
220 fprintf(stderr, "Subnet check 1 failed: %d\n", err);
221 exit(EXIT_FAILURE);
222 }
223
a5967330
MT
224 err = loc_network_is_subnet(network2, network1);
225 if (err) {
43554dc4
MT
226 fprintf(stderr, "Subnet check 2 failed: %d\n", err);
227 exit(EXIT_FAILURE);
228 }
229
a5967330
MT
230 // Make subnets
231 struct loc_network* subnet1 = NULL;
232 struct loc_network* subnet2 = NULL;
233
234 err = loc_network_subnets(network1, &subnet1, &subnet2);
235 if (err || !subnet1 || !subnet2) {
236 fprintf(stderr, "Could not find subnets of network: %d\n", err);
850e7516
MT
237 exit(EXIT_FAILURE);
238 }
239
0a0a289a 240 const char* s = loc_network_str(subnet1);
a5967330 241 printf("Received subnet1 = %s\n", s);
850e7516 242
a5967330
MT
243 s = loc_network_str(subnet2);
244 printf("Received subnet2 = %s\n", s);
850e7516 245
a5967330
MT
246 if (!loc_network_is_subnet(network1, subnet1)) {
247 fprintf(stderr, "Subnet1 is not a subnet\n");
248 exit(EXIT_FAILURE);
249 }
850e7516 250
a5967330
MT
251 if (!loc_network_is_subnet(network1, subnet2)) {
252 fprintf(stderr, "Subnet2 is not a subnet\n");
253 exit(EXIT_FAILURE);
850e7516
MT
254 }
255
82fa4c92
MT
256 if (!loc_network_overlaps(network1, subnet1)) {
257 fprintf(stderr, "Network1 does not seem to contain subnet1\n");
258 exit(EXIT_FAILURE);
259 }
260
261 if (!loc_network_overlaps(network1, subnet2)) {
262 fprintf(stderr, "Network1 does not seem to contain subnet2\n");
263 exit(EXIT_FAILURE);
264 }
265
a5967330
MT
266 loc_network_unref(subnet1);
267 loc_network_unref(subnet2);
850e7516
MT
268
269 struct loc_network_list* excluded = loc_network_exclude(network1, network2);
270 if (!excluded) {
271 fprintf(stderr, "Could not create excluded list\n");
272 exit(EXIT_FAILURE);
273 }
274
275 loc_network_list_dump(excluded);
850e7516
MT
276 loc_network_list_unref(excluded);
277
f3e02bc5
MT
278 // Create a database
279 struct loc_writer* writer;
5ce881d4 280 err = loc_writer_new(ctx, &writer, NULL, NULL);
f3e02bc5
MT
281 if (err < 0)
282 exit(EXIT_FAILURE);
283
c051bfad 284 struct loc_network* network3;
83a5d737 285 err = loc_writer_add_network(writer, &network3, "2001:db8::/64");
f3e02bc5
MT
286 if (err) {
287 fprintf(stderr, "Could not add network\n");
288 exit(EXIT_FAILURE);
289 }
290
291 // Set country code
c051bfad 292 loc_network_set_country_code(network3, "XX");
f3e02bc5 293
83a5d737
MT
294 struct loc_network* network4;
295 err = loc_writer_add_network(writer, &network4, "2001:db8:ffff::/64");
296 if (err) {
297 fprintf(stderr, "Could not add network\n");
298 exit(EXIT_FAILURE);
299 }
300
301 // Set country code
302 loc_network_set_country_code(network4, "XY");
303
9a339aa0
MT
304 // Set ASN
305 loc_network_set_asn(network4, 1024);
306
0f1aedbc
MT
307 // Try adding an invalid network
308 struct loc_network* network;
309 err = loc_writer_add_network(writer, &network, "xxxx:xxxx::/32");
95b6a8e4 310 if (!err) {
0f1aedbc
MT
311 fprintf(stderr, "It was possible to add an invalid network (err = %d)\n", err);
312 exit(EXIT_FAILURE);
313 }
314
13ad6e69
MT
315 // Try adding a single address
316 err = loc_writer_add_network(writer, &network, "2001:db8::");
26ab419b
MT
317 if (err) {
318 fprintf(stderr, "It was impossible to add an single IP address (err = %d)\n", err);
13ad6e69 319 exit(EXIT_FAILURE);
6a467e93
MT
320 }
321
6254dca6 322 FILE* f = tmpfile();
f3e02bc5 323 if (!f) {
6cd02f1d 324 fprintf(stderr, "Could not open file for writing: %m\n");
f3e02bc5
MT
325 exit(EXIT_FAILURE);
326 }
327
22c7b98b 328 err = loc_writer_write(writer, f, LOC_DATABASE_VERSION_UNSET);
f3e02bc5 329 if (err) {
198e382c 330 fprintf(stderr, "Could not write database: %m\n");
f3e02bc5
MT
331 exit(EXIT_FAILURE);
332 }
f3e02bc5
MT
333 loc_writer_unref(writer);
334
3b5f4af2 335 loc_network_unref(network1);
c051bfad
MT
336 loc_network_unref(network2);
337 loc_network_unref(network3);
83a5d737 338 loc_network_unref(network4);
7933f5bf
MT
339
340#if 0
3b5f4af2 341 loc_network_tree_unref(tree);
7933f5bf 342#endif
2a30e4de
MT
343
344 // And open it again from disk
2a30e4de
MT
345 struct loc_database* db;
346 err = loc_database_new(ctx, &db, f);
347 if (err) {
198e382c 348 fprintf(stderr, "Could not open database: %m\n");
2a30e4de
MT
349 exit(EXIT_FAILURE);
350 }
351
e477e813 352 // Lookup an address in the subnet
2a30e4de
MT
353 err = loc_database_lookup_from_string(db, "2001:db8::", &network1);
354 if (err) {
e477e813 355 fprintf(stderr, "Could not look up 2001:db8::\n");
2a30e4de
MT
356 exit(EXIT_FAILURE);
357 }
358 loc_network_unref(network1);
359
e477e813 360 // Lookup an address outside the subnet
2a30e4de 361 err = loc_database_lookup_from_string(db, "2001:db8:fffe:1::", &network1);
e477e813
MT
362 if (err == 0) {
363 fprintf(stderr, "Could look up 2001:db8:fffe:1::, but I shouldn't\n");
2a30e4de
MT
364 exit(EXIT_FAILURE);
365 }
2a30e4de 366
f69e0c8b
MT
367 const struct bit_length_test {
368 const char* network;
369 unsigned int bit_length;
370 } bit_length_tests[] = {
371 { "::/0", 0 },
23ece648
MT
372 { "2001::/128", 16 },
373 { "1.0.0.0/32", 8 },
374 { "0.0.0.1/32", 32 },
b074be0b 375 { "255.255.255.255/32", 32 },
f69e0c8b
MT
376 { NULL, 0, },
377 };
378
379 for (const struct bit_length_test* t = bit_length_tests; t->network; t++) {
380 err = loc_network_new_from_string(ctx, &network1, t->network);
381 if (err) {
382 fprintf(stderr, "Could not create network %s: %m\n", t->network);
383 exit(EXIT_FAILURE);
384 }
385
386 const struct in6_addr* addr = loc_network_get_first_address(network1);
387
388 unsigned int bit_length = loc_address_bit_length(addr);
389
390 if (bit_length != t->bit_length) {
391 printf("Bit length of %s didn't match: %u != %u\n",
392 t->network, t->bit_length, bit_length);
393 loc_network_unref(network1);
394 exit(EXIT_FAILURE);
395 }
396
397 loc_network_unref(network1);
398 }
399
8da88dda
MT
400 // Test reverse pointers
401 err = test_reverse_pointers(ctx);
402 if (err)
403 exit(err);
404
3b5f4af2 405 loc_unref(ctx);
6254dca6 406 fclose(f);
3b5f4af2
MT
407
408 return EXIT_SUCCESS;
409}