Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
        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
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
        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
Ejemplo n.º 7
0
    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)