示例#1
0
    def CheckForClientSubnetOption(addr, args, option_code=ASSIGNED_OPTION_CODE):
        print("Testing for edns-clientsubnet using option code", hex(option_code), file=sys.stderr)
        cso = ClientSubnetOption(args.subnet, args.mask, option=option_code)
        message = dns.message.make_query(args.rr, args.type)
        # Tested authoritative servers seem to use the last code in cases
        # where they support both. We make the official code last to allow
        # us to check for support of both draft and official
        message.use_edns(options=[cso])

        if args.recursive:
            message.flags = message.flags | dns.flags.RD

        try:
            r = dns.query.udp(message, addr, timeout=args.timeout)
            if r.flags & dns.flags.TC:
                r = dns.query.tcp(message, addr, timeout=args.timeout)
        except dns.exception.Timeout:
            print("Timeout: No answer received from %s\n" % args.nameserver, file=sys.stderr)
            return

        error = False
        found = False
        for options in r.options:
            # Have not run into anyone who passes back both codes yet
            # but just in case, we want to check all possible options
            if isinstance(options, ClientSubnetOption):
                found = True
                print("Found ClientSubnetOption...", end=None, file=sys.stderr)
                if not cso.family == options.family:
                    error = True
                    print("\nFailed: returned family (%d) is different from the passed family (%d)" % (options.family, cso.family), file=sys.stderr)
                if not cso.calculate_ip() == options.calculate_ip():
                    error = True
                    print("\nFailed: returned ip (%s) is different from the passed ip (%s)." % (options.calculate_ip(), cso.calculate_ip()), file=sys.stderr)
                if not options.mask == cso.mask:
                    error = True
                    print("\nFailed: returned mask bits (%d) is different from the passed mask bits (%d)" % (options.mask, cso.mask), file=sys.stderr)
                if not options.scope != 0:
                    print("\nWarning: scope indicates edns-clientsubnet data is not used", file=sys.stderr)
                if options.is_draft():
                    print("\nWarning: detected support for edns-clientsubnet draft code", file=sys.stderr)

        if found and not error:
            print("Success", file=sys.stderr)
        elif found:
            print("Failed: See error messages above", file=sys.stderr)
        else:
            print("Failed: No ClientSubnetOption returned", file=sys.stderr)
示例#2
0
    def CheckForClientSubnetOption(addr, args, option_code=ASSIGNED_OPTION_CODE):
        print("Testing for edns-clientsubnet using option code", hex(option_code), file=sys.stderr)
        cso = ClientSubnetOption(args.subnet, args.mask, option=option_code)
        message = dns.message.make_query(args.rr, args.type)
        # Tested authoritative servers seem to use the last code in cases
        # where they support both. We make the official code last to allow
        # us to check for support of both draft and official
        message.use_edns(options=[cso])

        try:
            r = dns.query.udp(message, addr, timeout=args.timeout)
            if r.flags & dns.flags.TC:
                r = dns.query.tcp(message, addr, timeout=args.timeout)
        except dns.exception.Timeout:
            print("Timeout: No answer received from %s\n" % args.nameserver, file=sys.stderr)
            sys.exit(3)

        error = False
        found = False
        for options in r.options:
            # Have not run into anyone who passes back both codes yet
            # but just in case, we want to check all possible options
            if isinstance(options, ClientSubnetOption):
                found = True
                print("Found ClientSubnetOption...", end=None, file=sys.stderr)
                if not cso.family == options.family:
                    error = True
                    print("\nFailed: returned family (%d) is different from the passed family (%d)" % (options.family, cso.family), file=sys.stderr)
                if not cso.calculate_ip() == options.calculate_ip():
                    error = True
                    print("\nFailed: returned ip (%s) is different from the passed ip (%s)." % (options.calculate_ip(), cso.calculate_ip()), file=sys.stderr)
                if not options.mask == cso.mask:
                    error = True
                    print("\nFailed: returned mask bits (%d) is different from the passed mask bits (%d)" % (options.mask, cso.mask), file=sys.stderr)
                if not options.scope != 0:
                    print("\nWarning: scope indicates edns-clientsubnet data is not used", file=sys.stderr)
                if options.is_draft():
                    print("\nWarning: detected support for edns-clientsubnet draft code", file=sys.stderr)

        if found and not error:
            print("Success", file=sys.stderr)
        elif found:
            print("Failed: See error messages above", file=sys.stderr)
        else:
            print("Failed: No ClientSubnetOption returned", file=sys.stderr)
        else:
            print "'%s' doesn't look like an IP to me..." % sys.argv[3]
            sys.exit(1)
    else:
        family = 1
        ip = 0xC0000200

    if len(sys.argv) == 5:
        mask = int(sys.argv[4])
    else:
        if family == 2:
            mask = 48
        else:
            mask = 24

    addr = socket.gethostbyname(sys.argv[1])
    cso = ClientSubnetOption(family, ip, mask)

    message = dns.message.make_query(sys.argv[2], "A")
    message.use_edns(options=[cso])
    r = dns.query.udp(message, addr)
    if r.flags & dns.flags.TC:
        r = dns.query.tcp(message, addr)
    for options in r.options:
        if isinstance(options, ClientSubnetOption):
            assert cso.family == options.family, "returned family (%d) is different from the passed family (%d)" % (options.family, cso.family)
            assert cso.calculate_ip() == options.calculate_ip(), "returned ip (%s) is different from then passed  ip(%s)." % (options.calculate_ip(), cso.calculate_ip())
            assert options.mask == cso.mask, "returned mask bits (%d) is different from the passed mask bits (%d)" % (options.mask, cso.mask)
            assert options.scope != 0, "scope indicates edns-clientsubnet data is not used"
            print "Success!"
