Пример #1
0
def genError(rcode, data):
    #-------------------------------------------------------------------------------
    ## generate header
    packet = pbf.BitField(12)
    packet[:2] = data[:2]
    packet[2] = 0x81
    packet[3] = 0x80 | rcode
    return packet
Пример #2
0
def genCNAME(name):
    #-------------------------------------------------------------------------------
    msg = pbf.BitField([])
    for lbl in name.split('.'):
        msg.append(len(lbl))  ## set length of this label
        msg.extend(bytes(lbl))  ## add the label
    msg.append(0)  ## add the zero length root label
    return msg
Пример #3
0
def main(argv):
    #-------------------------------------------------------------------------------
    args, opts = oss.gopt(argv[1:], [], [])

    #
    # set up database creating reverse mappings and some aliases
    #
    db = dict(DNS_DATABASE)
    for name, addr in DNS_DATABASE.items():
        a, b, c, d = addr.split('.')
        db[d + '.' + c + '.' + b + '.' + a + '.in-addr.arpa.'] = (name +
                                                                  '.work.', 1)
        db[name + '.work.'] = (addr, 0)
        db['m' + d + '.work.'] = (addr, 0)
        db['h' + d + '.work.'] = (addr, 0)

    pprint.pprint(db)
    print()

    ## start server
    udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udps.bind(('', 53))

    try:
        while 1:
            data, addr = udps.recvfrom(1024)
            data = pbf.BitField(data)

            opcode, query = getQuery(data)
            query = unicode(query)

            print('---\nQuery: ', opcode, '-> "%s"' % query)

            if opcode != 0:
                udps.sendto(genError(4, data), addr)
                continue

            if query in db:
                ip_name, ptr = db[query]
                resp = genResponse(ip_name, ptr, data)
                udps.sendto(resp, addr)
                print('Response: %s -> %s' % (query, ip_name))

            else:
                err, aa, addrs, aliases = dns.sendDNSQuery(
                    query[:-1], '192.168.1.1')
                if err == 0:
                    resp = genResponse(addrs[0], 0, data)
                    udps.sendto(resp, addr)
                    print('Response: %s -> %s' % (query, addrs[0]))
                else:
                    udps.sendto(genError(3, data), addr)

    except KeyboardInterrupt:
        udps.close()

    oss.exit(0)
Пример #4
0
def genResponse(ip_name, ptrRec, data):
    #-------------------------------------------------------------------------------
    packet = pbf.BitField(12)

    aRec = not ptrRec

    ## generate header
    packet[:2] = data[:2]
    packet[2] = 0x84
    packet[3] = 0x80
    packet.setM(4, 2, 1)
    packet.setM(6, 2, 1)

    ## copy original question
    packet.extend(data[12:])

    ## create answer
    packet.append(0xc0)  # use pointer
    packet.append(0x0c)  # to domain name in question
    packet.append(0)  # root

    if aRec:
        packet.append(1)  # response type - A record
    else:
        packet.append(12)  # response type - PTR record

    packet.addM(2, 1)  # class (IN)
    packet.addM(4, 0xa5a5a5a5)  # ttl

    if aRec:
        packet.addM(2, 4)  # rdata_length
        packet.extend([int(x) for x in ip_name.split('.')])
    else:
        name = dns.genCNAME(ip_name)
        packet.addM(2, len(name))  # rdata_length
        packet.extend(dns.genCNAME(ip_name))

    return packet
Пример #5
0
def sendDNSQuery(name, nameServerIPAddr, dump=False):
    #-------------------------------------------------------------------------------
    id = random.randint(0, 2**16 - 1)
    msg = pbf.BitField(12)

    msg.setM(0, 2, id)  ## set the id
    msg.setBit(2, 0, 1)  ## set recursion request
    msg.setM(4, 2, 1)  ## set query count to 1

    for lbl in name.split('.'):
        msg.append(len(lbl))  ## set length of this label
        msg.extend(bytes(lbl))  ## add the label
    msg.append(0)  ## add the zero length root label

    msg.addM(2, 1)  ## set qtype
    msg.addM(2, 1)  ## set qclass

    if dump:
        print('Sent packet:')
        msg.hexDump()
        print()

    ## send packet
    udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udps.sendto(msg, (nameServerIPAddr, 53))

    ## get packet
    data = pbf.BitField(udps.recv(1024))

    ## ensure it is the correct request
    if id == data.getM(0, 2):
        if dump:
            print('Recved packet:')
            pbf.hexDump(data)
            print()

        #print('QR:', data.getBit(2, 7))
        AA = data.getBit(2, 2)
        #print('AA:', data.getBit(2, 2))
        #print('RD:', data.getBit(2, 0))
        #print('RA:', data.getBit(3, 7))
        #print('Opcode:', data.getBits(3, 3, 6))

        rcode = data.getBits(3, 0, 3)
        #print('RCODE:', rcode)

        if dump:
            print('Q records:', data.getM(4, 2))
            print('A records:', data.getM(6, 2))
            print('NS records:', data.getM(8, 2))
            print('Additional records:', data.getM(10, 2))

        if rcode != 0:
            return rcode, 0, [], []

        ## get question records
        for i in range(data.getM(4, 2)):
            idx, name = getCNAME(12, data)
            idx += 5

        ## get answers
        idx, ipaddrs, aliases = getAnswerRecords(idx, data)

        if dump:
            print()
            pbf.hexDump(data[idx:])
            print()

            for i in range(data.getM(8, 2)):
                idx, name = getCNAME(idx, data)
                print('NS:', name)

            print()
            pbf.hexDump(data[idx:])
            print()

        return 0, AA, ipaddrs, aliases