dns-sacha/dns-sacha.py

85 lines
1.8 KiB
Python
Executable File

#!/usr/bin/env python3
import functools
import json
import socket
import sys
'''
Takes as input a list of domain names to test. Return wether they are
IPv4/IPv6-compatible.
Usage:
> cat test.txt
baionet.fr
google.com
> cat test.txt | ./dns-sacha.py | jq
[
{
"host": "baionet.fr",
"v4": true,
"v6": false
},
{
"host": "google.com",
"v4": true,
"v6": true
}
]
'''
class UrlIp:
'''
Struct wrapping a single record entry. Does it have IPv4 support?
IPv6 support?
'''
def __init__(self, host, v4, v6):
self.host = host
self.v4 = v4
self.v6 = v6
def get_host_records(host):
'''
Folds all the DNS entries of a Host and looks whether or not we
can find v4 and v6 records.
reduce == left fold in the python world btw...
'''
records = socket.getaddrinfo(host, 80)
return(functools.reduce(_test_record,records,UrlIp(host,False,False)))
def _test_record(urlip, rec):
'''
Fold function for get_host_records. Too big for a lambda not to
get messy.
Gotta love Python...
'''
(family, _rtype, proto, _canonname, _sockaddr) = rec
if family == socket.AF_INET:
urlip.v4 = True
elif family == socket.AF_INET6:
urlip.v6 = True
return urlip
def parse_hosts(file_name):
with open(file_name, 'r') as f:
return f.readlines()
def render_results(results):
'''
Takes an array of UrlIp and renders that to json.
Python's json.dumps only works with dictionnaries, not classes.
Extracting the dictionnary representation of the class.
'''
return(json.dumps([r.__dict__ for r in results]))
if __name__ == '__main__':
entries = [l.strip() for l in sys.stdin.readlines()]
test_results = [get_host_records(entry) for entry in entries]
print(render_results(test_results))