Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re^2: How would I do this "dig" command in Perl?

by Nige (Beadle)
on Feb 05, 2016 at 07:28 UTC ( [id://1154470]=note: print w/replies, xml ) Need Help??


in reply to Re: How would I do this "dig" command in Perl?
in thread How would I do this "dig" command in Perl?

The real question is how would you do it just in simple Perl!

Imagine a server that has no nslookup or dig utilities.
It has a recent Perl, you can "use Socket;", but not Net::DNS. You are not root, so can't install anything.
You have an IP address for something you think is a DNS server, and want to lookup some names. How?

  • Comment on Re^2: How would I do this "dig" command in Perl?

Replies are listed 'Best First'.
Re^3: How would I do this "dig" command in Perl?
by Anonymous Monk on Feb 05, 2016 at 07:35 UTC

      Using other people's maintained code is always best, but in some environments it is just not plausible. Tarring/packaging up lots of modules, onto a remote platform that is locked down for security reasons, is not trivial.

      Here is a paste of my long script that just uses plain simple Perl. It is somewhere in-between nslookup and dig. It was written for a Telco environment. Tested on MacOSX, RHEL6 & 7. Sorry about any bugs, and the use of ts=8

      #!/usr/bin/perl -w #===================================================================== +========= # # = NAME # nsdig.pl - A cross between nslookup and dig # # = DESCRIPTION # DNS lookups when BIND/dig/nslookup packages not installed # # = AUTHOR # Nigel Pearson. nigel.pearson.au@gmail.com # # Thanks to http://docstore.mik.ua/orelly/perl/sysadmin/ch05_03.htm # http://www.binarytides.com/dns-query-code-in-c-with-linux-sockets # (and Net::DNS + Perl Cookbook chapter 18, for earlier versions) # and tokai on PerlMonks.org for his hexdump(). # # = VERSION # 0.7, circa 2016. # # = COPYRIGHT # Released into public domain 29th Jan, 2021. #===================================================================== +========= use strict; use IO::Socket::INET; my $DEBUG = 0; my $EXTRA = 0; # Output extra sections, like AUTHORITY and ADDITION +AL. my $TEST = 0; my $DefNS = '8.8.8.8'; my $NS; #===================================================================== +========= sub Debug($) { $DEBUG && print STDERR @_, "\n" } sub hexdump($) { return if ( ! $DEBUG ); my $data = shift; my $offset = 0; foreach my $chunk ( unpack '(a16)*', $data ) # fails with old P +erl? { my $hex = unpack 'H*', $chunk; # hexadecimal magic $chunk =~ tr/ -~/./c; # replace unprintables $hex =~ s/(.{1,8})/$1 /gs; # insert spaces printf "0x%08x (%05u) %-*s %s\n", $offset, $offset, 36, $hex, $ch +unk; $offset += 16 } } #===================================================================== +========= # # Make a possibly compressed IPv6 into its full representation. # # Does not cope with '::' at the start (e.g. '::' or '::1') # We assume those are already filtered out. # sub ExpandIPv6($) { my $address = pop; $address =~ s/^(.):/000$1:/g; # Leading zeros $address =~ s/^(..):/00$1:/g; $address =~ s/^(...):/0$1:/g; $address =~ s/:(.):/:000$1:/g; # Same thing in middle $address =~ s/:(..):/:00$1:/g; $address =~ s/:(...):/:0$1:/g; if ( $address =~ /\w::/ ) { # A full address is 8 quad hex, plus 7 ':' (39) my $insLen = 39 - length $address; my $insert = substr ':0000:0000:0000:0000:0000:0000:0000', 0, $insLen+2; # The '::' is included $address =~ s/::/$insert/ } return $address } if ( 0 ) { my $addr = '2001:0db8:ac10:fe01::'; print "ExpandIPv6($addr) = " . &ExpandIPv6($addr) . "\n"; $addr = 'f::'; print "ExpandIPv6($addr) = " . &ExpandIPv6($addr) . "\n"; exit; } #===================================================================== +========= # # dn_expand_PP() from Net::DNS::Packet.pm # sub GetDN($$) { my ($data, $offset) = @_; my $datalen = length $data; my @domain = (); if ( $offset >= $datalen ) { &Debug("GenDN(,$offset) - Error, offset >= length data ($datalen)" +); return undef, $offset } if ( $DEBUG ) { my $str = substr $data, $offset, 20; my $hex = unpack 'H*', $str; # hexadecimal magic $hex =~ s/(.{1,8})/$1 /gs; # insert spaces $str =~ tr/ -~/./c; # replace unprintables print "GetDN(,$offset) $hex $str\n" } while ( $offset < $datalen ) { my $len = unpack "\@$offset C", $data; if ( ( $len & 0xC0 ) == 0xC0 ) # Offset/pointer { my $ptr = 0x3FFF & ( unpack "\@$offset n", $data ); Debug("GetDN() - found pointer to $ptr"); my ($FQDN, undef) = &GetDN($data, $ptr); push @domain, $FQDN; # pop??? return (join '.', @domain), $offset+2 } if ( $len ) { push @domain, substr $data, $offset+1, $len; $offset += $len+1 # Includes the unpacked length byte } else { last } } if ( ! length $data ) { die "GetDN() - ran over end of buffer!" } ++$offset; # Past zero/null at end Debug("GetDN() - Got '" . join ('.', @domain) . "', offset now $o +ffset"); return (join '.', @domain), $offset } my @typesbyval = ( 'SIGZERO', 'A', 'NS', 'MD', 'MF', 'CNAME', # [0]= +SIGZERO 'SOA', 'MB', 'MG', 'MR', 'NULL', # [10]=NULL 'WKS', 'PTR', 'HINFO', 'MINFO', 'MX', 'TXT', 'RP', 'AFSDB', 'X25', 'ISDN', # [20]=ISDN 'RT', 'NSAP', 'NSAP_PTR', 'SIG', 'KEY', 'PX', 'GPOS', 'AAAA', 'LOC', 'NXT', # [30]=NXT 'EID', 'NIMLOC', 'SRV', 'ATMA', 'NAPTR', 'KX', 'CERT', 'A6', 'DNAME', 'SINK', # [40]=SINK 'OPT', 'APL', 'DS', 'SSHFP', 'IPSECKEY', 'RRSIG', 'NSEC', 'DNSKEY', 'DHCID', 'NSEC3',# [50]=NSEC3 'NSEC3PARAM' ); $typesbyval[55] = 'HIP'; $typesbyval[56] = 'NINFO'; $typesbyval[57] = 'RKEY'; $typesbyval[99] = 'SPF'; $typesbyval[100] = 'UINFO'; $typesbyval[101] = 'UID'; $typesbyval[102] = 'GID'; $typesbyval[103] = 'UNSPEC'; $typesbyval[249] = 'TKEY'; $typesbyval[250] = 'TSIG'; $typesbyval[251] = 'IXFR'; $typesbyval[252] = 'AXFR'; $typesbyval[253] = 'ILB'; $typesbyval[254] = 'MAILA'; $typesbyval[255] = 'ANY'; $typesbyval[32768] = 'TA'; $typesbyval[32769] = 'DLV'; my @classesbyval = ( '', 'IN', '', 'CH', 'HS'); $classesbyval[254] = 'NONE'; $classesbyval[255] = 'ANY'; # # Simplified GetDN() used for resource record processing. # Generic strings don't use pointer compression, thus no recursion # sub GetStr($$) { my ($data, $offset) = @_; if ( $DEBUG ) { my $str = substr $data, $offset, 20; my $hex = unpack 'H*', $str; # hexadecimal magic $hex =~ s/(.{1,8})/$1 /gs; # insert spaces $str =~ tr/ -~/./c; # replace unprintables print "GetStr(,$offset) $hex $str\n" } my $len = unpack "\@$offset C", $data; my $str = substr $data, $offset+1, $len; Debug("GetStr() - Got '$str', offset now $offset+$len+1"); return $str, $offset+$len+1 } # # Slightly based on DNS::Question->parse(). # My caller doesn't need to know the length of what we parse, # so the recursion and offset stuff in dn_expand_PP() isn't needed! # sub ParseQ($) { my $data = shift; my $FQDN = ''; while ( length $data > 0 ) { my $len = unpack 'C', $data; my $str = substr $data, 1, $len; $data =~ s/^.$str//; if ( ! $len ) # Strings seem to end with a zero/null { last } # which is also stripped by the above =~ $FQDN .= "$str." } if ( ! length $data ) { die "ParseQ() - ran over end of QNAME!" } chop $FQDN; my ($type, $class) = unpack 'n2', $data; return $FQDN, $typesbyval[$type], $classesbyval[$class] } # # Rewrite of Net:DNS:RR->parse() and new_from_data() # sub ParseRR($$) { my ($data, $offset) = @_; Debug("ParseRR() Getting name at $offset"); my ($name, $index) = GetDN($data, $offset); my ($type, $class, $TTL, $rdlen) = unpack "\@$index n2 N n", $data +; $offset = $index + 10; Debug("ParseRR() Type $type, Class $class, TTL $TTL, rdlen $rdlen" +); if ( length $data < ($offset + $rdlen) ) { die 'ParseRR(): incomplete data' } Debug("ParseRR() Reading RDATA from offset $offset"); my $rdata = substr $data, $offset, $rdlen; # # Now, a lot of munging to return appropriate data: # $type = $typesbyval[$type]; if ( $type eq 'OPT' ) # RFC2671, 4.3 { $class = "uint16 $class" } else { $class = $classesbyval[$class] } my $result = ''; if ( $type =~ m/^(CNAME|MB|MG|MR|NS|PTR)$/ ) # MOSTLY UNTESTED { ($result, undef) = GetDN($data, $offset) } if ( $type eq 'SOA' ) { my ($mname, $skip1) = GetDN($data, $offset); my ($rname, $skip2) = GetDN($data, $skip1); if ( $rname !~ m/\@/ ) # If this doesn't look like an email +, { $rname =~ s/\./@/ } # hack it ! my ($serial, $refr, $rtry, $exp) = unpack "\@$skip2 N4", $data; $result = "$mname $rname ( $serial $refr $rtry $exp $TTL )" } if ( $type eq 'MX' ) { $result = unpack 'n', $rdata; my ($exchange, undef) = GetDN($data, $offset+2); $result .= " $exchange" } if ( $type eq 'NAPTR' ) { my ($order, $preference) = unpack 'n2 ', $rdata; $result = "$order $preference "; my ($flags, $skip1) = GetStr($data, $offset+4); my ($service, $skip2) = GetStr($data, $skip1); my ($regexp, $skip3) = GetStr($data, $skip2); my ($replace, undef) = GetDN($data, $skip3); $result .= "'$flags' '$service' '$regexp' '$replace'" } if ( $type eq 'SRV' ) { my ($pri, $weight, $port) = unpack 'n3 ', $rdata; my ($target, undef) = GetDN($data, $offset+6); $result = "$pri $weight $port $target."; } # OPT? SRV? LOC? MINFO if ( $type =~ m/(HINFO|ISDN|SPF|TXT|X25)/ ) # UNTESTED { my $byte = 0; while ( $byte < $rdlen ) { my $len = unpack 'n', $rdata; $byte += 2; $result .= substr $rdata, 0, $len; $byte += $len; $result .= ' ' } } if ( $type eq 'A' ) { $result = inet_ntoa(substr $rdata, 0, 4) } if ( $type eq 'AAAA' ) { $result = unpack 'H32', $rdata; # hex from network order (high fir +st) $result =~ s/(....)/$1:/g; chop $result; $result =~ s/^0+:/:/; # leading zeroes $result =~ s/:0+/:/g; # leading zeroes in each quad $result =~ s/:+:/::/g; # excess contractions! if ( $result eq '::' ) { $result .= ' (unspecified, all zeros)' } } return $name, $type, $class, $TTL, $result, $offset+$rdlen } # # Generate a UDP header, send to name server, read and return results # sub QueryV4($$$@) { my ($format, $type, $ns, @query) = @_; my $query = pack ( 'n C2 n4', $$, # Process ID - hopefully a short 0 + # Std. query, not authoritative, non-truncated 1, # Recursion desired 0, # No checking, authentication, recursion, z? 1, # 1 question entry supplied 0, # no answer entries ,, 0, # no nameserv entries ,, 0 ) # no resource entries ,, . pack ( $format, @query, 0, # end of query strings $type, 1 ); # Query class of IN Debug("\nSending ..."); hexdump($query); Debug(" to $ns"); my ($datagram, $sock); $sock = new IO::Socket::INET (PeerAddr=>$ns, PeerPort=>53, Proto=> +'udp') or die "Can't create socket: $@"; $sock->send($query); # Allow 3 seconds to respond. # If nothing back in that time, $ns is unreachable? eval { local $SIG{ALRM} = sub { die 'TIMEOUT'; }; alarm 3; # DNS over UDP is always up to 576 bytes? (512 payload) $sock->recv($datagram, 512 ); alarm 0; }; alarm 0; if ( $@ && $@ =~ 'TIMEOUT' ) { return 0, 'TIMEOUT' } close $sock; Debug("\nReceived ..."); hexdump($datagram); return length $query, $datagram } # # Lookup a nameserver and return either name, or "dig"-like output # sub Query($$$$) { my ($ns, $thingy, $qtype, $nameOnly) = @_; if ( $ns =~ m/:/ ) { return QueryErr($nameOnly, "$ns - Cannot query IPv6 servers y +et") } if ( $ns !~ m/^\d+\.\d+\.\d+\.\d+$/ ) { return QueryErr($nameOnly, "'$ns' is not an IP addresses") } if ( $thingy !~ m/\./ ) { return QueryErr($nameOnly, "Cannot lookup '$thingy' - no domai +n!") } if ( ! defined $qtype or $qtype !~ m/\d/ ) { $qtype = 1 } # IN type A=1 if ( ! defined $nameOnly ) { $nameOnly = 0 } # # Construct Query string for outgoing request: # my $qformat = ''; my @query = (); for (split ( /\./, $thingy ) ) { $qformat .= 'C a* '; push @query, length; push @query, $_ } $qformat .= 'C n2'; my $qtypestr = $typesbyval[$qtype]; my ($skip, $datagram) = QueryV4($qformat, $qtype, $ns, @query); if ( $datagram eq 'TIMEOUT' ) { return QueryErr($nameOnly, "Timeout receiving data from $ns") + } my $size = length $datagram; if ( $size < 40 ) { return QueryErr($nameOnly, "Short response from '$ns' - $size byte +s") } # Header is easy: my ($id, $flags1, $flags2, $queries, $answers, $authNSs, $addt) = unpack 'n C2 n4', $datagram; my $offset = 12; if ( $id != $$ or $queries != 1 ) { return QueryErr($nameOnly, "We got someone else's query? Damn + UDP!") } if ( $nameOnly and $answers lt 1 ) { return QueryErr($nameOnly, "Cannot find $thingy on $ns") } if ( $answers+$authNSs lt 1 ) { return QueryErr($nameOnly, "Cannot find 'IN $qtypestr' $thingy on +$ns") } Debug("$answers answers, $authNSs authoritative NSs, $addt additio +nal."); # # Parse results and make output to be similar tothat from dig(1) # my $lines = "\n; <<>> nsdig.pl 0.7 <<>> "; if ( $qtype != 1 ) { $lines .= "-t$qtypestr " } $lines .= "\@$ns $thingy\n"; # # We should parse the question section like this: # # $lines .= "\n;; QUESTION SECTION;\n"; # for ( 1 .. $queries ) # { # my ($name,$type,$class,undef) = ParseQ(substr $datagram, $offset) +; # $lines .= "$name\t\t$class $type\n" # } # # but since query received = query sent, save time: # $offset = $skip; my $foundIPv6 = 0; if ( $answers ) { if ( $nameOnly ) { $lines = '' } else { $lines .= "\n;; ANSWER SECTION:\n" } for ( 1 .. $answers ) { my ($name, $type, $class, $TTL, $result, $skip) = ParseRR($datagram, $offset); $offset = $skip; $lines .= "$name\t$TTL\t$class $type $result\n"; if ( $type eq 'AAAA' ) { $foundIPv6 = 1 } } } # # Since many DNS servers also have IPv6 data for thingy, # do another request if the first one was default lookup for addre +sses # if ( $qtype == 1 and ! $foundIPv6 ) { my ($skip, $data) = QueryV4($qformat, 28, $ns, @query); # type AA +AA=28 if ( length $data < 40 ) { next } my ($id, $flags1, $flags2, $queries, $answers, $authNSs, $addt) = unpack 'n C2 n4', $data; &Debug("IPv6: $answers answers," . " $authNSs authoritative NSs, $addt additional."); if ( $id == $$ and $queries == 1 and $answers > 0 ) { for ( 1 .. $answers ) { my ($name, $type, $class, $TTL, $result, $skip2) = ParseRR($data, $skip); $skip = $skip2; if ( $type eq 'AAAA' ) { $lines .= "$name\t$TTL\t$class $type $result\n" } } } } $lines .= "\n"; if ( $nameOnly ) { return $lines } if ( $authNSs ) { $lines .= ";; AUTHORITY SECTION:\n"; for ( 1 .. $authNSs ) { my ($name, $type, $class, $TTL, $result, $skip) = ParseRR($datagram, $offset); $offset = $skip; $lines .= "$name\t$TTL\t$class $type $result\n" } $lines .= "\n"; } if ( $addt ) { $lines .= ";; ADDITIONAL SECTION:\n"; for ( 1 .. $addt ) { my ($name, $type, $class, $TTL, $result, $skip) = ParseRR($datagram, $offset); $offset = $skip; $lines .= "$name\t$TTL\t$class\t$type\t$result\n" } $lines .= "\n"; } $lines .= ";; SERVER: $ns#53\n"; $lines .= ";; When: " . `date '+%a %b %e %H:%M:%S %Y' `; $lines .= ";; MSG SIZE rcvd: $size\n"; return $lines } # # Return error from Query in appropriate format # sub QueryErr($$) { my ($short, $err) = @_; if ( $short ) { return $err } return "\nERROR -- $err\n" } # # Use PTR lookup to find names for IP address # sub LookupIP($$) { my ($ns, $IP) = @_; if ( $ns !~ m/^\d+\.\d+\.\d+\.\d+$/ ) { return "Error - '$ns' is not an IP addresses" } # # Construct Query string for outgoing request: # my $qformat = ''; my @query = (); for (split ( /\./, $IP ) ) { $qformat .= 'C a* '; push @query, length; push @query, $_ } $qformat .= 'C n2'; my ($skip, $datagram) = QueryV4($qformat, 12, $ns, @query); # P +TR=12 my $size = length $datagram; if ( $size < 40 ) { return "Short Name Server response - $size bytes" } # Header is easy: my ($id, $flags1, $flags2, $queries, $answers, $authNSs, $addt) = unpack 'n C2 n4', $datagram; my $offset = 12; if ( $id != $$ or $queries != 1 ) { return "We got someone else's query? Damn UDP!" } if ( $answers lt 1 ) { return "Cannot find 'IN PTR $IP' on $ns" } Debug("$answers answers, $authNSs authoritative NSs, $addt additio +nal."); # # We should parse the question section like this: # # $lines .= "\n;; QUESTION SECTION;\n"; # for ( 1 .. $queries ) # { # my ($name,$type,$class,undef) = ParseQ(substr $datagram, $offset) +; # $lines .= "$name\t\t$class $type\n" # } # # but since query received = query sent, save time: # $offset = $skip; my @names; for ( 1 .. $answers ) { my ($name, $type, $class, $TTL, $result, $skip) = ParseRR($datagram, $offset); $offset = $skip; push @names, $result } # Very unlikely! for ( 1 .. $authNSs ) { my ($name, $type, $class, $TTL, $result, $skip) = ParseRR($datagram, $offset); $offset = $skip; push @names, $result } # Also very unlikely! for ( 1 .. $addt ) { my ($name, $type, $class, $TTL, $result, $skip) = ParseRR($datagram, $offset); $offset = $skip; push @names, $result } return @names; } sub Lookup($$$) { my ($thingy, $ns, $qtype) = @_; if ( ! defined $ns ) { $ns = $NS } my $result = ''; if ( $thingy =~ /:\/\/(.+)/ ) # Most URLs like http:// { $result = "URL: $thingy\n"; $thingy = $1; $thingy =~ s,/.*,,; } if ( $thingy =~ /^\w+:.*@(.+)/ ) # URIs like mailto: sip: { $result = "URI: $thingy\n"; $thingy = $1; } # Simple IPv4 reverse lookups: if ( $thingy =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/?/ or # A.B.C.D o +r A.B.C.D/ $thingy =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+):\d+/ ) # A.B.C.D:port/ +blah { $result .= "IP addr: $thingy\n"; my $IP = "$4.$3.$2.$1.in-addr.arpa"; my $names = join ', ', LookupIP($ns, $IP); if ( $names =~ /^Cannot find/ ) { return $result . " - $names" } else { return $result . "Name: $names" } } # Same for IPv6: if ( $thingy =~ /(::|[\dabcdef]+:[\dabcdef:]+)/ ) { # Strip [] from a possible URL. e.g. http:[.*]/blah $thingy =~ s/^\[//, $thingy =~ s/\].*//; $result .= "IPv6: $thingy\n"; if ( $thingy eq '::' or $thingy eq '0:0:0:0:0:0:0:0' ) { return $result . 'Meaning: "Unspecified" address' } if ( $thingy eq '::1' or $thingy eq '0:0:0:0:0:0:0:1' ) { return $result . 'Meaning: Local/loopback address' } $thingy = ExpandIPv6($thingy); $thingy =~ s/://g; my $IP = chop $thingy; while ( $thingy ) { $IP .= '.' . chop $thingy } my $names = join ', ', LookupIP($ns, "$IP.ip6.arpa"); if ( $names =~ /^Cannot find/ ) { return $result . " - $names" } else { return $result . "Name: $names" } } if ( $thingy =~ /\w+\.\w+/ ) # FQDN { $result .= "Domain: $thingy\n"; if ( ! defined $qtype ) { $qtype = 1 } # IN A - Address my $addr .= Query($ns, $thingy, $qtype, 1); if ( $addr =~ /^Cannot find/ ) { return $result . " - $addr" } else { return $result . "IP addr: $addr" } } if ( $result ) { $result .= " - Unable to lookup '$thingy'" } else { $result = "ERROR -- Unable to lookup '$thingy'" } return $result } #===================================================================== +========= sub Usage($) { my $err = shift; if ( $err ) { $err = "ERROR: $err\n" } print <<EOF; DNS lookup for hostname, FQDN, IP addresses, or simple URIs! $err usage: $0 -test usage: $0 name server usage: $0 -type=query-type name server usage: $0 \@server name* usage: $0 \@server -t query-type name* usage: $0 -extra name* usage: $0 -debug name* usage: $0 name* Note that name can be a number of host.domain, URI or an IP-address, but if you specify two of them, I'll assume second one is a DNS server + :-) EOF exit 0 } if ( ( scalar grep /^\@.+/, @ARGV) > 1 ) { Usage('multiple @server arguments') } my @args = (); my $qtype = ''; foreach ( @ARGV ) { # Ugly hack for split word arguments: if ( $qtype eq 'NEXTLOOP' ) { $qtype = $_; next } if ( /^-t$/ ) { $qtype = 'NEXTLOOP'; next } if ( /^@(.*)/ ) { $NS = $1; next } if ( /^-type=(.*)/ or /^--type=(.*)/ ) { $qtype = $1; next } if ( /^-debug/ or /^--debug/ ) { $DEBUG = 1; next } if ( /^-extra/ or /^--extra/ ) { $EXTRA = 1; next } if ( /^-test/ or /^--test/ ) { $TEST = 1; next } if ( /^-h/ or /^--help/ ) { Usage('') } # Otherwise, assume list of things to lookup push @args, $_ } if ( $qtype eq 'NEXTLOOP' ) { Usage('-t argument missing.') } if ( $qtype ) { my $i = 0; while ( $i < $#typesbyval ) { if ( defined $typesbyval[$i] # there are gaps in @typesbyval and (uc $qtype) eq $typesbyval[$i] ) { $qtype = $i; last } $i++; } if ( $i == $#typesbyval ) { $qtype = undef } } # # Finally start the lookups # if ( scalar @args == 2 ) { print &Query($args[1], $args[0], $qtype, $EXTRA==0) . "\n"; exit; + } if ( ! $NS ) { $NS = `egrep nameserver /etc/resolv.conf | head -n 1`; chop $NS; if ( $NS ) { $NS =~ s/^nameserver\W*// } else { $NS = $DefNS } } if ( scalar @args > 0 ) { foreach ( @args ) { if ( $EXTRA ) { print Query($NS, $_, $qtype, 0) } else { print Lookup($_, $NS, $qtype) } } } elsif ( $TEST ) { print &Query('2001:4860:4860::8888','www.apple.com'); print &Query('dns.google.com', 'blah.blah'); print &Query('8.8.8.8', 'blah'); my $sep = '======================================================= +======='; print $sep . &Query($NS, 'apple.com'); print $sep . &Query($NS, 'apple.com', 6); # 6=SOA print $sep . &Query($NS, 'apple.com', 15); # 15=MX print $sep . &Query($NS, 'apple.com', 35); # 35=NAPTR print $sep . &Query($NS, 'www.apple.com'); print $sep . &Query($NS, 'www.apple.com', 28); # 28=AAAA $sep = "\n........\n"; print $sep . &Lookup('http://127.0.0.1'); print $sep . &Lookup('anyoldrubbish'); print $sep . &Lookup('10.97.217.136'); print $sep . &Lookup('mailto:nigel\@ind.tansu.com.au'); print $sep . &Lookup('https://149.135.128.11/~nigel'); print $sep . &Lookup('2001:67c:2d7c:66::53'); print $sep . &Lookup('fdac:45f8:8cea:66d7:924:694f:bcd:d155'); print $sep . &Lookup('tel:+61285765449'); print $sep . &Lookup('sip:+61285765449;npdi@[fdac:45f8:8cea:66d7:9 +24:694f:bcd:d155];param=yes') . "\n"; exit 0; } else { Usage('') }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1154470]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (5)
As of 2024-04-23 21:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found