105 lines
2.9 KiB
Python
105 lines
2.9 KiB
Python
#! /usr/bin/env python
|
|
import os
|
|
import re
|
|
import collections
|
|
|
|
# constants
|
|
PING_HOST_RESPONSE = 0
|
|
PING_COMMAND = "ping -c 1 -W 1 {0} > /dev/null 2>&1"
|
|
ZONE_REGEX = "(\S+)\s+IN\s+([A-Z]+)\s+(\S+)"
|
|
DNS_REGEX = "([a-z0-9._-]+)$"
|
|
|
|
ZONE_FILENAMES = [
|
|
"master/0.16.10.in-addr.arpa",
|
|
"master/125.5.10.in-addr.arpa",
|
|
"master/126.5.10.in-addr.arpa",
|
|
"master/127.5.10.in-addr.arpa",
|
|
"master/phx2.fedoraproject.org"
|
|
]
|
|
|
|
AddressRecord = collections.namedtuple('AddressRecord', 'host, type, value')
|
|
|
|
def get_host_dict(fp, prefix):
|
|
hosts = dict()
|
|
|
|
# get the hostnames from the file
|
|
pattern = re.compile(ZONE_REGEX)
|
|
for line in fp:
|
|
m = pattern.match(line)
|
|
if m:
|
|
full_host = prefix.format(m.group(1))
|
|
if full_host[0] <> ';':
|
|
hosts[full_host] = AddressRecord._make( [full_host, m.group(2), m.group(3)] )
|
|
return hosts
|
|
|
|
def check_zones_match(fwd_hosts, rev_hosts):
|
|
results = {}
|
|
results["correct"] = []
|
|
results["mismatch"] = []
|
|
results["missing"] = []
|
|
|
|
for record in fwd_hosts.values():
|
|
if record.type is 'A':
|
|
try:
|
|
rev_record = rev_hosts[record.value]
|
|
if record.host == rev_record.value:
|
|
results["correct"].append( (record, rev_record) )
|
|
else:
|
|
results["mismatch"].append( (record, rev_record) )
|
|
except KeyError:
|
|
results["missing"].append( (record, None) )
|
|
return results
|
|
|
|
# ping each host and record the result
|
|
def ping(hosts):
|
|
results = {}
|
|
for record in hosts.values():
|
|
results[record] = os.system(PING_COMMAND.format(record.host) )
|
|
return results
|
|
|
|
def build_dns_suffix(filename, reverse=False):
|
|
m = re.search(DNS_REGEX, filename)
|
|
if m:
|
|
suffix = m.group(1)
|
|
if reverse:
|
|
parts = suffix.split(".")
|
|
return parts[2]+"."+parts[1]+"."+parts[0]+".{0}"
|
|
else:
|
|
return "{0}."+m.group(1)+"."
|
|
|
|
def main(filenames, check_dns=True, ping_hosts=True, print_stats=False):
|
|
rev_hosts = {}
|
|
fwd_hosts = {}
|
|
|
|
for filename in filenames:
|
|
is_reverse = filename.endswith(".in-addr.arpa")
|
|
suffix = build_dns_suffix(filename, is_reverse)
|
|
host_dict = get_host_dict(open(filename, "r"), suffix)
|
|
|
|
type_dict = rev_hosts if is_reverse else fwd_hosts
|
|
type_dict.update(host_dict)
|
|
|
|
if check_dns:
|
|
check_results = check_zones_match(fwd_hosts, rev_hosts)
|
|
|
|
if print_stats:
|
|
print("reverse dns records")
|
|
print("records correct: {0}".format(len(check_results["correct"])))
|
|
print("records incorrect: {0}".format(len(check_results["mismatch"])))
|
|
print("records missing: {0}".format(len(check_results["missing"])))
|
|
|
|
for (fwd, rev) in check_results["mismatch"]:
|
|
print ("mismatched record: {0} -> {1} -> {2}".format(fwd.host, fwd.value, rev.value))
|
|
|
|
for (fwd, rev) in check_results["missing"]:
|
|
print ("missing record: {0} -> {1}").format(fwd.host, fwd.value)
|
|
|
|
if ping_hosts:
|
|
results = ping(fwd_hosts)
|
|
|
|
# print all the non-zero (error) results
|
|
for (host, result) in results.items():
|
|
if result is not 0:
|
|
print ("ping failed: {0} (err {1})").format(host.host[:-1], result)
|
|
|
|
main(ZONE_FILENAMES)
|