def decode_request(message): # decode the query message = dns.message.from_wire(message) myprint(type(message)) myprint("---query----") myprint(message) myprint("------------") # section eg: message.question or message.answer # section=message.question # name="A" # rdclass= 1 # IN the internet # rdtype= 1 # A 1 a host address # rrs = message.find_rrset(section, name, rdclass, rdtype) # rrs = message.get_rrset(section, name, rdclass, rdtype) myprint("id %s" % message.id) myprint("rcode %s" % message.rcode()) myprint(" rcode %s" % dns.rcode.to_text(message.rcode())) # print dir(message.rcode) myprint("opcode %s" % message.opcode()) myprint(" opcode %s" % dns.opcode.to_text(message.opcode())) myprint("flags %s" % message.flags) myprint(" flags %s" % dns.flags.to_text(message.flags)) myprint("index %s" % message.index) for rrset in message.question: # list of dns.rrset.RRset objects myprint("----> rrset: %s" % rrset) myprint(" covers %i" % rrset.covers) myprint(" rdclass %i" % rrset.rdclass) myprint(" rdtype %i" % rrset.rdtype) myprint(" ttl %i" % rrset.ttl) myprint(" name %s" % rrset.name) return message
def handle(server, raddress, message): try: message = dns.message.from_wire(message) except: print "Error decoding DNS message" return if message.edns < 0: print "Received non-EDNS message, ignoring" return if not (message.opcode() == 5 and message.authority): print "Received non-UPDATE message, ignoring" return info = {'records': [], 'addresses': []} # Try to guess the interface this came in on for iface in netifaces.interfaces(): ifaddresses = netifaces.ifaddresses(iface) for af, addresses in ifaddresses.items(): if af != 2: # AF_INET continue for address in addresses: net = IPy.IP(address['addr']).make_net(address['netmask']) if IPy.IP(raddress[0]) in net: info['mymac'] = ifaddresses[17][0]['addr'] info['myif'] = iface for rrset in message.authority: info['records'].append(rrset) _add_addresses(info, rrset) for option in message.options: if option.otype == 2: info['ttl'] = struct.unpack("!L", option.data) if option.otype == 4: info['othermac'] = option.data.encode('hex_codec')[4:] # TODO: endsflags seems to indicate some other TTL # TODO: Better composability manage_host(info) _answer(server.socket, raddress, message)
print "---query----" print message print "------------" # section eg: message.question or message.answer # section=message.question # name="A" # rdclass= 1 # IN the internet # rdtype= 1 # A 1 a host address # rrs = message.find_rrset(section, name, rdclass, rdtype) # rrs = message.get_rrset(section, name, rdclass, rdtype) print "id %s" % message.id print "rcode %s" % message.rcode() print " rcode %s" % dns.rcode.to_text(message.rcode()) # print dir(message.rcode) print "opcode %s" % message.opcode() print " opcode %s" % dns.opcode.to_text(message.opcode()) print "flags %s" % message.flags print " flags %s" % dns.flags.to_text(message.flags) print "index %s" % message.index for rrset in message.question: # list of dns.rrset.RRset objects print "----> rrset: %s" % rrset print " covers %i" % rrset.covers print " rdclass %i" % rrset.rdclass print " rdtype %i" % rrset.rdtype print " ttl %i" % rrset.ttl print " name %s" % rrset.name # print dir(rrset) # for item in rrset.items(): # print item
def handle(self, message, raddress): try: #with ignored(dns.message.BadEDNS): message = dns.message.from_wire(message, ignore_trailing=True) except dns.message.BadEDNS: #yosemite's discoveryd sends an OPT record per active NIC, dnspython doesn't like more than 1 OPT record # https://github.com/rthalley/dnspython/blob/master/dns/message.py#L642 # so turn off Wi-Fi for ethernet-connected clients pass #or send back an nxdomain or servfail except: #no way to just catch dns.exceptions.* logging.warning("Error decoding DNS message from {}".format( raddress[0])) logging.debug(traceback.format_exc()) return if message.edns < 0: logging.warning( "Received non-EDNS message from {}, ignoring".format( raddress[0])) return if not (message.opcode() == 5 and message.authority): logging.warning( "Received non-UPDATE message from {}, ignoring".format( raddress[0])) return logging.debug("Received SPS registration from {}, parsing".format( raddress[0])) info = {'records': [], 'addresses': []} # Try to guess the interface this came in on # todo - precompute this table on new()? for iface in netifaces.interfaces(): ifaddresses = netifaces.ifaddresses(iface) for af, addresses in ifaddresses.items(): if af not in (netifaces.AF_INET, netifaces.AF_INET6): continue for address in addresses: mask = address['netmask'] if af == netifaces.AF_INET6: mask = ( mask.count('f') * 4 ) # convert linux masks to prefix length...gooney if address['addr'].find('%') > -1: continue #more linux ipv6 stupidity iface_net = ipaddress.ip_interface('{}/{}'.format( address['addr'], mask)).network if ipaddress.ip_address(raddress[0]) in iface_net: info['mymac'] = ifaddresses[ netifaces.AF_LINK][0]['addr'] info['myif'] = iface for rrset in message.authority: rrset.rdclass %= dns.rdataclass.UNIQUE #remove cache-flush bit #rrset.rdata = rrset.rdata.decode(utf-8) info['records'].append(rrset) self._add_addresses(info, rrset) logging.debug('NSUPDATE START--\n\n{}\n\n{}\n\n--NSUPDATE END'.format( message, message.options)) for option in message.options: if option.otype == dns.edns.UL: info['ttl'] = option.lease #send-WOL-no-later-than timer TTL if option.otype == dns.edns.OWNER: info['othermac'] = option.pmac #WOL target mac #if option.passwd: # password required in wakeup packet # mDNS.c:SendSPSRegistrationForOwner() doesn't seem to add a password self._answer(raddress, message) if len(message.options) == 2: # need both an owner and an update-lease option, else its just a post-wake notification (incremented seq number) manage_host(info)
myprint("---query----") myprint(message) myprint("------------") # section eg: message.question or message.answer # section=message.question # name="A" # rdclass= 1 # IN the internet # rdtype= 1 # A 1 a host address # rrs = message.find_rrset(section, name, rdclass, rdtype) # rrs = message.get_rrset(section, name, rdclass, rdtype) myprint("id %s" % message.id) myprint("rcode %s" % message.rcode()) myprint(" rcode %s" % dns.rcode.to_text(message.rcode())) # print dir(message.rcode) myprint("opcode %s" % message.opcode()) myprint(" opcode %s" % dns.opcode.to_text(message.opcode())) myprint("flags %s" % message.flags) myprint(" flags %s" % dns.flags.to_text(message.flags)) myprint("index %s" % message.index) for rrset in message.question: # list of dns.rrset.RRset objects myprint("----> rrset: %s" % rrset) myprint(" covers %i" % rrset.covers) myprint(" rdclass %i" % rrset.rdclass) myprint(" rdtype %i" % rrset.rdtype) myprint(" ttl %i" % rrset.ttl) myprint(" name %s" % rrset.name) # print dir(rrset) # for item in rrset.items(): # print item
def _parse(self): try: message = dns.message.from_wire(self.data) except dns.exception.ShortHeader: print("The message is less than 12 octets long.", file=sys.stderr) raise except dns.exception.TrailingJunk: print("There were octets in the message past the end of the proper DNS message.", file=sys.stderr) raise except dns.exception.BadEDNS: print("An OPT record was in the wrong section, or occurred more than once.", file=sys.stderr) raise except dns.exception.BadTSIG: print("A TSIG record was not the last record of the additional data section.", file=sys.stderr) raise message_id = message.id flags = [] for flag in dns.flags.to_text(message.flags).split(): flags.append(flag) flags.append(dns.opcode.to_text(message.opcode())) flags.append(dns.rcode.to_text(message.rcode())) total_questions = len(message.question) total_answer_rrs = len(message.answer) total_authority_rrs = len(message.authority) total_additional_rrs = len(message.additional) questions = [] for question in message.question: questions.append({"name": question.name.to_text(), "type": dns.rdatatype.to_text(question.rdtype), "class": dns.rdataclass.to_text(question.rdclass)}) answer_rrs = [] for answer in message.answer: rdata_items = [] for item in answer.items: rdata_items.append(item.to_text()) answer_rrs.append({"name": answer.name.to_text(), "type": dns.rdatatype.to_text(answer.rdtype), "class": dns.rdataclass.to_text(answer.rdclass), "ttl": answer.ttl, "rdata_length": len(answer.items), "rdata": rdata_items}) authority_rrs = [] for authority in message.authority: rdata_items = [] for item in authority.items: rdata_items.append(item.to_text()) authority_rrs.append({"name": authority.name.to_text(), "type": dns.rdatatype.to_text(dnsauthority.rdtype), "class": dns.rdataclass.to_text(authority.rdclass), "ttl": authority.ttl, "rdata_length": len(authority.items), "rdata": rdata_items}) additional_rrs = [] for additional in message.additional: rdata_items = [] for item in additional.items: rdata_items.append(item.to_text()) additional_rrs.append({"name": additional.name.to_text(), "type": dns.rdatatype.to_text(additional.rdtype), "class": dns.rdataclass.to_text(additional.rdclass), "ttl": additional.ttl, "rdata_length": len(additional.items), "rdata": rdata_items}) return (message_id, flags, total_questions, total_answer_rrs, total_authority_rrs, total_additional_rrs, questions, answer_rrs, authority_rrs, additional_rrs)