]> git.ipfire.org Git - people/ms/libloc.git/blame - src/test-network.c
network: Pass prefix in native length
[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
MT
31
32int main(int argc, char** argv) {
33 int err;
34
35 struct loc_ctx* ctx;
36 err = loc_new(&ctx);
37 if (err < 0)
38 exit(EXIT_FAILURE);
39
37317e4f
MT
40 // Enable debug logging
41 loc_set_log_priority(ctx, LOG_DEBUG);
42
7933f5bf 43#if 0
3b5f4af2
MT
44 struct loc_network_tree* tree;
45 err = loc_network_tree_new(ctx, &tree);
46 if (err) {
47 fprintf(stderr, "Could not create the network tree\n");
48 exit(EXIT_FAILURE);
49 }
7933f5bf 50#endif
3b5f4af2 51
fc692a58
MT
52 struct in6_addr address;
53 err = inet_pton(AF_INET6, "2001:db8::1", &address);
54 if (err != 1) {
55 fprintf(stderr, "Could not parse IP address\n");
56 exit(EXIT_FAILURE);
57 }
58
3b5f4af2
MT
59 // Create a network
60 struct loc_network* network1;
2b9338ea 61 err = loc_network_new_from_string(ctx, &network1, "2001:db8::1/32");
3b5f4af2
MT
62 if (err) {
63 fprintf(stderr, "Could not create the network\n");
64 exit(EXIT_FAILURE);
65 }
66
e8ebd079 67 err = loc_network_set_country_code(network1, "DE");
3b5f4af2
MT
68 if (err) {
69 fprintf(stderr, "Could not set country code\n");
70 exit(EXIT_FAILURE);
71 }
72
7933f5bf 73#if 0
3b5f4af2
MT
74 // Adding network to the tree
75 err = loc_network_tree_add_network(tree, network1);
76 if (err) {
77 fprintf(stderr, "Could not add network to the tree\n");
78 exit(EXIT_FAILURE);
79 }
7933f5bf 80#endif
3b5f4af2 81
2b9338ea
MT
82 // Check if the first and last addresses are correct
83 char* string = loc_network_format_first_address(network1);
84 if (!string) {
85 fprintf(stderr, "Did get NULL instead of a string for the first address\n");
86 exit(EXIT_FAILURE);
87 }
88
89 if (strcmp(string, "2001:db8::") != 0) {
90 fprintf(stderr, "Got an incorrect first address: %s\n", string);
91 exit(EXIT_FAILURE);
92 }
93
94 string = loc_network_format_last_address(network1);
95 if (!string) {
96 fprintf(stderr, "Did get NULL instead of a string for the last address\n");
97 exit(EXIT_FAILURE);
98 }
99
100 if (strcmp(string, "2001:db8:ffff:ffff:ffff:ffff:ffff:ffff") != 0) {
101 fprintf(stderr, "Got an incorrect last address: %s\n", string);
102 exit(EXIT_FAILURE);
103 }
104
0258d3c9 105 err = loc_network_matches_address(network1, &address);
fc692a58
MT
106 if (!err) {
107 fprintf(stderr, "Network1 does not match address\n");
108 exit(EXIT_FAILURE);
109 }
110
c051bfad
MT
111 struct loc_network* network2;
112 err = loc_network_new_from_string(ctx, &network2, "2001:db8:ffff::/48");
113 if (err) {
114 fprintf(stderr, "Could not create the network\n");
115 exit(EXIT_FAILURE);
116 }
117
e8ebd079 118 err = loc_network_set_country_code(network2, "DE");
c051bfad
MT
119 if (err) {
120 fprintf(stderr, "Could not set country code\n");
121 exit(EXIT_FAILURE);
122 }
123
7933f5bf 124#if 0
c051bfad
MT
125 // Adding network to the tree
126 err = loc_network_tree_add_network(tree, network2);
127 if (err) {
128 fprintf(stderr, "Could not add network to the tree\n");
129 exit(EXIT_FAILURE);
130 }
131
3b5f4af2
MT
132 // Dump the tree
133 err = loc_network_tree_dump(tree);
134 if (err) {
135 fprintf(stderr, "Error dumping tree: %d\n", err);
136 exit(EXIT_FAILURE);
137 }
138
940f9c2b
MT
139 size_t nodes = loc_network_tree_count_nodes(tree);
140 printf("The tree has %zu nodes\n", nodes);
7933f5bf 141#endif
940f9c2b 142
850e7516 143 // Check equals function
da101d55
MT
144 err = loc_network_cmp(network1, network1);
145 if (err) {
850e7516
MT
146 fprintf(stderr, "Network is not equal with itself\n");
147 exit(EXIT_FAILURE);
148 }
149
da101d55
MT
150 err = loc_network_cmp(network1, network2);
151 if (!err) {
850e7516
MT
152 fprintf(stderr, "Networks equal unexpectedly\n");
153 exit(EXIT_FAILURE);
154 }
155
43554dc4 156 // Check subnet function
a5967330
MT
157 err = loc_network_is_subnet(network1, network2);
158 if (!err) {
43554dc4
MT
159 fprintf(stderr, "Subnet check 1 failed: %d\n", err);
160 exit(EXIT_FAILURE);
161 }
162
a5967330
MT
163 err = loc_network_is_subnet(network2, network1);
164 if (err) {
43554dc4
MT
165 fprintf(stderr, "Subnet check 2 failed: %d\n", err);
166 exit(EXIT_FAILURE);
167 }
168
a5967330
MT
169 // Make subnets
170 struct loc_network* subnet1 = NULL;
171 struct loc_network* subnet2 = NULL;
172
173 err = loc_network_subnets(network1, &subnet1, &subnet2);
174 if (err || !subnet1 || !subnet2) {
175 fprintf(stderr, "Could not find subnets of network: %d\n", err);
850e7516
MT
176 exit(EXIT_FAILURE);
177 }
178
a5967330
MT
179 char* s = loc_network_str(subnet1);
180 printf("Received subnet1 = %s\n", s);
181 free(s);
850e7516 182
a5967330
MT
183 s = loc_network_str(subnet2);
184 printf("Received subnet2 = %s\n", s);
185 free(s);
850e7516 186
a5967330
MT
187 if (!loc_network_is_subnet(network1, subnet1)) {
188 fprintf(stderr, "Subnet1 is not a subnet\n");
189 exit(EXIT_FAILURE);
190 }
850e7516 191
a5967330
MT
192 if (!loc_network_is_subnet(network1, subnet2)) {
193 fprintf(stderr, "Subnet2 is not a subnet\n");
194 exit(EXIT_FAILURE);
850e7516
MT
195 }
196
82fa4c92
MT
197 if (!loc_network_overlaps(network1, subnet1)) {
198 fprintf(stderr, "Network1 does not seem to contain subnet1\n");
199 exit(EXIT_FAILURE);
200 }
201
202 if (!loc_network_overlaps(network1, subnet2)) {
203 fprintf(stderr, "Network1 does not seem to contain subnet2\n");
204 exit(EXIT_FAILURE);
205 }
206
a5967330
MT
207 loc_network_unref(subnet1);
208 loc_network_unref(subnet2);
850e7516
MT
209
210 struct loc_network_list* excluded = loc_network_exclude(network1, network2);
211 if (!excluded) {
212 fprintf(stderr, "Could not create excluded list\n");
213 exit(EXIT_FAILURE);
214 }
215
216 loc_network_list_dump(excluded);
850e7516
MT
217 loc_network_list_unref(excluded);
218
f3e02bc5
MT
219 // Create a database
220 struct loc_writer* writer;
5ce881d4 221 err = loc_writer_new(ctx, &writer, NULL, NULL);
f3e02bc5
MT
222 if (err < 0)
223 exit(EXIT_FAILURE);
224
c051bfad 225 struct loc_network* network3;
83a5d737 226 err = loc_writer_add_network(writer, &network3, "2001:db8::/64");
f3e02bc5
MT
227 if (err) {
228 fprintf(stderr, "Could not add network\n");
229 exit(EXIT_FAILURE);
230 }
231
232 // Set country code
c051bfad 233 loc_network_set_country_code(network3, "XX");
f3e02bc5 234
83a5d737
MT
235 struct loc_network* network4;
236 err = loc_writer_add_network(writer, &network4, "2001:db8:ffff::/64");
237 if (err) {
238 fprintf(stderr, "Could not add network\n");
239 exit(EXIT_FAILURE);
240 }
241
242 // Set country code
243 loc_network_set_country_code(network4, "XY");
244
9a339aa0
MT
245 // Set ASN
246 loc_network_set_asn(network4, 1024);
247
0f1aedbc
MT
248 // Try adding an invalid network
249 struct loc_network* network;
250 err = loc_writer_add_network(writer, &network, "xxxx:xxxx::/32");
251 if (err != -EINVAL) {
252 fprintf(stderr, "It was possible to add an invalid network (err = %d)\n", err);
253 exit(EXIT_FAILURE);
254 }
255
13ad6e69
MT
256 // Try adding a single address
257 err = loc_writer_add_network(writer, &network, "2001:db8::");
26ab419b
MT
258 if (err) {
259 fprintf(stderr, "It was impossible to add an single IP address (err = %d)\n", err);
13ad6e69 260 exit(EXIT_FAILURE);
6a467e93
MT
261 }
262
6254dca6 263 FILE* f = tmpfile();
f3e02bc5
MT
264 if (!f) {
265 fprintf(stderr, "Could not open file for writing: %s\n", strerror(errno));
266 exit(EXIT_FAILURE);
267 }
268
22c7b98b 269 err = loc_writer_write(writer, f, LOC_DATABASE_VERSION_UNSET);
f3e02bc5
MT
270 if (err) {
271 fprintf(stderr, "Could not write database: %s\n", strerror(-err));
272 exit(EXIT_FAILURE);
273 }
f3e02bc5
MT
274 loc_writer_unref(writer);
275
3b5f4af2 276 loc_network_unref(network1);
c051bfad
MT
277 loc_network_unref(network2);
278 loc_network_unref(network3);
83a5d737 279 loc_network_unref(network4);
7933f5bf
MT
280
281#if 0
3b5f4af2 282 loc_network_tree_unref(tree);
7933f5bf 283#endif
2a30e4de
MT
284
285 // And open it again from disk
2a30e4de
MT
286 struct loc_database* db;
287 err = loc_database_new(ctx, &db, f);
288 if (err) {
289 fprintf(stderr, "Could not open database: %s\n", strerror(-err));
290 exit(EXIT_FAILURE);
291 }
292
e477e813 293 // Lookup an address in the subnet
2a30e4de
MT
294 err = loc_database_lookup_from_string(db, "2001:db8::", &network1);
295 if (err) {
e477e813 296 fprintf(stderr, "Could not look up 2001:db8::\n");
2a30e4de
MT
297 exit(EXIT_FAILURE);
298 }
299 loc_network_unref(network1);
300
e477e813 301 // Lookup an address outside the subnet
2a30e4de 302 err = loc_database_lookup_from_string(db, "2001:db8:fffe:1::", &network1);
e477e813
MT
303 if (err == 0) {
304 fprintf(stderr, "Could look up 2001:db8:fffe:1::, but I shouldn't\n");
2a30e4de
MT
305 exit(EXIT_FAILURE);
306 }
307 loc_network_unref(network1);
308
f69e0c8b
MT
309 const struct bit_length_test {
310 const char* network;
311 unsigned int bit_length;
312 } bit_length_tests[] = {
313 { "::/0", 0 },
314 { "2001::/128", 126 },
b074be0b
MT
315 { "1.0.0.0/32", 25 },
316 { "255.255.255.255/32", 32 },
f69e0c8b
MT
317 { NULL, 0, },
318 };
319
320 for (const struct bit_length_test* t = bit_length_tests; t->network; t++) {
321 err = loc_network_new_from_string(ctx, &network1, t->network);
322 if (err) {
323 fprintf(stderr, "Could not create network %s: %m\n", t->network);
324 exit(EXIT_FAILURE);
325 }
326
327 const struct in6_addr* addr = loc_network_get_first_address(network1);
328
329 unsigned int bit_length = loc_address_bit_length(addr);
330
331 if (bit_length != t->bit_length) {
332 printf("Bit length of %s didn't match: %u != %u\n",
333 t->network, t->bit_length, bit_length);
334 loc_network_unref(network1);
335 exit(EXIT_FAILURE);
336 }
337
338 loc_network_unref(network1);
339 }
340
3b5f4af2 341 loc_unref(ctx);
6254dca6 342 fclose(f);
3b5f4af2
MT
343
344 return EXIT_SUCCESS;
345}