(ipstr)
Parse a string and return the corrospondending IPaddress and the a guess of the IP version.

    Following Forms ar recorgnized:
    0x0123456789abcdef           # IPv4 if <= 0xffffffff else IPv6
    123.123.123.123              # IPv4
    123.123                      # 0-padded IPv4
    1080:0000:0000:0000:0008:0800:200C:417A
    1080:0:0:0:8:800:200C:417A
    1080:0::8:800:200C:417A
    ::1
    ::
    0:0:0:0:0:FFFF:129.144.52.38
    ::13.1.68.3
    ::FFFF:129.144.52.38
Parse a string and return the corrospondending IPaddress and the a guess of the IP version.
Parse a string and return the corrospondending IPaddress and the a guess of the IP version .
def parseAddress(ipstr):
    """Parse a string and return the corrospondending IPaddress and the a guess of the IP version.

    Following Forms ar recorgnized:
    0x0123456789abcdef           # IPv4 if <= 0xffffffff else IPv6
    123.123.123.123              # IPv4
    123.123                      # 0-padded IPv4
    1080:0000:0000:0000:0008:0800:200C:417A
    1080:0:0:0:8:800:200C:417A
    1080:0::8:800:200C:417A
    ::1
    ::
    0:0:0:0:0:FFFF:129.144.52.38
    ::13.1.68.3
    ::FFFF:129.144.52.38
    """

    # TODO: refactor me!
    if ipstr.startswith('0x'):
        ret = long(ipstr[2:], 16)
        if ret > 0xffffffffffffffffffffffffffffffff:
            raise ValueError(
                "%r: IP Address can't be bigger than 2^128" %
                (ipstr))
        if ret < 0x100000000:
            return (ret, 4)
        else:
            return (ret, 6)

    if ipstr.find(':') != -1:
        # assume IPv6
        if ipstr.find(':::') != -1:
            raise ValueError("%r: IPv6 Address can't contain ':::'" % (ipstr))
        hextets = ipstr.split(':')
        if ipstr.find('.') != -1:
            # this might be a mixed address like '0:0:0:0:0:0:13.1.68.3'
            (v4, foo) = parseAddress(hextets[-1])
            assert foo == 4
            del(hextets[-1])
            hextets.append(hex(v4 >> 16)[2:-1])
            hextets.append(hex(v4 & 0xffff)[2:-1])
        if len(hextets) > 8:
            raise ValueError(
                "%r: IPv6 Address with more than 8 hexletts" %
                (ipstr))
        if len(hextets) < 8:
            if '' not in hextets:
                raise ValueError(
                    "%r IPv6 Address with less than 8 hexletts and without '::'" %
                    (ipstr))
            # catch :: at the beginning or end
            if hextets.index('') < len(hextets) - 1 and hextets[hextets.index('') + 1] == '':
                hextets.remove('')
            # catch '::'
            if hextets.index('') < len(hextets) - 1 and hextets[hextets.index('') + 1] == '':
                hextets.remove('')

            for foo in range(9 - len(hextets)):
                hextets.insert(hextets.index(''), '0')
            hextets.remove('')
            if '' in hextets:
                raise ValueError(
                    "%r IPv6 Address may contain '::' only once" %
                    (ipstr))
        if '' in hextets:
            raise ValueError(
                "%r IPv6 Address may contain '::' only if it has less than 8 hextets" %
                (ipstr))
        num = ''
        for x in hextets:
            if len(x) < 4:
                x = ((4 - len(x)) * '0') + x
            if int(x, 16) < 0 or int(x, 16) > 0xffff:
                raise ValueError(
                    "%r: single hextet must be 0 <= hextet <= 0xffff which isn't true for %s" %
                    (ipstr, x))
            num += x
        return (long(num, 16), 6)

    elif len(ipstr) == 32:
        # assume IPv6 in pure hexadecimal notation
        return (long(ipstr, 16), 6)

    elif ipstr.find('.') != -1 or (len(ipstr) < 4 and int(ipstr) < 256):
        # assume IPv4  ('127' gets interpreted as '127.0.0.0')
        bytes = ipstr.split('.')
        if len(bytes) > 4:
            raise ValueError("IPv4 Address with more than 4 bytes")
        bytes += ['0'] * (4 - len(bytes))
        bytes = [long(x) for x in bytes]
        for x in bytes:
            if x > 255 or x < 0:
                raise ValueError(
                    "%r: single byte must be 0 <= byte < 256" %
                    (ipstr))
        return (
            ((bytes[0] << 24) + (bytes[1] << 16)
             + (bytes[2] << 8) + bytes[3], 4)
        )

    else:
        # we try to interprete it as a decimal digit -
        # this ony works for numbers > 255 ... others
        # will be interpreted as IPv4 first byte
        ret = long(ipstr)
        if ret > 0xffffffffffffffffffffffffffffffff:
            raise ValueError("IP Address cant be bigger than 2^128")
        if ret <= 0xffffffff:
            return (ret, 4)
        else:
            return (ret, 6)
