pythonnetwork-programmingdigpython-socketsgethostbyaddr

Difficulty using Python's socket.gethostbyaddr()


I am trying to reverse dns a list of IPs using socket.gethostbyaddr() in python, which returns 'Unknown Host' for some values, but using dig for the same ip returns the Hostname. Also, dig seems to be significantly faster than using python module, is there any specific reasons for that?

import socket

# This returns 'Unknown Host' 
name, alias, addresslist = socket.gethostbyaddr('114.143.51.197')

Solution

  • From the comments...

    whereas dig -x 114.143.51.197+short gives me the hostname.

    I'm sorry, but you are mistaken. 114.143.51.197 does not have a PTR record... therefore socket.gethostbyaddr() should throw an error... To process this use-case correctly, add a try / except clause that traps socket.herror

    >>> def dns_ptr_lookup(addr):
    ...     try:
    ...         return socket.gethostbyaddr(addr)
    ...     except socket.herror:
    ...         return None, None, None
    ...
    >>> # At this time, 4.2.2.2 has a valid PTR
    >>> name,alias,addresslist = dns_ptr_lookup('4.2.2.2')
    >>> print(name)
    vnsc-bak.sys.gtei.net
    >>>
    >>> # At this time, 114.143.51.197 does NOT have a valid PTR
    >>> name,alias,addresslist = dns_ptr_lookup('114.143.51.197')
    >>> print(name)
    None
    >>>
    

    DNS reverse lookup for 114.143.51.197... note that it does not have a valid PTR record

    [mpenning@Bucksnort ~]$ dig @8.8.8.8 -x 114.143.51.197
    
    ; <<>> DiG 9.6-ESV-R4 <<>> @8.8.8.8 -x 114.143.51.197
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 4735
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0
    
    ;; QUESTION SECTION:
    ;197.51.143.114.in-addr.arpa.   IN      PTR
    
    ;; AUTHORITY SECTION:
    114.in-addr.arpa.       1800    IN      SOA     ns1.apnic.net. read-txt-record-of-zone-first-dns-admin.apnic.net. 17812 7200 1800 604800 172800
    
    ;; Query time: 182 msec
    ;; SERVER: 8.8.8.8#53(8.8.8.8)
    ;; WHEN: Tue Nov 22 05:11:36 2011
    ;; MSG SIZE  rcvd: 134
    
    [mpenning@Bucksnort ~]$ python
    Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14)
    [GCC 4.3.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import socket
    >>> socket.gethostbyaddr('114.143.51.197')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    socket.herror: (1, 'Unknown host')
    >>>
    

    This is what a valid PTR record should look like...

    [mpenning@Bucksnort ~]$ dig -x 4.2.2.2
    
    ; <<>> DiG 9.6-ESV-R4 <<>> -x 4.2.2.2
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61856
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 1
    
    ;; QUESTION SECTION:
    ;2.2.2.4.in-addr.arpa.          IN      PTR
    
    ;; ANSWER SECTION:
    2.2.2.4.in-addr.arpa.   86400   IN      PTR     vnsc-bak.sys.gtei.net.
    
    ;; AUTHORITY SECTION:
    2.4.in-addr.arpa.       86400   IN      NS      dnsauth2.sys.gtei.net.
    2.4.in-addr.arpa.       86400   IN      NS      dnsauth1.sys.gtei.net.
    2.4.in-addr.arpa.       86400   IN      NS      dnsauth3.sys.gtei.net.
    
    ;; ADDITIONAL SECTION:
    dnsauth1.sys.gtei.net.  1800    IN      A       4.2.49.2
    
    ;; Query time: 308 msec
    ;; SERVER: 127.0.0.1#53(127.0.0.1)
    ;; WHEN: Tue Nov 22 05:10:16 2011
    ;; MSG SIZE  rcvd: 158
    
    [mpenning@Bucksnort ~]$ python
    Python 2.5.2 (r252:60911, Jan 24 2010, 14:53:14)
    [GCC 4.3.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import socket
    >>> socket.gethostbyaddr('4.2.2.2')
    ('vnsc-bak.sys.gtei.net', [], ['4.2.2.2'])
    >>>