Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package dnsdiag for openSUSE:Factory checked in at 2024-07-01 11:20:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dnsdiag (Old) and /work/SRC/openSUSE:Factory/.dnsdiag.new.18349 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "dnsdiag" Mon Jul 1 11:20:27 2024 rev:7 rq:1184040 version:2.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/dnsdiag/dnsdiag.changes 2023-02-08 17:21:03.850170245 +0100 +++ /work/SRC/openSUSE:Factory/.dnsdiag.new.18349/dnsdiag.changes 2024-07-01 11:21:02.064512003 +0200 @@ -1,0 +2,18 @@ +Thu Jun 20 12:16:30 UTC 2024 - Martin Hauke <mardnh@gmx.de> + +- Update to version 2.5.0 + * Add RFC5001 NSID support (-n or --nsid). + * Display RFC8914 Extended DNS Errors when available (-E or --ede) + * Add ability to override default RR class (-C or --class). + * Display response TTL if applicable (-L or --ttl). + * Display first answer in RRSET, when available (-a or --answer). + * Add -x to display extra/expert information, implying Flags, EDE + and TTL. + * Display EDNS flags alongside other response flags, when available + * Always display RCODE with responses. + * Add more resolvers to the default list. + * Lots of bug fixes and UX improvements. + * Change default behavior of --edns to disabled by default. + * Always display flags in brackets. + +------------------------------------------------------------------- Old: ---- dnsdiag-2.1.0.tar.gz New: ---- dnsdiag-2.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dnsdiag.spec ++++++ --- /var/tmp/diff_new_pack.p848te/_old 2024-07-01 11:21:02.632532696 +0200 +++ /var/tmp/diff_new_pack.p848te/_new 2024-07-01 11:21:02.632532696 +0200 @@ -1,8 +1,8 @@ # # spec file for package dnsdiag # -# Copyright (c) 2023 SUSE LLC -# Copyright (c) 2017-2023, Martin Hauke <mardnh@gmx.de> +# Copyright (c) 2024 SUSE LLC +# Copyright (c) 2017-2024, Martin Hauke <mardnh@gmx.de> # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %bcond_without test Name: dnsdiag -Version: 2.1.0 +Version: 2.5.0 Release: 0 Summary: DNS request auditing toolset License: BSD-3-Clause @@ -33,13 +33,15 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros BuildRequires: python3-setuptools +Requires: python3-cryptography >= 42.0.7 Requires: python3-cymruwhois >= 1.6 -Requires: python3-dnspython >= 2.3.0 -Requires: python3-setuptools +Requires: python3-dnspython >= 2.6.1 +Requires: python3-h2 >= 4.1.0 +Requires: python3-httpx >= 0.27.0 BuildArch: noarch %if %{with test} BuildRequires: python3-cymruwhois >= 1.6 -BuildRequires: python3-dnspython >= 2.3.0 +BuildRequires: python3-dnspython >= 2.6.1 %endif %description @@ -64,6 +66,7 @@ %prep %setup -q -n dnsdiag-%{version} +sed -e '/^#!\//, 1d' -i util/*.py %build %python3_build ++++++ dnsdiag-2.1.0.tar.gz -> dnsdiag-2.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/LICENSE new/dnsdiag-2.5.0/LICENSE --- old/dnsdiag-2.1.0/LICENSE 2020-01-18 10:44:22.000000000 +0100 +++ new/dnsdiag-2.5.0/LICENSE 2024-05-31 14:28:10.000000000 +0200 @@ -1,4 +1,4 @@ -Copyright (c) 2020, Babak Farrokhi +Copyright (c) 2024, Babak Farrokhi All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/PKG-INFO new/dnsdiag-2.5.0/PKG-INFO --- old/dnsdiag-2.1.0/PKG-INFO 2023-02-01 14:48:49.904830000 +0100 +++ new/dnsdiag-2.5.0/PKG-INFO 2024-06-18 19:25:51.963563200 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: dnsdiag -Version: 2.1.0 +Version: 2.5.0 Summary: DNS Measurement, Troubleshooting and Security Auditing Toolset (ping, traceroute) Home-page: https://dnsdiag.org/ Author: Babak Farrokhi @@ -11,14 +11,21 @@ Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: Name Service (DNS) Classifier: Development Status :: 5 - Production/Stable Classifier: Operating System :: OS Independent License-File: LICENSE +Requires-Dist: dnspython>=2.6.1 +Requires-Dist: cymruwhois>=1.6 +Requires-Dist: httpx>=0.27.0 +Requires-Dist: cryptography>=42.0.7 +Requires-Dist: h2>=4.1.0 DNSDiag provides a handful of tools to measure and diagnose your DNS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/README.md new/dnsdiag-2.5.0/README.md --- old/dnsdiag-2.1.0/README.md 2023-02-01 14:16:46.000000000 +0100 +++ new/dnsdiag-2.5.0/README.md 2024-06-15 15:16:23.000000000 +0200 @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/farrokhi/dnsdiag.svg)](https://travis-ci.org/farrokhi/dnsdiag) [![PyPI](https://img.shields.io/pypi/v/dnsdiag.svg?maxAge=8600)](https://pypi.python.org/pypi/dnsdiag/) [![PyPI](https://img.shields.io/pypi/l/dnsdiag.svg?maxAge=8600)]() [![Downloads](https://static.pepy.tech/personalized-badge/dnsdiag?period=total&units=international_system&left_color=grey&right_color=blue&left_text=PyPi%20Downloads)](https://pepy.tech/project/dnsdiag) [![PyPI](https://img.shields.io/pypi/pyversions/dnsdiag.svg?maxAge=8600)]() [![Docker Pulls](https://img.shields.io/docker/pulls/farrokhi/dnsdiag)](https://hub.docker.com/r/farrokhi/dnsdiag) [![GitHub stars](https://img.shields.io/github/stars/farrokhi/dnsdiag.svg?style=social&label=Star&maxAge=8600)](https://github.com/farrokhi/dnsdiag/stargazers) +[![PyPI](https://img.shields.io/pypi/v/dnsdiag.svg?maxAge=8600)](https://pypi.python.org/pypi/dnsdiag/) [![PyPI](https://img.shields.io/pypi/l/dnsdiag.svg?maxAge=8600)]() [![Downloads](https://static.pepy.tech/personalized-badge/dnsdiag?period=total&units=international_system&left_color=grey&right_color=blue&left_text=PyPi%20Downloads)](https://pepy.tech/project/dnsdiag) [![PyPI](https://img.shields.io/pypi/pyversions/dnsdiag.svg?maxAge=8600)]() [![Docker Pulls](https://img.shields.io/docker/pulls/farrokhi/dnsdiag)](https://hub.docker.com/r/farrokhi/dnsdiag) [![GitHub stars](https://img.shields.io/github/stars/farrokhi/dnsdiag.svg?style=social&label=Star&maxAge=8600)](https://github.com/farrokhi/dnsdiag/stargazers) DNS Measurement, Troubleshooting and Security Auditing Toolset =============================================================== @@ -62,26 +62,28 @@ A complete explanation of supported command line flags is shown by using `--help`. Here are a few useful flags: - Using `--tcp`, `--tls` and `--doh` to select transport protocol. Default is UDP. -- Using `--flags` to display response flags for each response +- Using `--flags` to display response flags (including EDNS flags) for each response - Using `--dnssec` to request DNSSEC if available +- Using `--ede` to display Extended DNS Error messages ([RFC 8914](https://www.rfc-editor.org/rfc/rfc8914)) +- Using `--nsid` to display Name Server Identifier (NSID) if available ([RFC 5001](https://www.rfc-editor.org/rfc/rfc5001)) In addition to UDP, you can ping using TCP, DoT (DNS over TLS) and DoH (DNS over HTTPS) using `--tcp`, `--tls` and `--doh` respectively. ```shell -./dnsping.py -c 5 --dnssec --flags --tls -t AAAA -s 9.9.9.9 ripe.net +./dnsping.py -c 5 --dnssec --flags --tls --ede -t AAAA -s 8.8.8.8 brokendnssec.net ``` ``` -dnsping.py DNS: 9.9.9.9:853, hostname: ripe.net, proto: TLS, rdatatype: AAAA, flags: RD -169 bytes from 9.9.9.9: seq=1 time=279.805 ms [QR RD RA AD] NOERROR -169 bytes from 9.9.9.9: seq=2 time=107.237 ms [QR RD RA AD] NOERROR -169 bytes from 9.9.9.9: seq=3 time=96.747 ms [QR RD RA AD] NOERROR -169 bytes from 9.9.9.9: seq=4 time=107.782 ms [QR RD RA AD] NOERROR -169 bytes from 9.9.9.9: seq=5 time=94.713 ms [QR RD RA AD] NOERROR +dnsping.py DNS: 8.8.8.8:853, hostname: brokendnssec.net, proto: TLS, class: IN, type: AAAA, flags: [RD] +75 bytes from 8.8.8.8: seq=1 time=113.631 ms [QR RD RA DO] SERVFAIL [EDE 10: For brokendnssec.net/soa] +75 bytes from 8.8.8.8: seq=2 time=115.479 ms [QR RD RA DO] SERVFAIL [EDE 10: For brokendnssec.net/soa] +75 bytes from 8.8.8.8: seq=3 time=90.882 ms [QR RD RA DO] SERVFAIL [EDE 10: For brokendnssec.net/soa] +75 bytes from 8.8.8.8: seq=4 time=91.256 ms [QR RD RA DO] SERVFAIL [EDE 10: For brokendnssec.net/soa] +75 bytes from 8.8.8.8: seq=5 time=94.072 ms [QR RD RA DO] SERVFAIL [EDE 10: For brokendnssec.net/soa] ---- 9.9.9.9 dnsping statistics --- +--- 8.8.8.8 dnsping statistics --- 5 requests transmitted, 5 responses received, 0% lost -min=94.713 ms, avg=137.257 ms, max=279.805 ms, stddev=79.908 ms +min=90.882 ms, avg=101.064 ms, max=115.479 ms, stddev=12.394 ms ``` It also displays statistics such as minimum, maximum and average response time as well as @@ -169,9 +171,10 @@ Babak Farrokhi -- twitter: [@farrokhi](https://twitter.com/farrokhi) - github: [github.com/farrokhi](https://github.com/farrokhi/) - website: [farrokhi.net](https://farrokhi.net/) +- mastodon: [@farrokhi@unix.family](https://unix.family/@farrokhi) +- twitter: [@farrokhi](https://twitter.com/farrokhi) ### License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/dnsdiag.egg-info/PKG-INFO new/dnsdiag-2.5.0/dnsdiag.egg-info/PKG-INFO --- old/dnsdiag-2.1.0/dnsdiag.egg-info/PKG-INFO 2023-02-01 14:48:49.000000000 +0100 +++ new/dnsdiag-2.5.0/dnsdiag.egg-info/PKG-INFO 2024-06-18 19:25:51.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: dnsdiag -Version: 2.1.0 +Version: 2.5.0 Summary: DNS Measurement, Troubleshooting and Security Auditing Toolset (ping, traceroute) Home-page: https://dnsdiag.org/ Author: Babak Farrokhi @@ -11,14 +11,21 @@ Classifier: Environment :: Console Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Topic :: Internet :: Name Service (DNS) Classifier: Development Status :: 5 - Production/Stable Classifier: Operating System :: OS Independent License-File: LICENSE +Requires-Dist: dnspython>=2.6.1 +Requires-Dist: cymruwhois>=1.6 +Requires-Dist: httpx>=0.27.0 +Requires-Dist: cryptography>=42.0.7 +Requires-Dist: h2>=4.1.0 DNSDiag provides a handful of tools to measure and diagnose your DNS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/dnsdiag.egg-info/requires.txt new/dnsdiag-2.5.0/dnsdiag.egg-info/requires.txt --- old/dnsdiag-2.1.0/dnsdiag.egg-info/requires.txt 2023-02-01 14:48:49.000000000 +0100 +++ new/dnsdiag-2.5.0/dnsdiag.egg-info/requires.txt 2024-06-18 19:25:51.000000000 +0200 @@ -1,4 +1,5 @@ -dnspython>=2.3.0 +dnspython>=2.6.1 cymruwhois>=1.6 -requests>=2.28.2 -requests-toolbelt>=0.9.1 +httpx>=0.27.0 +cryptography>=42.0.7 +h2>=4.1.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/dnseval.py new/dnsdiag-2.5.0/dnseval.py --- old/dnsdiag-2.1.0/dnseval.py 2023-02-01 13:35:46.000000000 +0100 +++ new/dnsdiag-2.5.0/dnseval.py 2024-06-17 23:12:23.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2016-2023, Babak Farrokhi +# Copyright (c) 2016-2024, Babak Farrokhi # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -63,8 +63,8 @@ -H --doh Use HTTPS as transport protols (DoH) -p --port DNS server port number (default: 53 for TCP/UDP and 853 for TLS) -S --srcip Query source IP address - -e --edns Disable EDNS0 (default: Enabled) - -D --dnssec Enable 'DNSSEC desired' flag in requests. + -e --edns Enable EDNS0 + -D --dnssec Enable 'DNSSEC desired' (DO flag) in requests -C --color Print colorful output -v --verbose Print actual dns response """ % (__progname__, __version__, __progname__)) @@ -92,7 +92,7 @@ inputfilename = None fromfile = False json_output = False - use_edns = True + use_edns = False want_dnssec = False force_miss = False verbose = False @@ -100,9 +100,9 @@ qname = 'wikipedia.org' try: - opts, args = getopt.getopt(sys.argv[1:], "hf:c:t:w:S:TevCmXHDj:", + opts, args = getopt.getopt(sys.argv[1:], "hf:c:t:w:S:TevCmXHDj:p:", ["help", "file=", "count=", "type=", "wait=", "json=", "tcp", "edns", "verbose", - "color", "cache-miss", "srcip=", "tls", "doh", "dnssec"]) + "color", "cache-miss", "srcip=", "tls", "doh", "dnssec", "port="]) except getopt.GetoptError as err: print(err) usage() @@ -134,19 +134,20 @@ json_output = True json_filename = a elif o in ("-e", "--edns"): - use_edns = False + use_edns = True elif o in ("-D", "--dnssec"): want_dnssec = True + use_edns = True # implied elif o in ("-C", "--color"): color_mode = True elif o in ("-v", "--verbose"): verbose = True elif o in ("-X", "--tls"): proto = PROTO_TLS - dst_port = 853 # default for DoT, unless overriden using -p + dst_port = 853 # default for DoT, unless overridden using -p elif o in ("-H", "--doh"): proto = PROTO_HTTPS - dst_port = 443 # default for DoH, unless overriden using -p + dst_port = 443 # default for DoH, unless overridden using -p elif o in ("-p", "--port"): dst_port = int(a) @@ -154,6 +155,11 @@ print("Invalid option: %s" % o) usage() + # validate RR type + if not util.dns.valid_rdatatype(rdatatype): + print('Error: Invalid record type "%s" ' % rdatatype) + sys.exit(1) + color = Colors(color_mode) try: @@ -173,7 +179,7 @@ f = dns.resolver.get_default_resolver().nameservers if len(f) == 0: - print("No nameserver specified") + print("Error: No nameserver specified") f = [name.strip() for name in f] # remove annoying blanks f = [x for x in f if not x.startswith('#') and len(x)] # remove comments and empty entries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/dnsping.py new/dnsdiag-2.5.0/dnsping.py --- old/dnsdiag-2.1.0/dnsping.py 2023-02-01 14:12:27.000000000 +0100 +++ new/dnsdiag-2.5.0/dnsping.py 2024-06-18 15:37:52.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2016-2023, Babak Farrokhi +# Copyright (c) 2016-2024, Babak Farrokhi # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -33,12 +33,13 @@ import socket import sys import time +import httpx from statistics import stdev import dns.flags import dns.resolver -import requests +import util.dns from util.dns import PROTO_UDP, PROTO_TCP, PROTO_TLS, PROTO_HTTPS, proto_to_text, unsupported_feature, random_string from util.shared import __version__ @@ -50,7 +51,8 @@ def usage(): print("""%s version %s -usage: %s [-46DeFhqTvX] [-i interval] [-s server] [-p port] [-P port] [-S address] [-c count] [-t type] [-w wait] hostname +usage: %s [-46aDeEFhLmqnrvTxXH] [-i interval] [-w wait] [-p dst_port] [-P src_port] [-S src_ip] + %s [-c count] [-t qtype] [-C class] [-s server] hostname -h --help Show this help -q --quiet Quiet @@ -70,10 +72,16 @@ -w --wait Maximum wait time for a reply (default: 2 seconds) -i --interval Time between each request (default: 1 seconds) -t --type DNS request record type (default: A) - -e --edns Disable EDNS0 (default: Enabled) + -L --ttl Display response TTL (if present) + -C --class DNS request record class (default: IN) + -a --answer Display first matching answer in rdata, if applicable + -e --edns Enable EDNS0 and set + -E --ede Display EDE messages when available + -n --nsid Enable NSID bit to find out identification of the resolver. Implies EDNS. -D --dnssec Enable 'DNSSEC desired' flag in requests. Implies EDNS. -F --flags Display response flags -""" % (__progname__, __version__, __progname__)) + -x --expert Display extra information. Implies --ttl --flags --ede. +""" % (__progname__, __version__, __progname__, ' ' * len(__progname__))) sys.exit(0) @@ -92,6 +100,12 @@ shutdown = True # pressed once, exit gracefully +def print_stderr(s, should_die): + print(s, file=sys.stderr, flush=True) + if should_die: + sys.exit(1) + + def validate_server_address(dnsserver, address_family): """checks if we have a valid dns server address and resolve if it is a hostname""" @@ -101,8 +115,7 @@ try: dnsserver = socket.getaddrinfo(dnsserver, port=None, family=address_family)[1][4][0] except OSError: - print('Error: cannot resolve hostname:', dnsserver, file=sys.stderr, flush=True) - sys.exit(1) + print_stderr('Error: cannot resolve hostname: %s' % dnsserver, True) return dnsserver @@ -114,32 +127,38 @@ # defaults rdatatype = 'A' + rdata_class = dns.rdataclass.from_text('IN') count = 10 timeout = 2 interval = 1 quiet = False verbose = False show_flags = False + show_ede = False dnsserver = None # do not try to use system resolver by default dst_port = 53 # default for UDP and TCP src_port = 0 src_ip = None proto = PROTO_UDP - use_edns = True + use_edns = False + want_nsid = False want_dnssec = False + show_ttl = False force_miss = False + show_answer = False request_flags = dns.flags.from_text('RD') af = socket.AF_INET qname = 'wikipedia.org' try: - opts, args = getopt.getopt(sys.argv[1:], "qhc:s:t:w:i:vp:P:S:T46meDFXHr", + opts, args = getopt.getopt(sys.argv[1:], "qhc:s:t:w:i:vp:P:S:T46meDFXHrnEC:Lxa", ["help", "count=", "server=", "quiet", "type=", "wait=", "interval=", "verbose", "port=", "srcip=", "tcp", "ipv4", "ipv6", "cache-miss", "srcport=", "edns", - "dnssec", "flags", "norecurse", "tls", "doh"]) + "dnssec", "flags", "norecurse", "tls", "doh", "nsid", "ede", "class=", "ttl", + "expert", "answer"]) except getopt.GetoptError as err: # print help information and exit: - print(err, file=sys.stderr) # will print something like "option -a not recognized" + print_stderr(err, False) # will print something like "option -a not recognized" usage() if args and len(args) == 1: @@ -151,7 +170,10 @@ if o in ("-h", "--help"): usage() elif o in ("-c", "--count"): - count = abs(int(a)) + if a.isdigit(): + count = abs(int(a)) + else: + print_stderr("Invalid count of requests: %s" % a, True) elif o in ("-v", "--verbose"): verbose = True elif o in ("-s", "--server"): @@ -161,38 +183,58 @@ verbose = False elif o in ("-w", "--wait"): timeout = int(a) + elif o in ("-a", "--answer"): + show_answer = True + elif o in ("-x", "--expert"): + show_flags = True + show_ede = True + show_ttl = True elif o in ("-m", "--cache-miss"): force_miss = True elif o in ("-i", "--interval"): interval = float(a) + elif o in ("-L", "--ttl"): + show_ttl = True elif o in ("-t", "--type"): rdatatype = a + elif o in ("-C", "--class"): + try: + rdata_class = dns.rdataclass.from_text(a) + except dns.rdataclass.UnknownRdataclass: + print_stderr("Invalid RR class: %s" % a, True) + elif o in ("-T", "--tcp"): proto = PROTO_TCP elif o in ("-X", "--tls"): proto = PROTO_TLS - dst_port = 853 # default for DoT, unless overriden using -p + dst_port = 853 # default for DoT, unless overridden using -p elif o in ("-H", "--doh"): proto = PROTO_HTTPS - dst_port = 443 # default for DoH, unless overriden using -p + dst_port = 443 # default for DoH, unless overridden using -p elif o in ("-4", "--ipv4"): af = socket.AF_INET elif o in ("-6", "--ipv6"): af = socket.AF_INET6 elif o in ("-e", "--edns"): - use_edns = False + use_edns = True + elif o in ("-n", "--nsid"): + use_edns = True # required + want_nsid = True elif o in ("-r", "--norecurse"): request_flags = dns.flags.from_text('') elif o in ("-D", "--dnssec"): + use_edns = True # required want_dnssec = True elif o in ("-F", "--flags"): show_flags = True + elif o in ("-E", "--ede"): + show_ede = True elif o in ("-p", "--port"): dst_port = int(a) elif o in ("-P", "--srcport"): src_port = int(a) - if src_port < 1024: - print("WARNING: Source ports below 1024 are only available to superuser", flush=True) + if src_port < 1024 and not quiet: + print_stderr("WARNING: Source ports below 1024 are only available to superuser", False) elif o in ("-S", "--srcip"): src_ip = a else: @@ -208,9 +250,13 @@ response_time = [] i = 0 - print("%s DNS: %s:%d, hostname: %s, proto: %s, rdatatype: %s, flags: %s" % - (__progname__, dnsserver, dst_port, qname, proto_to_text(proto), rdatatype, - dns.flags.to_text(request_flags)), flush=True) + # validate RR type + if not util.dns.valid_rdatatype(rdatatype): + print_stderr('Error: Invalid record type: %s ' % rdatatype, True) + + print("%s DNS: %s:%d, hostname: %s, proto: %s, class: %s, type: %s, flags: [%s]" % + (__progname__, dnsserver, dst_port, qname, proto_to_text(proto), dns.rdataclass.to_text(rdata_class), + rdatatype, dns.flags.to_text(request_flags)), flush=True) while not shutdown: @@ -225,12 +271,16 @@ fqdn = qname if use_edns: - query = dns.message.make_query(fqdn, rdatatype, dns.rdataclass.IN, flags=request_flags, - use_edns=True, want_dnssec=want_dnssec, - ednsflags=dns.flags.EDNSFlag.DO, payload=8192) + edns_options = [] + if want_nsid: + edns_options.append(dns.edns.GenericOption(dns.edns.NSID, '')) + + query = dns.message.make_query(fqdn, rdatatype, rdata_class, flags=request_flags, + use_edns=True, want_dnssec=want_dnssec, payload=1232, + options=edns_options) else: - query = dns.message.make_query(fqdn, rdatatype, dns.rdataclass.IN, flags=request_flags, - use_edns=False, want_dnssec=want_dnssec) + query = dns.message.make_query(fqdn, rdatatype, rdata_class, flags=request_flags, + use_edns=False, want_dnssec=False) try: stime = time.perf_counter() @@ -257,35 +307,71 @@ etime = time.perf_counter() except dns.resolver.NoNameservers as e: if not quiet: - print("No response to DNS request", file=sys.stderr, flush=True) + print_stderr("No response to DNS request", False) if verbose: - print("error:", e, file=sys.stderr, flush=True) + print_stderr("error: %s" % e, False) sys.exit(1) - except (requests.exceptions.ConnectTimeout, dns.exception.Timeout): + except (httpx.ConnectTimeout, dns.exception.Timeout): if not quiet: print("Request timeout", flush=True) - except requests.exceptions.ReadTimeout: + except httpx.ReadTimeout: if not quiet: print("Read timeout", flush=True) + except PermissionError: + if not quiet: + print_stderr("Permission denied", True) + sys.exit(1) + except OSError as e: + if not quiet: + print_stderr("%s" % e, True) + sys.exit(1) except ValueError: if not quiet: - print("Invalid Response", flush=True) + print_stderr("Invalid Response", False) continue else: # convert time to milliseconds, considering that - # time property is retruned differently by query.https + # time property is returned differently by query.https if type(answers.time) is datetime.timedelta: elapsed = answers.time.total_seconds() * 1000 else: elapsed = answers.time * 1000 response_time.append(elapsed) if not quiet: + extras = "" + extras += " %s" % dns.rcode.to_text(answers.rcode()) # add response code + + if show_ttl: + if answers.answer: + ans_ttl = str(answers.answer[0].ttl) + extras += " [TTL=%-4s]" % ans_ttl + if show_flags: - flags = " [%s] %s" % (dns.flags.to_text(answers.flags), dns.rcode.to_text(answers.rcode())) - else: - flags = "" - print("%d bytes from %s: seq=%-3d time=%-7.3f ms%s" % ( - len(answers.to_wire()), dnsserver, i, elapsed, flags), flush=True) + ans_flags = dns.flags.to_text(answers.flags) + edns_flags = dns.flags.edns_to_text(answers.ednsflags) + extras += " [%s]" % " ".join([ans_flags, edns_flags]).rstrip(' ') # show both regular + edns flags + + if want_nsid: + for ans_opt in answers.options: + if ans_opt.otype == dns.edns.OptionType.NSID: + nsid_val = ans_opt.nsid + extras += " [ID: %s]" % nsid_val.decode("utf-8") + + if show_ede: + for ans_opt in answers.options: # EDE response is optional, but print if there is one + if ans_opt.otype == dns.edns.EDE: + extras += " [EDE %d: %s]" % (ans_opt.code, ans_opt.text) + + if show_answer: # The answer should be displayed at the rightmost + for ans in answers.answer: + if ans.rdtype == dns.rdatatype.from_text(rdatatype): # is this the answer to our question? + # extras += " [%s]" % ans[0] + extras += " [RDATA: %s]" % ans[0] + break + + print("%-3d bytes from %s: seq=%-3d time=%-7.3f ms %s" % ( + len(answers.to_wire()), dnsserver, i, elapsed, extras), flush=True) + if verbose: print(answers.to_text(), flush=True) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/dnstraceroute.py new/dnsdiag-2.5.0/dnstraceroute.py --- old/dnsdiag-2.1.0/dnstraceroute.py 2023-02-01 13:35:46.000000000 +0100 +++ new/dnsdiag-2.5.0/dnstraceroute.py 2024-06-17 19:40:34.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2016-2023, Babak Farrokhi +# Copyright (c) 2016-2024, Babak Farrokhi # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -72,7 +72,7 @@ -w --wait Maximum wait time for a reply (default: 2) -t --type DNS request record type (default: A) -C --color Print colorful output - -e --edns Disable EDNS0 (Default: Enabled) + -e --edns Enable EDNS0 (Default: Disabled) """ % (__progname__, __version__, __progname__)) sys.exit() @@ -110,7 +110,7 @@ print(" %s[*]%s No expert hint available for this trace" % (color.G, color.N)) -def ping(qname, server, rdtype, proto, port, ttl, timeout, src_ip, use_edns=False): +def ping(qname, server, rdtype, proto, port, ttl, timeout, src_ip, use_edns): reached = False resp_time = None @@ -151,7 +151,7 @@ as_lookup = False expert_mode = False should_resolve = True - use_edns = True + use_edns = False color_mode = False args = None @@ -197,12 +197,17 @@ elif o in ("-a", "--asn"): as_lookup = True elif o in ("-e", "--edns"): - use_edns = False + use_edns = True else: usage() color = Colors(color_mode) + # validate RR type + if not util.dns.valid_rdatatype(rdatatype): + print('Error: Invalid record type "%s" ' % rdatatype) + sys.exit(1) + # Use system DNS server if parameter is not specified # remember not all systems have /etc/resolv.conf (i.e. Android) if dnsserver is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/public-servers.txt new/dnsdiag-2.5.0/public-servers.txt --- old/dnsdiag-2.1.0/public-servers.txt 2020-03-08 20:01:12.000000000 +0100 +++ new/dnsdiag-2.5.0/public-servers.txt 2024-06-12 22:28:59.000000000 +0200 @@ -1,24 +1,24 @@ -#Cloudflare +## Cloudflare 1.0.0.1 1.1.1.1 2606:4700:4700::1001 2606:4700:4700::1111 -#SafeDNS +## SafeDNS 195.46.39.39 195.46.39.40 -#OpenDNS +## OpenDNS 208.67.220.220 208.67.222.222 2620:0:ccc::2 2620:0:ccd::2 -#DYN DNS +## DYN DNS 216.146.35.35 216.146.36.36 -#Level3 +## Level3 209.244.0.3 209.244.0.4 4.2.2.1 @@ -27,25 +27,59 @@ 4.2.2.4 4.2.2.5 -#freenom world +## Freenom World 80.80.80.80 80.80.81.81 -#Google +## Google 8.8.4.4 8.8.8.8 2001:4860:4860::8844 2001:4860:4860::8888 -#PCH's Quad9 +## Quad9 9.9.9.9 -2620:fe::fe 149.112.112.112 +2620:fe::fe -#Verisign +## Verisign 64.6.64.6 64.6.65.6 +2620:74:1b::1:1 +2620:74:1c::2:2 -#Comodo +## Comodo 8.26.56.26 8.20.247.20 + +## DNS0.eu +193.110.81.0 +185.253.5.0 +2a0f:fc80:: +2a0f:fc81:: + +## Hurricane Electric +74.82.42.42 +2001:470:20::2 + +## Yandex.DNS +77.88.8.88 +77.88.8.2 +2a02:6b8::feed:bad +2a02:6b8:0:1::feed:bad + +## DNS4all +194.0.5.3 +2001:678:8::3 + +## AdGuard DNS +94.140.14.14 +94.140.15.15 +2a10:50c0::ad1:ff +2a10:50c0::ad2:ff + +## Control D +76.76.2.11 +76.76.10.11 +2606:1a40::11 +2606:1a40:1::11 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/public-v4.txt new/dnsdiag-2.5.0/public-v4.txt --- old/dnsdiag-2.1.0/public-v4.txt 2021-04-03 18:56:18.000000000 +0200 +++ new/dnsdiag-2.5.0/public-v4.txt 2024-06-18 15:30:26.000000000 +0200 @@ -1,19 +1,20 @@ -#Cloudflare +## Cloudflare 1.0.0.1 1.1.1.1 -#SafeDNS +## SafeDNS 195.46.39.39 195.46.39.40 -#OpenDNS +## OpenDNS 208.67.220.220 208.67.222.222 -#DYN DNS +## DYN DNS 216.146.35.35 +216.146.36.36 -#Level3 +## Level3 209.244.0.3 209.244.0.4 4.2.2.1 @@ -22,14 +23,47 @@ 4.2.2.4 4.2.2.5 -#freenom world +## Freenom World 80.80.80.80 80.80.81.81 -#Google +## Google 8.8.4.4 8.8.8.8 -#PCH's Quad9 +## Quad9 9.9.9.9 149.112.112.112 + +## Verisign +64.6.64.6 +64.6.65.6 + +## Comodo +8.26.56.26 +8.20.247.20 + +## DNS0.eu +193.110.81.0 +185.253.5.0 + +## Hurricane Electric +74.82.42.42 + +## Yandex.DNS +77.88.8.88 +77.88.8.2 + +## DNS4all +194.0.5.3 + +## AdGuard DNS +94.140.14.14 +94.140.15.15 + +## Control D +76.76.2.11 +76.76.10.11 + +## Wikimedia DNS (Formerly Wikidough) +185.71.138.138 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/setup.py new/dnsdiag-2.5.0/setup.py --- old/dnsdiag-2.1.0/setup.py 2023-02-01 13:44:12.000000000 +0100 +++ new/dnsdiag-2.5.0/setup.py 2024-05-31 14:46:03.000000000 +0200 @@ -6,16 +6,18 @@ version=__version__, packages=find_packages(), scripts=["dnseval.py", "dnsping.py", "dnstraceroute.py"], - install_requires=['dnspython>=2.3.0', 'cymruwhois>=1.6', 'requests>=2.28.2', 'requests-toolbelt>=0.9.1'], + install_requires=['dnspython>=2.6.1', 'cymruwhois>=1.6', 'httpx>=0.27.0', 'cryptography>=42.0.7', 'h2>=4.1.0'], classifiers=[ "Topic :: System :: Networking", "Environment :: Console", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Internet :: Name Service (DNS)", "Development Status :: 5 - Production/Stable", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/util/dns.py new/dnsdiag-2.5.0/util/dns.py --- old/dnsdiag-2.1.0/util/dns.py 2023-02-01 13:36:24.000000000 +0100 +++ new/dnsdiag-2.5.0/util/dns.py 2024-06-18 08:09:47.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2016-2023, Babak Farrokhi +# Copyright (c) 2016-2024, Babak Farrokhi # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -31,12 +31,12 @@ import sys from statistics import stdev +import httpx import dns.flags import dns.message import dns.query import dns.rcode import dns.rdataclass -import requests.exceptions import string shutdown = False @@ -105,10 +105,9 @@ fqdn = qname if use_edns: - query = dns.message.make_query(fqdn, rdtype, dns.rdataclass.IN, use_edns, want_dnssec, - ednsflags=dns.flags.edns_from_text('DO'), payload=8192) + query = dns.message.make_query(fqdn, rdtype, dns.rdataclass.IN, use_edns, want_dnssec, payload=1232) else: - query = dns.message.make_query(fqdn, rdtype, dns.rdataclass.IN, use_edns, want_dnssec) + query = dns.message.make_query(fqdn, rdtype, dns.rdataclass.IN, use_edns=False, want_dnssec=False) try: if proto is PROTO_UDP: @@ -127,19 +126,21 @@ else: unsupported_feature() - except (requests.exceptions.ConnectTimeout, requests.exceptions.ReadTimeout, - requests.exceptions.ConnectionError): + except (httpx.ConnectTimeout, httpx.ReadTimeout, + httpx.ConnectError): raise ConnectionError('Connection failed') except ValueError: retval.rcode_text = "Invalid Response" break except dns.exception.Timeout: break - except OSError: + except OSError as e: if socket_ttl: # this is an acceptable error while doing traceroute break + print("error: %s"% e.strerror, file=sys.stderr, flush=True) + raise OSError(e) except Exception as e: - print(e) + print("error: %s"% e, file=sys.stderr, flush=True) break else: # convert time to milliseconds, considering that @@ -192,12 +193,21 @@ def unsupported_feature(): - print("Error: You have an older version of Python interpreter.") + print("Error: You have an unsupported version of Python interpreter dnspython library.") print(" Some features such as DoT and DoH are not available. You should upgrade") - print(" the Python interpreter to at least 3.6 and reinstall dependencies.") + print(" the Python interpreter to at least 3.7 and reinstall dependencies.") sys.exit(127) +def valid_rdatatype(rtype): + # validate RR type + try: + _ = dns.rdatatype.from_text(rtype) + except dns.rdatatype.UnknownRdatatype: + return False + return True + + def flags_to_text(flags): # Standard DNS flags diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/util/shared.py new/dnsdiag-2.5.0/util/shared.py --- old/dnsdiag-2.1.0/util/shared.py 2023-02-01 13:36:24.000000000 +0100 +++ new/dnsdiag-2.5.0/util/shared.py 2024-06-18 08:15:34.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2016-2023, Babak Farrokhi +# Copyright (c) 2016-2024, Babak Farrokhi # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -25,7 +25,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -__version__ = '2.1.0' +__version__ = '2.5.0' class Colors(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnsdiag-2.1.0/util/whois.py new/dnsdiag-2.5.0/util/whois.py --- old/dnsdiag-2.1.0/util/whois.py 2023-02-01 13:36:24.000000000 +0100 +++ new/dnsdiag-2.5.0/util/whois.py 2024-05-31 14:28:27.000000000 +0200 @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # -# Copyright (c) 2016-2023, Babak Farrokhi +# Copyright (c) 2016-2024, Babak Farrokhi # All rights reserved. # # Redistribution and use in source and binary forms, with or without
participants (1)
-
Source-Sync