Search code examples
pythonsocketsip-addressipv6ipv4

Why does gethostbyaddr(gethostname()) return my IPv6 IP?


I'm working on making a simple server application with python, and I'm trying to get the IP to bind the listening socket to. An example I looked at uses this:

HOST = gethostbyaddr(gethostname())

With a little more processing after this, it should give me just the host IP as a string. This should return the IPv4 address. But when I run this code, it returns my IPv6 address. Why does it do this and how can I get my IPv4 address?

If its relevant, I'm using windows vista and python 2.5


Solution

  • Getting your IP address is harder than you might think.

    Check this answer I gave for the one reliable way I've found.

    Here's what the answer says in case you don't like clicking on things:

    Use the netifaces module. Because networking is complex, using netifaces can be a little tricky, but here's how to do what you want:

    >>> import netifaces
    >>> netifaces.interfaces()
    ['lo', 'eth0']
    >>> netifaces.ifaddresses('eth0')
    {17: [{'broadcast': 'ff:ff:ff:ff:ff:ff', 'addr': '00:11:2f:32:63:45'}], 2: [{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}], 10: [{'netmask': 'ffff:ffff:ffff:ffff::', 'addr': 'fe80::211:2fff:fe32:6345%eth0'}]}
    >>> for interface in netifaces.interfaces():
    ...   print netifaces.ifaddresses(interface)[netifaces.AF_INET]
    ...
    [{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
    [{'broadcast': '10.0.0.255', 'netmask': '255.255.255.0', 'addr': '10.0.0.2'}]
    >>> for interface in netifaces.interfaces():
    ...   for link in netifaces.ifaddresses(interface)[netifaces.AF_INET]:
    ...     print link['addr']
    ...
    127.0.0.1
    10.0.0.2
    

    This can be made a little more readable like this:

    from netifaces import interfaces, ifaddresses, AF_INET
    
    def ip4_addresses():
        ip_list = []
        for interface in interfaces():
            for link in ifaddresses(interface)[AF_INET]:
                ip_list.append(link['addr'])
        return ip_list
    

    If you want IPv6 addresses, use AF_INET6 instead of AF_INET. If you're wondering why netifaces uses lists and dictionaries all over the place, it's because a single computer can have multiple NICs, and each NIC can have multiple addresses, and each address has its own set of options.