Search code examples
pythondnslocalhostcross-platformsystem

Get local DNS settings in Python


Is there any elegant and cross platform (Python) way to get the local DNS settings?

It could probably work with a complex combination of modules such as platform and subprocess, but maybe there is already a good module, such as netifaces which can retrieve it in low-level and save some "reinventing the wheel" effort.

Less ideally, one could probably query something like dig, but I find it "noisy", because it would run an extra request instead of just retrieving something which exists already locally.

Any ideas?


Solution

  • Thanks @MasterOfTheHouse. I ended up writing my own function. It's not so elegant, but it does the job for now. There's plenty of room for improvement, but well...

    import os
    import subprocess
    
    def get_dns_settings()->dict:
        # Initialize the output variables
        dns_ns, dns_search = [], ''
    
        # For Unix based OSs
        if os.path.isfile('/etc/resolv.conf'):
            for line in open('/etc/resolv.conf','r'):
                if line.strip().startswith('nameserver'):
                    nameserver = line.split()[1].strip()
                    dns_ns.append(nameserver)
                elif line.strip().startswith('search'):
                    search = line.split()[1].strip()
                    dns_search = search
    
        # If it is not a Unix based OS, try "the Windows way"
        elif os.name == 'nt':
            cmd = 'ipconfig /all'
            raw_ipconfig = subprocess.check_output(cmd)
            # Convert the bytes into a string
            ipconfig_str = raw_ipconfig.decode('cp850')
            # Convert the string into a list of lines
            ipconfig_lines = ipconfig_str.split('\n')
    
            for n in range(len(ipconfig_lines)):
                line = ipconfig_lines[n]
                # Parse nameserver in current line and next ones
                if line.strip().startswith('DNS-Server'):
                    nameserver = ':'.join(line.split(':')[1:]).strip()
                    dns_ns.append(nameserver)
                    next_line = ipconfig_lines[n+1]
                    # If there's too much blank at the beginning, assume we have
                    # another nameserver on the next line
                    if len(next_line) - len(next_line.strip()) > 10:
                        dns_ns.append(next_line.strip())
                        next_next_line = ipconfig_lines[n+2]
                        if len(next_next_line) - len(next_next_line.strip()) > 10:
                            dns_ns.append(next_next_line.strip())
    
                elif line.strip().startswith('DNS-Suffix'):
                    dns_search = line.split(':')[1].strip()
    
        return {'nameservers': dns_ns, 'search': dns_search}
    
    print(get_dns_settings())
    

    By the way... how did you manage to write two answers with the same account?