python: Add script to lookup database from command line
authorMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Feb 2018 13:00:44 +0000 (13:00 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Thu, 1 Feb 2018 13:00:44 +0000 (13:00 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/python/as.c
src/python/location-query [new file with mode: 0644]
src/python/network.c

index 2372937..ebbb0e5 100644 (file)
@@ -112,6 +112,9 @@ src_python_location_la_LIBADD = \
        src/libloc.la \
        $(PYTHON_LIBS)
 
+bin_SCRIPTS = \
+       src/python/location-query
+
 TESTS_CFLAGS = \
        $(AM_CFLAGS) \
        -DLIBLOC_PRIVATE
index f6e9cab..0a9c7cc 100644 (file)
@@ -68,6 +68,16 @@ static PyObject* AS_repr(ASObject* self) {
        return PyUnicode_FromFormat("<AS %d>", number);
 }
 
+static PyObject* AS_str(ASObject* self) {
+       uint32_t number = loc_as_get_number(self->as);
+       const char* name = loc_as_get_name(self->as);
+
+       if (name)
+               return PyUnicode_FromFormat("AS%d (%s)", number, name);
+
+       return PyUnicode_FromFormat("AS%d", number);
+}
+
 static PyObject* AS_get_number(ASObject* self) {
        uint32_t number = loc_as_get_number(self->as);
 
@@ -144,5 +154,6 @@ PyTypeObject ASType = {
        tp_doc:                 "AS object",
        tp_getset:              AS_getsetters,
        tp_repr:                (reprfunc)AS_repr,
+       tp_str:                 (reprfunc)AS_str,
        tp_richcompare:         (richcmpfunc)AS_richcompare,
 };
diff --git a/src/python/location-query b/src/python/location-query
new file mode 100644 (file)
index 0000000..9b5ea94
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/python3
+###############################################################################
+#                                                                             #
+# libloc - A library to determine the location of someone on the Internet     #
+#                                                                             #
+# Copyright (C) 2017 IPFire Development Team <info@ipfire.org>                #
+#                                                                             #
+# This library is free software; you can redistribute it and/or               #
+# modify it under the terms of the GNU Lesser General Public                  #
+# License as published by the Free Software Foundation; either                #
+# version 2.1 of the License, or (at your option) any later version.          #
+#                                                                             #
+# This library is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           #
+# Lesser General Public License for more details.                             #
+#                                                                             #
+###############################################################################
+
+import argparse
+import sys
+import syslog
+
+# Load our location module
+import location
+
+# i18n
+_ = lambda x: x
+
+class CLI(object):
+       def __init__(self):
+               # Open database
+               self.db = location.Database("test.db")
+
+       def parse_cli(self):
+               parser = argparse.ArgumentParser(
+                       description=_("Location Database Command Line Interface"),
+               )
+               subparsers = parser.add_subparsers()
+
+               # Global configuration flags
+               parser.add_argument("--debug", action="store_true",
+                       help=_("Enable debug output"))
+
+               # lookup an IP address
+               lookup = subparsers.add_parser("lookup",
+                       help=_("Lookup one or multiple IP addresses"),
+               )
+               lookup.add_argument("address", nargs="+")
+               lookup.set_defaults(func=self.handle_lookup)
+
+               return parser.parse_args()
+
+       def run(self):
+               # Parse command line arguments
+               args = self.parse_cli()
+
+               # Callback function must be defined
+               assert args.func, "Callback function not defined"
+
+               # Call function
+               ret = args.func(args)
+
+               # Return with exit code
+               if ret:
+                       sys.exit(ret)
+
+               # Otherwise just exit
+               sys.exit(0)
+
+       def handle_lookup(self, ns):
+               ret = 0
+
+               for address in ns.address:
+                       try:
+                               n = self.db.lookup(address)
+                       except ValueError:
+                               sys.stderr.write(_("Invalid IP address: %s") % address)
+
+                       args = {
+                               "address" : address,
+                               "network" : n,
+                       }
+
+                       # Nothing found?
+                       if not n:
+                               print(_("Nothing found for %(address)s") % args)
+                               ret = 1
+                               continue
+
+                       # Try to retrieve the AS if we have an AS number
+                       if n.asn:
+                               a = self.db.get_as(n.asn)
+
+                               # If we have found an AS we will print it in the message
+                               if a:
+                                       args.update({
+                                               "as" : a,
+                                       })
+
+                                       print(_("%(address)s belongs to %(network)s which is a part of %(as)s") % args)
+                                       continue
+
+                       print(_("%(address)s belongs to %(network)s") % args)
+
+               return ret
+
+
+def main():
+       # Run the command line interface
+       c = CLI()
+       c.run()
+
+main()
index 91264df..9ee5067 100644 (file)
@@ -71,6 +71,15 @@ static PyObject* Network_repr(NetworkObject* self) {
        return obj;
 }
 
+static PyObject* Network_str(NetworkObject* self) {
+       char* network = loc_network_str(self->network);
+
+       PyObject* obj = PyUnicode_FromString(network);
+       free(network);
+
+       return obj;
+}
+
 static PyObject* Network_get_country_code(NetworkObject* self) {
        const char* country_code = loc_network_get_country_code(self->network);
 
@@ -146,4 +155,5 @@ PyTypeObject NetworkType = {
        tp_doc:                 "Network object",
        tp_getset:              Network_getsetters,
        tp_repr:                (reprfunc)Network_repr,
+       tp_str:                 (reprfunc)Network_str,
 };