]> git.ipfire.org Git - people/ms/libloc.git/blame - src/perl/Location.xs
importer: Drop EDROP as it has been merged into DROP
[people/ms/libloc.git] / src / perl / Location.xs
CommitLineData
1ea740e9
SS
1#define PERL_NO_GET_CONTEXT
2#include "EXTERN.h"
3#include "perl.h"
4#include "XSUB.h"
5
6#include <stdio.h>
7#include <string.h>
8
c12a1385
MT
9#include <libloc/libloc.h>
10#include <libloc/database.h>
11#include <libloc/network.h>
12#include <libloc/country.h>
1ea740e9
SS
13
14MODULE = Location PACKAGE = Location
15
16struct loc_database *
3bbf013a 17init(file)
e5a1a0bd 18 char* file;
1ea740e9
SS
19
20 CODE:
da1039da 21 struct loc_ctx* ctx = NULL;
1ea740e9 22
74ad091d 23 // Initialise location context
da1039da 24 int err = loc_new(&ctx);
1ea740e9 25 if (err < 0)
5242283a 26 croak("Could not initialize libloc context: %d\n", err);
1ea740e9 27
74ad091d 28 // Open the database file for reading
1ea740e9
SS
29 FILE* f = fopen(file, "r");
30 if (!f) {
c820094d
MT
31 loc_unref(ctx);
32
5242283a
MT
33 croak("Could not open file for reading: %s: %s\n",
34 file, strerror(errno));
1ea740e9
SS
35 }
36
74ad091d 37 // Parse the database
c820094d 38 struct loc_database* db = NULL;
1ea740e9 39 err = loc_database_new(ctx, &db, f);
46d6c767
MT
40
41 // We can close the database file straight away
42 // because loc_database_new creates a copy of the file descriptor
43 fclose(f);
44
1ea740e9 45 if (err) {
c820094d
MT
46 loc_unref(ctx);
47
5242283a 48 croak("Could not read database: %s\n", file);
1ea740e9
SS
49 }
50
3bbf013a
MT
51 // Cleanup
52 loc_unref(ctx);
53
54 RETVAL = db;
55 OUTPUT:
56 RETVAL
57
58#
59# Database functions
60#
61bool
62verify(db, keyfile)
63 struct loc_database* db;
64 char* keyfile;
65
66 CODE:
2061ff77 67 // Try to open the keyfile
3bbf013a 68 FILE* f = fopen(keyfile, "r");
2061ff77 69 if (!f) {
2061ff77
SS
70 croak("Could not open keyfile %s: %s\n",
71 keyfile, strerror(errno));
72 }
73
74 // Verify the database
75 int status = loc_database_verify(db, f);
76 if (status) {
3bbf013a 77 RETVAL = false;
2061ff77
SS
78 fclose(f);
79
80 croak("Could not verify the database signature\n");
81 }
82
3bbf013a
MT
83 // Database was validated successfully
84 RETVAL = true;
85
2061ff77
SS
86 // Close the keyfile
87 fclose(f);
1ea740e9
SS
88 OUTPUT:
89 RETVAL
90
777959b2
MT
91const char*
92get_vendor(db)
93 struct loc_database* db;
94
95 CODE:
96 // Get vendor
97 RETVAL = loc_database_get_vendor(db);
98 OUTPUT:
99 RETVAL
100
973c5f03
SS
101const char*
102get_description(db)
103 struct loc_database* db;
104
105 CODE:
106 // Get database description
107 RETVAL = loc_database_get_description(db);
108 OUTPUT:
109 RETVAL
110
733bd087
SS
111const char*
112get_license(db)
113 struct loc_database* db;
114
115 CODE:
116 // Get database license
117 RETVAL = loc_database_get_license(db);
118 OUTPUT:
119 RETVAL
120
c1590ddd
SS
121void
122database_countries(db)
123 struct loc_database* db;
124
125 PPCODE:
126 // Create Database enumerator
127 struct loc_database_enumerator* enumerator;
681ff05c 128 int err = loc_database_enumerator_new(&enumerator, db, LOC_DB_ENUMERATE_COUNTRIES, 0);
c1590ddd
SS
129
130 if (err) {
131 croak("Could not create a database enumerator\n");
132 }
133
134 // Init and enumerate first country.
135 struct loc_country* country;
136 err = loc_database_enumerator_next_country(enumerator, &country);
137 if (err) {
138 croak("Could not enumerate next country\n");
139 }
140
141 while (country) {
142 // Extract the country code.
143 const char* ccode = loc_country_get_code(country);
144
145 // Push country code.
146 XPUSHs(sv_2mortal(newSVpv(ccode, 2)));
147
148 // Unref country pointer.
149 loc_country_unref(country);
150
151 // Enumerate next item.
152 err = loc_database_enumerator_next_country(enumerator, &country);
153 if (err) {
154 croak("Could not enumerate next country\n");
155 }
156 }
157
158 loc_database_enumerator_unref(enumerator);
159
46fbc975
SS
160#
161# Lookup functions
162#
6aa97cac 163SV*
70f45781 164lookup_country_code(db, address)
e5a1a0bd
MT
165 struct loc_database* db;
166 char* address;
1ea740e9
SS
167
168 CODE:
6aa97cac
SS
169 RETVAL = &PL_sv_undef;
170
74ad091d 171 // Lookup network
1ea740e9 172 struct loc_network *network;
d3daf87c 173 int err = loc_database_lookup_from_string(db, address, &network);
6aa97cac
SS
174 if (!err) {
175 // Extract the country code
176 const char* country_code = loc_network_get_country_code(network);
177 RETVAL = newSVpv(country_code, strlen(country_code));
1ea740e9 178
6aa97cac 179 loc_network_unref(network);
1ea740e9 180 }
1ea740e9
SS
181 OUTPUT:
182 RETVAL
183
c8e6ee4e
SS
184bool
185lookup_network_has_flag(db, address, flag)
186 struct loc_database* db;
187 char* address;
188 char* flag;
189
190 CODE:
191 RETVAL = false;
192
193 enum loc_network_flags iv = 0;
194
195 if (strcmp("LOC_NETWORK_FLAG_ANONYMOUS_PROXY", flag) == 0)
196 iv |= LOC_NETWORK_FLAG_ANONYMOUS_PROXY;
197 else if (strcmp("LOC_NETWORK_FLAG_SATELLITE_PROVIDER", flag) == 0)
198 iv |= LOC_NETWORK_FLAG_SATELLITE_PROVIDER;
199 else if (strcmp("LOC_NETWORK_FLAG_ANYCAST", flag) == 0)
200 iv |= LOC_NETWORK_FLAG_ANYCAST;
e17e804e
PM
201 else if (strcmp("LOC_NETWORK_FLAG_DROP", flag) == 0)
202 iv |= LOC_NETWORK_FLAG_DROP;
c8e6ee4e
SS
203 else
204 croak("Invalid flag");
205
206 // Lookup network
207 struct loc_network *network;
208 int err = loc_database_lookup_from_string(db, address, &network);
209
210 if (!err) {
211 // Check if the network has the given flag.
212 if (loc_network_has_flag(network, iv)) {
213 RETVAL = true;
214 }
215
216 loc_network_unref(network);
217 }
218
219 OUTPUT:
220 RETVAL
221
8d4f5f67
SS
222SV*
223lookup_asn(db, address)
224 struct loc_database* db;
225 char* address;
226
227 CODE:
228 RETVAL = &PL_sv_undef;
229
230 // Lookup network
231 struct loc_network *network;
232 int err = loc_database_lookup_from_string(db, address, &network);
233 if (!err) {
234 // Extract the ASN
235 unsigned int as_number = loc_network_get_asn(network);
236 if (as_number > 0) {
237 RETVAL = newSViv(as_number);
238 }
239
240 loc_network_unref(network);
241 }
242 OUTPUT:
243 RETVAL
244
cd022c5f
SS
245#
246# Get functions
247#
201bfcd9
SS
248SV*
249get_country_name(db, ccode)
250 struct loc_database* db;
251 char* ccode;
252
253 CODE:
254 RETVAL = &PL_sv_undef;
255
256 // Lookup country code
257 struct loc_country *country;
258 int err = loc_database_get_country(db, &country, ccode);
259 if(!err) {
260 // Extract the name for the given country code.
261 const char* country_name = loc_country_get_name(country);
262 RETVAL = newSVpv(country_name, strlen(country_name));
263
264 loc_country_unref(country);
265 }
266
267 OUTPUT:
268 RETVAL
269
cd022c5f
SS
270SV*
271get_continent_code(db, ccode)
272 struct loc_database* db;
273 char* ccode;
274
275 CODE:
276 RETVAL = &PL_sv_undef;
277
278 // Lookup country code
279 struct loc_country *country;
280 int err = loc_database_get_country(db, &country, ccode);
281 if(!err) {
282 //Extract the continent code for the given country code.
283 const char* continent_code = loc_country_get_continent_code(country);
284 RETVAL = newSVpv(continent_code, strlen(continent_code));
285
286 loc_country_unref(country);
287 }
288
289 OUTPUT:
290 RETVAL
291
30c8e528
SS
292SV*
293get_as_name(db, as_number)
294 struct loc_database* db;
295 unsigned int as_number;
296
297 CODE:
298 RETVAL = &PL_sv_undef;
299
300 // Lookup AS.
301 struct loc_as *as;
302 int err = loc_database_get_as(db, &as, as_number);
303 if(!err) {
304 // Get the name of the given AS number.
305 const char* as_name = loc_as_get_name(as);
306
307 RETVAL = newSVpv(as_name, strlen(as_name));
308
309 loc_as_unref(as);
310 }
311
312 OUTPUT:
313 RETVAL
314
1ea740e9
SS
315void
316DESTROY(db)
34eed014 317 struct loc_database* db;
da1039da 318
1ea740e9 319 CODE:
74ad091d 320 // Close database
1ea740e9 321 loc_database_unref(db);