7

I wonder if there is a way to use python to resolve a hostname that resolves only in ipv6 and/or for a hostname that resolves both in ipv4 and ipv6?

socket.gethostbyname() and socket.gethostbyname_ex()does not work for ipv6 resolution.

A dummy way to do that is to run actual linux host command and parse the results. Is there any better way to do that?

Thanks,

Mariusz Jamro
  • 27,234
  • 22
  • 104
  • 144
Amir
  • 5,136
  • 11
  • 40
  • 56

2 Answers2

14

socket.getaddrinfo supports IPv6. You just need to set family to AF_INET6.

socket.getaddrinfo("example.com", None, socket.AF_INET6)
John Colanduoni
  • 1,496
  • 14
  • 18
  • Thanks, it works but not with the format you mentioned. It doesn't take any keyword argument. – Amir Mar 12 '13 at 22:24
  • With socket.AF_INET6, this returns only local IPV6 for my Win10. without param AF_INET6, it returns also public IPV6 and IPV4 – rundekugel Jan 30 '20 at 10:39
  • I tried this for "www.google.com" and it returns an error `[Errno 11004] getaddrinfo failed` but when use `nslookup -query=AAAA google.com` it returns some IPv6 address. Is there any way to get same IPv6 address by using the python script? – Sachihiro Mar 03 '21 at 23:41
3

I want to expand on the answer of @john-colanduoni with more detail.

Get only the IPv6 address

To really get only the corresponding IPv6-address, you should try using socket.getaddrinfo.

>>> print(socket.getaddrinfo('www.microsoft.com', None, socket.AF_INET6)[0][4][0])
2a02:26f0:6a:288::356e

but beware, e.g. if there is no IPv6 AAAA-Record for the hostname, such as:

>>> print(socket.getaddrinfo('microsoft.com', None, socket.AF_INET6)[0][4][0])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.7/socket.py", line 748, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno -2] Name or service not known

you will get socket.gaierror: [Errno -2] Name or service not known which is a subclass of OSError.

Btw. try using localhost, the hostname of your computer (if it's IPv6 enabled) or example.com as the hostname argument.

Get the hostname from IPv6 address

A query for the PTR-Record would look like:

>>> print(socket.gethostbyaddr('2a00:1450:4001:81d::200e')[0])
fra15s18-in-x0e.1e100.net

since socket.gethostbyaddr is both IPv4 and IPv6 enabled.

Community
  • 1
  • 1
AdamKalisz
  • 252
  • 2
  • 12
  • Did not work for me, returned an error `[Errno 11004] getaddrinfo failed` – Sachihiro Mar 03 '21 at 23:42
  • @Sachihiro can you be more specific? Maybe you have to `import socket` first? https://stackoverflow.com/questions/7334199/getaddrinfo-failed-what-does-that-mean – AdamKalisz Mar 05 '21 at 04:24
  • Yea of course i imported socket, It would be a different error if I had not done that. I think it is a bug on python 3.9, updated to 3.9.2 and the error persists. – Sachihiro Mar 05 '21 at 09:11
  • @Sachihiro what OS is this? Does your resolver actually deliver IPv6 AAAA records (try with nslookup, host, dig or other tools depending on platform)? What have you found by searching for the bug on the web? Have you found, where this messsage gets emitted in the source code of Python or elsewhere? I use Python 3.9.1 on Debian and it doesn't hit this error. – AdamKalisz Mar 05 '21 at 19:09
  • I am on Windows, and yes I used nslookup, tried on `google.com` – Sachihiro Mar 05 '21 at 22:37