from struct import pack # A pattern to match the timestamp format that the tai64nlocal program # produces. It appears in both dnscache and tinydns lines, after # they've been piped through tai64nlocal, of course. timestamp_pat = r'[\d-]+ [\d:\.]+' # A dictionary mapping query type identifiers, in decimal, to their # friendly names for tinydns. Reference: # # https://en.wikipedia.org/wiki/List_of_DNS_record_types # # Note that mapping here is non-exhaustive, and that tinydns will # log responses for record types that it does not know about. query_type = { 1: "a", 2: "ns", 5: "cname", 6: "soa", 12: "ptr", 13: "hinfo", 15: "mx", 16: "txt", 17: "rp", 24: "sig", 25: "key", 28: "aaaa", 33: "srv", 35: "naptr", 38: "a6", 48: "dnskey", 52: "tlsa", 65: "https", 252: "axfr", 255: "any", 257: "caa" } def convert_ip(ip : str) -> str: r""" Convert a hex string representing an IP address to human-readable form. Parameters ---------- ip : str The hexadecimal representation of either an IPv4 or an IPv6 address. Returns ------- The usual decimal dotted-quad representation is returned for an IPv4 address. IPv6 addresses are returned almost as-is, but with colons inserted in the appropriate places, between every four characters. Examples -------- >>> convert_ip("7f000001") '127.0.0.1' >>> convert_ip("00000000000000000000ffff7f000001") '0000:0000:0000:0000:0000:ffff:7f00:0001' """ if len(ip) == 8: # IPv4, eg. "7f000001" -> "7f 00 00 01" -> "127.0.0.1" return ".".join(map(str, pack(">L", int(ip, 16)))) elif len(ip) == 32: # IPv6 is actually simpler -- it's just a string-slicing operation. return ":".join([ip[(4*i) : (4*i+4)] for i in range(8)])