#!python

"""querycontacts: query network abuse contacts for a given ip address on
abuse-contacts.abusix.org

Copyright 2013 by abusix GmbH
License: GPLv3

"""

import cli.app        # $ pip install pyCLI | todo: change to argparser
import csv
import dns.resolver   # $ pip install dnspython
import dns.reversename
import re
import sys


@cli.app.CommandLineApp


def querycontacts(app):

    provider = app.params.provider
    if not app.params.ipv6:
        if not re.match('^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$',
                        app.params.ip):
            sys.stderr.write('error: this does not seem to be an IPv4 address\n')
            exit()
        rev_ip = '.'.join(reversed(app.params.ip.split(".")))
    else:
        if "." in app.params.ip:
            sys.stderr.write('error: this does not seem to be an IPv6 address\n')
            exit()
        try:
            addr = dns.reversename.from_address(app.params.ip)
        except:
            sys.stderr.write('error: this does not seem to be an IPv6 address\n')
            exit()
        else:
            addr = str(addr)
            rev_ip = addr[:-10]
    if not app.params.zone:
        zone = ""
    else:
        zone = ".%s" % (app.params.zone, )
    resolver = dns.resolver.Resolver()
    resolver.lifetime = 5
    try:
        dns_query_results = resolver.query("%s%s.%s" % (rev_ip, zone, provider, ),
                                           'TXT')
    except dns.resolver.NXDOMAIN:
        if not zone:
            sys.stderr.write('error: no contacts for %s\n' % (app.params.ip, ))
        else:
            sys.stderr.write('error: no contacts for %s in zone %s\n' % (app.params.ip, zone.strip('.'), ))
    except Exception as err:
        sys.stderr.write('error: %s\n' % (err.__class__.__name__, ))
    else:
        abuse_addresses_txt = csv.reader(dns_query_results.rrset.items[0].strings,
                                         skipinitialspace=True)
        for abuse_addresses in abuse_addresses_txt:
            for abuse_address in abuse_addresses:
                print abuse_address


querycontacts.add_param(
    "ip",
    action='store',
    default="",
    help="query network abuse contacts for a given ip address on abuse-contacts.abusix.org"
)
querycontacts.add_param(
    "-z",
    "--zone",
    action='store',
    dest="zone", default="",
    help="query only one specific rir zone, supported values: arin, afrinic, lacnic, apnic, ripencc"
)
querycontacts.add_param(
    '--version',
    action='version',
    version='%(prog)s 0.1.0'
)
querycontacts.add_param(
    "--provider",
    action='store',
    dest="provider",
    default="abuse-contacts.abusix.org",
    help="change standard network abuse contacts provider"
)
querycontacts.add_param(
    "-6",
    action='store_true',
    dest="ipv6",
    help="provided ip address is v6 (currently only for arin ipv6 adresses)"
)


if __name__ == "__main__":
    querycontacts.run()