def parseAddress ( ipstr ) : # TODO: refactor me! if ipstr . startswith ( '0x' ) : ret = long ( ipstr [ 2 : ] , 16 ) if ret > 0xffffffffffffffffffffffffffffffff : raise ValueError ( "%r: IP Address can't be bigger than 2^128" % ( ipstr ) ) if ret < 0x100000000 : return ( ret , 4 ) else : return ( ret , 6 ) if ipstr . find ( ':' ) != - 1 : # assume IPv6 if ipstr . find ( ':::' ) != - 1 : raise ValueError ( "%r: IPv6 Address can't contain ':::'" % ( ipstr ) ) hextets = ipstr . split ( ':' ) if ipstr . find ( '.' ) != - 1 : # this might be a mixed address like '0:0:0:0:0:0:13.1.68.3' ( v4 , foo ) = parseAddress ( hextets [ - 1 ] ) assert foo == 4 del ( hextets [ - 1 ] ) hextets . append ( hex ( v4 >> 16 ) [ 2 : - 1 ] ) hextets . append ( hex ( v4 & 0xffff ) [ 2 : - 1 ] ) if len ( hextets ) > 8 : raise ValueError ( "%r: IPv6 Address with more than 8 hexletts" % ( ipstr ) ) if len ( hextets ) < 8 : if '' not in hextets : raise ValueError ( "%r IPv6 Address with less than 8 hexletts and without '::'" % ( ipstr ) ) # catch :: at the beginning or end if hextets . index ( '' ) < len ( hextets ) - 1 and hextets [ hextets . index ( '' ) + 1 ] == '' : hextets . remove ( '' ) # catch '::' if hextets . index ( '' ) < len ( hextets ) - 1 and hextets [ hextets . index ( '' ) + 1 ] == '' : hextets . remove ( '' ) for foo in range ( 9 - len ( hextets ) ) : hextets . insert ( hextets . index ( '' ) , '0' ) hextets . remove ( '' ) if '' in hextets : raise ValueError ( "%r IPv6 Address may contain '::' only once" % ( ipstr ) ) if '' in hextets : raise ValueError ( "%r IPv6 Address may contain '::' only if it has less than 8 hextets" % ( ipstr ) ) num = '' for x in hextets : if len ( x ) < 4 : x = ( ( 4 - len ( x ) ) * '0' ) + x if int ( x , 16 ) < 0 or int ( x , 16 ) > 0xffff : raise ValueError ( "%r: single hextet must be 0 <= hextet <= 0xffff which isn't true for %s" % ( ipstr , x ) ) num += x return ( long ( num , 16 ) , 6 ) elif len ( ipstr ) == 32 : # assume IPv6 in pure hexadecimal notation return ( long ( ipstr , 16 ) , 6 ) elif ipstr . find ( '.' ) != - 1 or ( len ( ipstr ) < 4 and int ( ipstr ) < 256 ) : # assume IPv4  ('127' gets interpreted as '127.0.0.0') bytes = ipstr . split ( '.' ) if len ( bytes ) > 4 : raise ValueError ( "IPv4 Address with more than 4 bytes" ) bytes += [ '0' ] * ( 4 - len ( bytes ) ) bytes = [ long ( x ) for x in bytes ] for x in bytes : if x > 255 or x < 0 : raise ValueError ( "%r: single byte must be 0 <= byte < 256" % ( ipstr ) ) return ( ( ( bytes [ 0 ] << 24 ) + ( bytes [ 1 ] << 16 ) + ( bytes [ 2 ] << 8 ) + bytes [ 3 ] , 4 ) ) else : # we try to interprete it as a decimal digit - # this ony works for numbers > 255 ... others # will be interpreted as IPv4 first byte ret = long ( ipstr ) if ret > 0xffffffffffffffffffffffffffffffff : raise ValueError ( "IP Address cant be bigger than 2^128" ) if ret <= 0xffffffff : return ( ret , 4 ) else : return ( ret , 6 )