at the moment I do:
def get_inet_ip(): s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.connect(('mysite.com', 80)) return s.getsockname()[0] This was based on: Finding local IP addresses using Python's stdlib
However, This looks a bit dubious. As far as I can tell, it opens a socket to mysite.com:80, and then returns the first address for that socket, assuming it to be an IPv4 address. This seems a bit dodgy... i dont think we can ever guaranteee that to be the case.
Thats my first question, is it safe? On an IPv6-enable server, could the IPv6 address ever be returned unexpectedly?
My second question, is how do I get the IPv6 address in a similar way. Im going to modify the function to take an optional ipv6 paramater.
22 Answers
The question is, do you just want to connect, or do you really want the address?
If you just want to connect, you can do
s = socket.create_connection(('mysite.com', 80)) and have the connection established.
However, if you are interested in the address, you can go one of these ways:
def get_ip_6(host, port=0): import socket # search only for the wanted v6 addresses result = socket.getaddrinfo(host, port, socket.AF_INET6) return result # or: return result[0][4][0] # just returns the first answer and only the address or, to be closer to another, already presented solution:
def get_ip_6(host, port=0): # search for all addresses, but take only the v6 ones alladdr = socket.getaddrinfo(host,port) ip6 = filter( lambda x: x[0] == socket.AF_INET6, # means its ip6 alladdr ) # if you want just the sockaddr # return map(lambda x:x[4],ip6) return list(ip6)[0][4][0] 1You should be using the function socket.getaddrinfo()
Example code to get IPv6
def get_ip_6(host,port=80): # discard the (family, socktype, proto, canonname) part of the tuple # and make sure the ips are unique alladdr = list( set( map( lambda x: x[4], socket.getaddrinfo(host,port) ) ) ) ip6 = filter( lambda x: ':' in x[0], # means its ip6 alladdr ) return ip6 2