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 <mar...@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 <mar...@gmx.de>
+# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2017-2024, Martin Hauke <mar...@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

Reply via email to