]> git.ipfire.org Git - location/libloc.git/commitdiff
location-query: Support listing networks for xt_geoip
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 15 Nov 2019 13:53:02 +0000 (13:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 15 Nov 2019 13:53:02 +0000 (13:53 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
man/location-query.txt
src/python/location-query.in

index 216d1dbeada93f45d96984b48e0fbc6ffe7e04bf..84f0fdcad542d0f5bd450d0078c8b96ff9b78033 100644 (file)
@@ -43,13 +43,22 @@ or countries.
        +
        The search will be performed case-insensitively.
 
-'list-networks-by-as ASN'::
+'list-networks-by-as [--output-format FORMAT] ASN'::
        Lists all networks which belong to this Autonomous System.
+       +
+       The '--output-format' parameter can change the output so that it can be
+       directly loaded into other software. The following options are available:
+       +
+       * 'list' (default): Just lists all networks, one per line
+       * 'xt_geoip': Returns a list of networks to be loaded into the xt_geoip
+         kernel module
 
-'list-networks-by-cc COUNTRY_CODE'::
+'list-networks-by-cc [--output-format FORMAT] COUNTRY_CODE'::
        Lists all networks that belong to a country.
        +
        The country has to be encoded in ISO3166 Alpha-2 notation.
+       +
+       See above for usage of the '--output-format' parameter.
 
 '--help'::
        Shows a short help text on using this program.
index 2172da2e09b037408f282d5b5d883f11a591503c..258afbc8f878bf23713af64cfc5c8f501373f260 100644 (file)
@@ -19,6 +19,9 @@
 
 import argparse
 import gettext
+import ipaddress
+import os
+import socket
 import sys
 import syslog
 
@@ -32,7 +35,52 @@ def _(singular, plural=None, n=None):
 
        return gettext.dgettext("libloc", singular)
 
+# Output formatters
+
+class OutputFormatter(object):
+       def __enter__(self):
+               # Open the output
+               self.open()
+
+               return self
+
+       def __exit__(self, type, value, tb):
+               if tb is None:
+                       self.close()
+
+       def open(self):
+               pass
+
+       def close(self):
+               pass
+
+       def network(self, network):
+               print(network)
+
+
+class XTGeoIPOutputFormatter(OutputFormatter):
+       """
+               Formats the output in that way, that it can be loaded by
+               the xt_geoip kernel module from xtables-addons.
+       """
+       def network(self, network):
+               n = ipaddress.ip_network("%s" % network)
+
+               for address in (n.network_address, n.broadcast_address):
+                       bytes = socket.inet_pton(
+                               socket.AF_INET6 if address.version == 6 else socket.AF_INET,
+                               "%s" % address,
+                       )
+
+                       os.write(1, bytes)
+
+
 class CLI(object):
+       output_formats = {
+               "list"     : OutputFormatter,
+               "xt_geoip" : XTGeoIPOutputFormatter,
+       }
+
        def parse_cli(self):
                parser = argparse.ArgumentParser(
                        description=_("Location Database Command Line Interface"),
@@ -78,6 +126,8 @@ class CLI(object):
                        help=_("Lists all networks in an AS"),
                )
                list_networks_by_as.add_argument("asn", nargs=1, type=int)
+               list_networks_by_as.add_argument("--output-format",
+                       choices=self.output_formats.keys(), default="list")
                list_networks_by_as.set_defaults(func=self.handle_list_networks_by_as)
 
                # List all networks in a country
@@ -85,6 +135,8 @@ class CLI(object):
                        help=_("Lists all networks in a country"),
                )
                list_networks_by_cc.add_argument("country_code", nargs=1)
+               list_networks_by_cc.add_argument("--output-format",
+                       choices=self.output_formats.keys(), default="list")
                list_networks_by_cc.set_defaults(func=self.handle_list_networks_by_cc)
 
                args = parser.parse_args()
@@ -188,17 +240,28 @@ class CLI(object):
                        for a in db.search_as(query):
                                print(a)
 
+       def __get_output_formatter(self, ns):
+               try:
+                       cls = self.output_formats[ns.output_format]
+               except KeyError:
+                       cls = OutputFormatter
+
+               return cls()
+
        def handle_list_networks_by_as(self, db, ns):
-               for asn in ns.asn:
-                       # Print all matching networks
-                       for n in db.search_networks(asn=asn):
-                               print(n)
+               with self.__get_output_formatter(ns) as f:
+                       for asn in ns.asn:
+                               # Print all matching networks
+                               for n in db.search_networks(asn=asn):
+                                       f.network(n)
 
        def handle_list_networks_by_cc(self, db, ns):
-               for country_code in ns.country_code:
-                       # Print all matching networks
-                       for n in db.search_networks(country_code=country_code):
-                               print(n)
+               with self.__get_output_formatter(ns) as f:
+                       for country_code in ns.country_code:
+                               # Print all matching networks
+                               for n in db.search_networks(country_code=country_code):
+                                       f.network(n)
+
 
 def main():
        # Run the command line interface