示例#4
0
def do_edns_c_query(resolver,ip,family,mask,query, timeout=1.0):

    # ip - client_ip to fake
    # family - IP-family (int)
    # mask - mask to send (int)
    # query - name to query

    dns.edns._type_to_class[0x0008] = ClientSubnetOption

    #client_ip_str=socket.inet_ntoa(struct.pack('!L',ip))
    #lprefix = "%s %s %s %d -" % (resolver,query,client_ip_str,mask)
    lprefix=ip

    cso = ClientSubnetOption(family, ip, mask)
    message = dns.message.make_query(query, "A")
    message.use_edns(options=[cso])


    # NOTE: THis is not forgiving! No TCP fallback!
    #try:

    r = dns.query.udp(message, resolver,timeout=timeout)


    if r.flags & dns.flags.TC:
        logger.debug( "D: %s udp flag TC, trying tcp" % lprefix )
        try:
            r = dns.query.tcp(message, resolver)
            #UTO - TCPOK
        except socket.error:
            logger.error( "E: %s tcp refused after TC flag set" % lprefix )
            raise ednsException("tcp refused after TC flag set")

    #    #else:
    #        # UDPOK
    #except dns.exception.Timeout:
    #    logger.debug( "D: %s udp timeout, trying tcp" % lprefix )
    #    try:
    #        r = dns.query.tcp(message, resolver)
    #        # TCPON
    #    except socket.error:
    #        logger.error( "E: %s tcp refused too" % lprefix )
    #        raise ednsException("tcp refused after udp timeout")


    records=[]
    for answers in r.answer:
        for item in answers.items:
            # there seems no generic way to get the payload, except using to_text
            # but that does not include the type of RR (e.g. CNAME)
            records.append( "%s %s %s" % (item.rdclass,item.rdtype,item.to_text() ) )

    response={}

    have_csn = False
    for options in r.options:
        if isinstance(options, ClientSubnetOption):
            have_csn=True
            response['client_ip']     = cso.ip
            response['client_family'] = cso.family
            response['client_mask']   = cso.mask
            response['client_scope']  = options.scope

    if not have_csn:
        logger.error( "E: %s clientsubnet: FALSE" % lprefix )
        raise ednsException("No csn option")

    #logger.debug (  "D: %s %s" % ( lprefix, str(r).splitlines() ) )
    response['rcode'] = r.rcode()
    response['dns_results'] = r
    response['records'] = records
    return response
示例#5
0
文件: edns.py 项目: atwenzel/395s16
def do_edns_c_query(resolver,ip,family,mask,query, timeout=1.0):

    # ip - client_ip to fake
    # family - IP-family (int)
    # mask - mask to send (int)
    # query - name to query

    dns.edns._type_to_class[0x0008] = ClientSubnetOption

    #client_ip_str=socket.inet_ntoa(struct.pack('!L',ip))
    #lprefix = "%s %s %s %d -" % (resolver,query,client_ip_str,mask)
    lprefix=ip

    cso = ClientSubnetOption(family, ip, mask)
    message = dns.message.make_query(query, "A")
    message.use_edns(options=[cso])

    
    # NOTE: THis is not forgiving! No TCP fallback!
    #try:

    r = dns.query.udp(message, resolver,timeout=timeout)


    if r.flags & dns.flags.TC:
        logger.debug( "D: %s udp flag TC, trying tcp" % lprefix )
        try:
            r = dns.query.tcp(message, resolver)
            #UTO - TCPOK
        except socket.error:
            logger.error( "E: %s tcp refused after TC flag set" % lprefix )
            raise ednsException("tcp refused after TC flag set")

    #    #else:
    #        # UDPOK
    #except dns.exception.Timeout:
    #    logger.debug( "D: %s udp timeout, trying tcp" % lprefix )
    #    try:
    #        r = dns.query.tcp(message, resolver)
    #        # TCPON
    #    except socket.error:
    #        logger.error( "E: %s tcp refused too" % lprefix )
    #        raise ednsException("tcp refused after udp timeout")


    records=[]
    for answers in r.answer:
        for item in answers.items:
            # there seems no generic way to get the payload, except using to_text
            # but that does not include the type of RR (e.g. CNAME)
            records.append( "%s %s %s" % (item.rdclass,item.rdtype,item.to_text() ) )

    response={}

    have_csn = False
    for options in r.options:
        if isinstance(options, ClientSubnetOption):
            have_csn=True
            response['client_ip']     = cso.ip
            response['client_family'] = cso.family
            response['client_mask']   = cso.mask
            response['client_scope']  = options.scope

    if not have_csn:
        logger.error( "E: %s clientsubnet: FALSE" % lprefix )
        raise ednsException("No csn option")

    #logger.debug (  "D: %s %s" % ( lprefix, str(r).splitlines() ) )
    response['rcode'] = r.rcode()
    response['dns_results'] = r
    response['records'] = records
    return response