]> git.ipfire.org Git - location/libloc.git/blobdiff - src/perl/Location.xs
Implement an additional flag for hostile networks safe to drop
[location/libloc.git] / src / perl / Location.xs
index b6c4dc52c53796b7b18d91b2ca8c35bb1d43e6b5..73f85b45ce586f5136b0738f33afa61e95cd5f67 100644 (file)
@@ -6,11 +6,10 @@
 #include <stdio.h>
 #include <string.h>
 
-
 #include <loc/libloc.h>
 #include <loc/database.h>
 #include <loc/network.h>
-
+#include <loc/country.h>
 
 MODULE = Location              PACKAGE = Location
 
@@ -59,6 +58,36 @@ init(file)
 #
 # Database functions
 #
+bool
+verify(db, keyfile)
+       struct loc_database* db;
+       char* keyfile;
+
+       CODE:
+               // Try to open the keyfile
+               FILE* f = fopen(keyfile, "r");
+               if (!f) {
+                       croak("Could not open keyfile %s: %s\n",
+                               keyfile, strerror(errno));
+               }
+
+               // Verify the database
+               int status = loc_database_verify(db, f);
+               if (status) {
+                       RETVAL = false;
+                       fclose(f);
+
+                       croak("Could not verify the database signature\n");
+               }
+
+               // Database was validated successfully
+               RETVAL = true;
+
+               // Close the keyfile
+               fclose(f);
+       OUTPUT:
+               RETVAL
+
 const char*
 get_vendor(db)
        struct loc_database* db;
@@ -89,6 +118,45 @@ get_license(db)
        OUTPUT:
                RETVAL
 
+void
+database_countries(db)
+       struct loc_database* db;
+
+       PPCODE:
+               // Create Database enumerator
+               struct loc_database_enumerator* enumerator;
+               int err = loc_database_enumerator_new(&enumerator, db, LOC_DB_ENUMERATE_COUNTRIES, 0);
+
+               if (err) {
+                       croak("Could not create a database enumerator\n");
+               }
+
+               // Init and enumerate first country.
+               struct loc_country* country;
+               err = loc_database_enumerator_next_country(enumerator, &country);
+               if (err) {
+                       croak("Could not enumerate next country\n");
+               }
+
+               while (country) {
+                       // Extract the country code.
+                       const char* ccode = loc_country_get_code(country);
+
+                       // Push country code.
+                       XPUSHs(sv_2mortal(newSVpv(ccode, 2)));
+
+                       // Unref country pointer.
+                       loc_country_unref(country);
+
+                       // Enumerate next item.
+                       err = loc_database_enumerator_next_country(enumerator, &country);
+                       if (err) {
+                               croak("Could not enumerate next country\n");
+                       }
+               }
+
+               loc_database_enumerator_unref(enumerator);
+
 #
 # Lookup functions
 #
@@ -113,6 +181,44 @@ lookup_country_code(db, address)
        OUTPUT:
                RETVAL
 
+bool
+lookup_network_has_flag(db, address, flag)
+       struct loc_database* db;
+       char* address;
+       char* flag;
+
+       CODE:
+               RETVAL = false;
+
+               enum loc_network_flags iv = 0;
+
+               if (strcmp("LOC_NETWORK_FLAG_ANONYMOUS_PROXY", flag) == 0)
+                       iv |= LOC_NETWORK_FLAG_ANONYMOUS_PROXY;
+               else if (strcmp("LOC_NETWORK_FLAG_SATELLITE_PROVIDER", flag) == 0)
+                       iv |= LOC_NETWORK_FLAG_SATELLITE_PROVIDER;
+               else if (strcmp("LOC_NETWORK_FLAG_ANYCAST", flag) == 0)
+                       iv |= LOC_NETWORK_FLAG_ANYCAST;
+               else if (strcmp("LOC_NETWORK_FLAG_DROP", flag) == 0)
+                       iv |= LOC_NETWORK_FLAG_DROP;
+               else
+                       croak("Invalid flag");
+
+               // Lookup network
+               struct loc_network *network;
+               int err = loc_database_lookup_from_string(db, address, &network);
+
+               if (!err) {
+                       // Check if the network has the given flag.
+                       if (loc_network_has_flag(network, iv)) {
+                               RETVAL = true;
+                       }
+
+                       loc_network_unref(network);
+               }
+
+       OUTPUT:
+               RETVAL
+
 SV*
 lookup_asn(db, address)
        struct loc_database* db;
@@ -136,6 +242,76 @@ lookup_asn(db, address)
        OUTPUT:
                RETVAL
 
+#
+# Get functions
+#
+SV*
+get_country_name(db, ccode)
+       struct loc_database* db;
+       char* ccode;
+
+       CODE:
+               RETVAL = &PL_sv_undef;
+
+               // Lookup country code
+               struct loc_country *country;
+               int err = loc_database_get_country(db, &country, ccode);
+               if(!err) {
+                       // Extract the name for the given country code.
+                       const char* country_name = loc_country_get_name(country);
+                       RETVAL = newSVpv(country_name, strlen(country_name));
+
+                       loc_country_unref(country);
+               }
+
+       OUTPUT:
+               RETVAL
+
+SV*
+get_continent_code(db, ccode)
+       struct loc_database* db;
+       char* ccode;
+
+       CODE:
+               RETVAL = &PL_sv_undef;
+
+               // Lookup country code
+               struct loc_country *country;
+               int err = loc_database_get_country(db, &country, ccode);
+               if(!err) {
+                       //Extract the continent code for the given country code.
+                       const char* continent_code =  loc_country_get_continent_code(country);
+                       RETVAL = newSVpv(continent_code, strlen(continent_code));
+
+                       loc_country_unref(country);
+               }
+
+       OUTPUT:
+               RETVAL
+
+SV*
+get_as_name(db, as_number)
+       struct loc_database* db;
+       unsigned int as_number;
+
+       CODE:
+               RETVAL = &PL_sv_undef;
+
+               // Lookup AS.
+               struct loc_as *as;
+               int err = loc_database_get_as(db, &as, as_number);
+               if(!err) {
+                       // Get the name of the given AS number.
+                       const char* as_name = loc_as_get_name(as);
+
+                       RETVAL = newSVpv(as_name, strlen(as_name));
+
+                       loc_as_unref(as);
+               }
+
+       OUTPUT:
+               RETVAL
+
 void
 DESTROY(db)
        struct loc_database* db;