#!/usr/bin/python

import os
import re
import sys

import commands
import logging
import socket
import struct

from optparse import OptionParser


class Route(object):
    """Gets routing information from the system.
    """

    # auxiliary functions
    def _hex_to_dec(self, string):
        """Returns the integer value of a hexadecimal string s
        """
        return int(string, 16)

    def _num_to_dotted_quad(self, number):
        """Convert long int to dotted quad string
        """
        return socket.inet_ntoa(struct.pack("<L", number))

    def _get_default_gateway_from_proc(self):
        """"Returns the current default gateway, reading that from /proc
        """
        logging.debug("Reading default gateway information from /proc")
        try:
            descriptor = file("/proc/net/route")
            route = descriptor.read()
        except:
            logging.error("Failed to read def gateway from /proc")
            return None
        else:
            h = re.compile("\n(?P<interface>\w+)\s+00000000\s+(?P<def_gateway>[\w]+)\s+")
            w = h.search(route)
            if w:
                if w.group("def_gateway"):
                    return self._num_to_dotted_quad(self._hex_to_dec(w.group("def_gateway")))
                else:
                    logging.error("Could not find def gateway info in /proc") 
                    return None
            else:
                logging.error("Could not find def gateway info in /proc") 
                return None

    def _get_default_gateway_from_bin_route(self):
        """Get default gateway from /sbin/route -n
        Called by get_default_gateway and is only used if could not get that from /proc
        """
        logging.debug("Reading default gateway information from route binary")
        routebin = commands.getstatusoutput("export LANGUAGE=C; /usr/bin/env route -n")

        if routebin[0] != 0:
            logging.error("Error while trying to run route")
            return None

        h = re.compile("\n0.0.0.0\s+(?P<def_gateway>[\w.]+)\s+")
        w = h.search(routebin[1])
        if w:
            def_gateway = w.group("def_gateway")

        if def_gateway:
            return def_gateway
        
        logging.error("Could not find default gateway by running route")
        return None

    def get_hostname(self):
        return socket.gethostname()

    def get_default_gateway(self):
        t1 = self._get_default_gateway_from_proc()
        if not t1:
            t1 = self._get_default_gateway_from_bin_route()

        return t1

def ping(host, count, deadline):
    command = "ping -q -c %s -w %s %s" % (count, deadline, host)
    reg = re.compile(r"(\d) received")
    packets_received = 0

    output = os.popen(command)
    for line in output.readlines():
        received = re.findall(reg, line)
        if received:
            packets_received = int(received[0])

    return packets_received

def main(args):
    default_count = 2
    default_delay = 4

    usage = "%prog [HOST]"
    parser = OptionParser(usage=usage)
    parser.add_option("-c", "--count",
        default=default_count,
        type="int",
        help="Number of packets to send.")
    parser.add_option("-d", "--deadline",
        default=default_delay,
        type="int",
        help="Timeouts in seconds.")
    (options, args) = parser.parse_args(args)

    if args:
        host = args.pop(0)
    else:
        route = Route()
        host = route.get_default_gateway()

    received_packets = ping(host, options.count, options.deadline)

    if received_packets == 0:
        print "No Internet connection"
    elif received_packets != options.count:
        print "Connection established lost a packet"
    else:
        print "Internet connection fully established"

    return 0

if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))
