@@ -140,31 +140,37 @@ def _rank(info):
140140 yield sockaddr
141141
142142
143- def _resolve_one_ip ( host , prefer_ipv6 = True ):
143+ def _resolve_all_server_ips ( dns_server , prefer_ipv6 = True ):
144144 """
145- Best-effort resolve hostname -> one IP string (display only) .
146- Returns None on failure .
145+ Display helper: resolve hostname -> list of IP strings .
146+ For IP literals, returns just the literal (IPv6%zone -> IPv6) .
147147 """
148- if not host :
149- return None
150- if _is_ip_literal (host ):
151- if "%" in host :
152- return host .split ("%" , 1 )[0 ]
153- return host
148+ if not dns_server :
149+ return []
150+ if _is_ip_literal (dns_server ):
151+ if "%" in dns_server :
152+ return [dns_server .split ("%" , 1 )[0 ]]
153+ return [dns_server ]
154+
155+ ips = []
154156 try :
155- infos = socket .getaddrinfo (host , 0 , socket .AF_UNSPEC , 0 , 0 )
156- best = None
157+ infos = socket .getaddrinfo (dns_server , 0 , socket .AF_UNSPEC , 0 , 0 )
157158 for fam , _socktype , _proto , _canon , sockaddr in infos :
158159 ip = sockaddr [0 ]
159- if best is None :
160- best = ip
161- if prefer_ipv6 and fam == socket .AF_INET6 :
162- return ip
163- if (not prefer_ipv6 ) and fam == socket .AF_INET :
164- return ip
165- return best
160+ if ip not in ips :
161+ ips .append (ip )
166162 except Exception :
167- return None
163+ return []
164+
165+ # Sort in preferred order for display
166+ def _rank_ip (ip ):
167+ is_v6 = ":" in ip
168+ if prefer_ipv6 :
169+ return 0 if is_v6 else 1
170+ return 0 if (not is_v6 ) else 1
171+
172+ ips .sort (key = _rank_ip )
173+ return ips
168174
169175
170176def encode_qname (domain ):
@@ -596,7 +602,14 @@ def _print_nslookup_error(domain, rcode):
596602def _print_nslookup_like (dns_server , port , domain , prefer_ipv6 , timeout ,
597603 tcp_fallback , strict_txid ,
598604 server_name_display = None ,
599- resolve_server_name = False ):
605+ resolve_server_name = False ,
606+ nslookup_default_header = False ):
607+ """
608+ nslookup-style output.
609+ - Queries both A and AAAA and prints them.
610+ - If nslookup_default_header=True prints "Default server:" style header.
611+ - If resolve_server_name=True and dns_server is hostname, prints all resolved server IPs.
612+ """
600613 rcode_any = 0
601614 aa_any = False
602615 a_list = []
@@ -630,13 +643,31 @@ def _print_nslookup_like(dns_server, port, domain, prefer_ipv6, timeout,
630643
631644 server_line = server_name_display if server_name_display else dns_server
632645
633- if resolve_server_name and (not _is_ip_literal (dns_server )):
634- used_ip = _resolve_one_ip (dns_server , prefer_ipv6 = prefer_ipv6 ) or (used [0 ] if used else dns_server )
646+ # For the "Address:" header lines:
647+ if resolve_server_name :
648+ server_ips = _resolve_all_server_ips (dns_server , prefer_ipv6 = prefer_ipv6 )
649+ if not server_ips and used :
650+ server_ips = [used [0 ]]
651+ if not server_ips :
652+ server_ips = [dns_server ]
653+ else :
654+ if used :
655+ server_ips = [used [0 ]]
656+ else :
657+ # best effort: literal -> itself, hostname -> try resolve one
658+ one = _resolve_all_server_ips (dns_server , prefer_ipv6 = prefer_ipv6 )
659+ server_ips = one [:1 ] if one else [dns_server ]
660+
661+ if nslookup_default_header :
662+ print ("Default server:\t %s" % server_line )
663+ # nslookup often prints multiple Address lines for the server too:
664+ for ip in server_ips :
665+ print ("Address:\t %s#%d" % (ip , int (port )))
635666 else :
636- used_ip = used [0 ] if used else dns_server
667+ print ("Server:\t \t %s" % server_line )
668+ for ip in server_ips [:1 ]:
669+ print ("Address:\t %s#%d" % (ip , int (port )))
637670
638- print ("Server:\t \t %s" % server_line )
639- print ("Address:\t %s#%d" % (used_ip , int (port )))
640671 print ("" )
641672
642673 if (not a_list ) and (not aaaa_list ):
@@ -693,10 +724,12 @@ def main():
693724
694725 parser .add_argument ('--nslookup' , action = 'store_true' ,
695726 help = 'Print nslookup-like output (queries both A and AAAA)' )
727+ parser .add_argument ('--nslookup-default-header' , action = 'store_true' ,
728+ help = 'Use "Default server:" / "Address:" header style (like common nslookup)' )
696729 parser .add_argument ('--nslookup-server-name' , type = str , default = None ,
697- help = 'Override the name printed on the "Server:" line (e.g. dns.google)' )
730+ help = 'Override the name printed on the "Server:"/"Default server:" line (e.g. dns.google)' )
698731 parser .add_argument ('--nslookup-resolve-server' , action = 'store_true' ,
699- help = 'Resolve the server hostname for the "Address:" line (display only)' )
732+ help = 'Resolve the server hostname and print ALL server IPs in the header (display only)' )
700733
701734 parser .add_argument ('--quiet' , action = 'store_true' , help = 'Less header/debug output (classic mode)' )
702735
@@ -733,6 +766,7 @@ def main():
733766 strict_txid = strict_txid ,
734767 server_name_display = args .nslookup_server_name ,
735768 resolve_server_name = bool (args .nslookup_resolve_server ),
769+ nslookup_default_header = bool (args .nslookup_default_header ),
736770 )
737771 return
738772
0 commit comments