########################################################################
#
#  Copyright (C) 2009, CZ.NIC, z.s.p.o.
# 
#  This file is part of dnstester.
#
#  dnstester is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  dnstester 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 General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
########################################################################

import sys
import time
import string
import traceback
import re
from subprocess import Popen, PIPE

from misc import readall

def detect_gateway():
    
    try:
        route = Popen(args=['/usr/sbin/netstat', '-nr', '-f', 'inet'], stdout=PIPE, stderr=PIPE)
        retcode = route.wait()
        ferr = route.stderr
        log = readall(ferr)
    except Exception, e:
        retcode = -1
        log = traceback.format_exc()

    if retcode == 0:

        fout = route.stdout
        line = fout.readline()
        while line != "":
            if line.startswith('default '):
                columns = string.split(line)
                if len(columns) < 2:
                    log += 'Invalid netstat output.\n'
                    return None, log
                gateway = string.strip(columns[1])
                if not re.match('[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}', gateway):
                    log += 'Invalid gateway address format.\n'
                    return None, log
        	return gateway, log
            line = fout.readline()

    else:
        return None, log

def normalize_mac(mac):

    hexdigits = ['0', '1', '2', '3', '4',
                 '5', '6', '7', '8', '9', 
                 'a', 'b', 'c', 'd', 'e', 'f']
    bytes = mac.split(':')
    if len(bytes) != 6: return None
    r = []
    for b in bytes:
        if len(b) == 1: b = '0' + b
        if len(b) != 2: return None
        if not b[0] in hexdigits or not b[1] in hexdigits: return None
        r.append(b)
    return ':'.join(r)
    

def get_arp(ip):
    
    try:
        route = Popen(args=['/usr/sbin/arp', '-an'], stdout=PIPE, stderr=PIPE)
        retcode = route.wait()
        ferr = route.stderr
        log = readall(ferr)
    except:
        retcode = -1
        log = traceback.format_exc()

    if retcode == 0:

        mac = '00:00:00:00:00:00'
        linestart = "? (%s) at " % ip
        fout = route.stdout
        line = fout.readline()
        while line != "":
            if line.startswith(linestart):
                line = line[len(linestart):]
                index = line.find(' ')
                mac = line[0:index]
                mac = normalize_mac(mac)
                if not mac: log += 'invalid mac address format\n'
                return mac, log

            line = fout.readline()

    return None, log

def get_gateway_ipmac():

    gateway, route_log = detect_gateway()
    log = "Route log:\n" + route_log

    if not gateway:
        return (None, None), log

    mac, arp_log = get_arp(gateway)
    log += "ARP log:\n" + arp_log

    return (gateway, mac), log

