########################################################################
#
#  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/>.
#
########################################################################

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

# assuming that the mask matches to [08cef]{8}
def mask2bits(mask):
    
    B = {'0': 0, '8': 1, 'c': 2, 'e': 3, 'f': 4}

    i = 0
    b = 0
    prev = 'f'
    for i in range(8):
        c = mask[i]
        if prev != 'f' and c != '0': return -1
        prev = c
        if c not in B.keys(): return -1
        b += B[c]

    return b
    

def host_addresses():

    try:
        ip = Popen(args=['/sbin/ifconfig'], stdout=PIPE, stderr=PIPE)
        retcode = ip.wait()
        ferr = ip.stderr
        log = misc.readall(ferr)
    except Exception, e:
        retcode = -1
        log = traceback.format_exc()

    if retcode == 0:

        fout = ip.stdout
        line = fout.readline()

        addresses = []
        ipv4 = re.compile(r'[ \t]+inet ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) netmask 0x([08cef]{8})')
        ipv6 = re.compile(r'[ \t]+inet6 ([a-f0-9:]{2,39}) prefixlen ([0-9]{1,3})')

        while line != "":

            match = ipv4.match(line)
            if match:
                mask = match.group(2)
                bits = mask2bits(mask)
                if bits >= 0:
                    addresses.append("%s/%d" % (match.group(1), bits))
                else:
                    log += 'invalid mask %s\n' % mask
                    return None, log
            else:
                match = ipv6.match(line)
                if match:
                    addresses.append("%s/%s" % (match.group(1), match.group(2)))

            line = fout.readline()

        return addresses, log
    else:
        return None, log

