DNS query: Difference between revisions
→{{header|Lasso}}: Add Lasso DNS lookup example |
|||
Line 405: | Line 405: | ||
IPv6 : 2001:200:dff:fff1:216:3eff:feb1:44d7 |
IPv6 : 2001:200:dff:fff1:216:3eff:feb1:44d7 |
||
</pre> |
</pre> |
||
=={{header|Lasso}}== |
|||
The DNS lookup methods in Lasso do not support IPv6 addresses at this time, only IPv4. |
|||
<lang Lasso>dns_lookup('www.kame.net', -type='A')</lang> |
|||
== {{header|NetRexx}} == |
== {{header|NetRexx}} == |
Revision as of 06:23, 2 November 2013
You are encouraged to solve this task according to the task description, using any language you may know.
DNS is an internet service that maps domain names, like rosettacode.org
, to IP addresses, like 66.220.0.231
.
Use DNS to resolve www.kame.net
to both IPv4 and IPv6 addresses. Print these addresses.
Ada
<lang Ada>with Ada.Text_IO; use Ada.Text_IO; with GNAT.Sockets; use GNAT.Sockets;
procedure DNSQuerying is
Host : Host_Entry_Type (1, 1); Inet_Addr_V4 : Inet_Addr_Type (Family_Inet);
begin
Host := Get_Host_By_Name (Name => "www.kame.net"); Inet_Addr_V4 := Addresses (Host); Put ("IPv4: " & Image (Value => Inet_Addr_V4));
end DNSQuerying;</lang>
BBC BASIC
<lang bbcbasic> name$ = "www.kame.net"
AF_INET = 2 AF_INET6 = 23 WSASYS_STATUS_LEN = 128 WSADESCRIPTION_LEN = 256 SYS "LoadLibrary", "WS2_32.DLL" TO ws2% SYS "GetProcAddress", ws2%, "WSAStartup" TO `WSAStartup` SYS "GetProcAddress", ws2%, "WSACleanup" TO `WSACleanup` SYS "GetProcAddress", ws2%, "getaddrinfo" TO `getaddrinfo` DIM WSAdata{wVersion{l&,h&}, wHighVersion{l&,h&}, \ \ szDescription&(WSADESCRIPTION_LEN), szSystemStatus&(WSASYS_STATUS_LEN), \ \ iMaxSockets{l&,h&}, iMaxUdpDg{l&,h&}, lpVendorInfo%} DIM addrinfo{ai_flags%, ai_family%, ai_socktype%, ai_protocol%, \ \ ai_addrlen%, lp_ai_canonname%, lp_ai_addr%, lp_ai_next%} DIM ipv4info{} = addrinfo{}, ipv6info{} = addrinfo{} DIM sockaddr_in{sin_family{l&,h&}, sin_port{l&,h&}, sin_addr&(3), sin_zero&(7)} DIM sockaddr_in6{sin6_family{l&,h&}, sin6_port{l&,h&}, sin6_flowinfo%, \ \ sin6_addr&(15), sin6_scope_id%} SYS `WSAStartup`, &202, WSAdata{} TO res% IF res% ERROR 102, "WSAStartup failed" addrinfo.ai_family% = AF_INET SYS `getaddrinfo`, name$, 0, addrinfo{}, ^ipv4info{}+4 TO res% IF res% ERROR 103, "getaddrinfo failed" !(^sockaddr_in{}+4) = ipv4info.lp_ai_addr% PRINT "IPv4 address = " ; PRINT ;sockaddr_in.sin_addr&(0) "." sockaddr_in.sin_addr&(1) "." ; PRINT ;sockaddr_in.sin_addr&(2) "." sockaddr_in.sin_addr&(3) addrinfo.ai_family% = AF_INET6 SYS `getaddrinfo`, name$, 0, addrinfo{}, ^ipv6info{}+4 TO res% IF res% ERROR 104, "getaddrinfo failed" !(^sockaddr_in6{}+4) = ipv6info.lp_ai_addr% PRINT "IPv6 address = " ; PRINT ;~sockaddr_in6.sin6_addr&(0) * 256 + sockaddr_in6.sin6_addr&(1) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(2) * 256 + sockaddr_in6.sin6_addr&(3) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(4) * 256 + sockaddr_in6.sin6_addr&(5) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(6) * 256 + sockaddr_in6.sin6_addr&(7) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(8) * 256 + sockaddr_in6.sin6_addr&(9) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(10) * 256 + sockaddr_in6.sin6_addr&(11) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(12) * 256 + sockaddr_in6.sin6_addr&(13) ":" ; PRINT ;~sockaddr_in6.sin6_addr&(14) * 256 + sockaddr_in6.sin6_addr&(15) SYS `WSACleanup`
</lang> Output:
IPv4 address = 203.178.141.194 IPv6 address = 2001:200:DFF:FFF1:216:3EFF:FEB1:44D7
C
This solution uses getaddrinfo()
, a standard function from RFC 3493. This code resembles an example from getaddrinfo(3), the BSD manual page. Whereas the man page code connects to www.kame.net
, this code only prints the numeric addresses.
<lang c>#include <sys/types.h>
- include <sys/socket.h>
- include <netdb.h> /* getaddrinfo, getnameinfo */
- include <stdio.h> /* fprintf, printf */
- include <stdlib.h> /* exit */
- include <string.h> /* memset */
int main() { struct addrinfo hints, *res, *res0; int error; char host[NI_MAXHOST];
/* * Request only one socket type from getaddrinfo(). Else we * would get both SOCK_DGRAM and SOCK_STREAM, and print two * copies of each numeric address. */ memset(&hints, 0, sizeof hints); hints.ai_family = PF_UNSPEC; /* IPv4, IPv6, or anything */ hints.ai_socktype = SOCK_DGRAM; /* Dummy socket type */
/* * Use getaddrinfo() to resolve "www.kame.net" and allocate * a linked list of addresses. */ error = getaddrinfo("www.kame.net", NULL, &hints, &res0); if (error) { fprintf(stderr, "%s\n", gai_strerror(error)); exit(1); }
/* Iterate the linked list. */ for (res = res0; res; res = res->ai_next) { /* * Use getnameinfo() to convert res->ai_addr to a * printable string. * * NI_NUMERICHOST means to present the numeric address * without doing reverse DNS to get a domain name. */ error = getnameinfo(res->ai_addr, res->ai_addrlen, host, sizeof host, NULL, 0, NI_NUMERICHOST);
if (error) { fprintf(stderr, "%s\n", gai_strerror(error)); } else { /* Print the numeric address. */ printf("%s\n", host); } }
/* Free the linked list. */ freeaddrinfo(res0);
return 0; }</lang>
C#
Implementation takes a host name string as a parameter, and returns the IP addresses in a comma-delimited string. Note that a failed lookup throws a SocketException. <lang csharp>
private string LookupDns(string s) { try { System.Net.IPHostEntry ip = System.Net.Dns.GetHostEntry(s);
string result = ip.AddressList[0].ToString();
for (int i = 1; i < ip.AddressList.Length; ++i) result += ", " + ip.AddressList[i].ToString();
return result; } catch (System.Net.Sockets.SocketException se) { return se.Message; } }
</lang>
Caché ObjectScript
<lang cos> Class Utils.Net [ Abstract ] {
ClassMethod QueryDNS(pHost As %String, Output ip As %List) As %Status { // some initialisation Set ip=$ListBuild()
// check host operating system and input parameters Set os=$Case($ZVersion(1), 1: "vms", 2: "win", 3: "*nx", : "") If (os="vms")||(os="") Quit $$$ERROR($$$GeneralError, "Not implemented.") If os="win" Set cmd="nslookup "_pHost If os="*nx" Set cmd="host "_pHost If $Match(pHost, "^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$")=0 { Quit $$$ERROR($$$GeneralError, "Invalid host name.") }
// enable end-of-file flagging Do $System.Process.SetZEOF(1)
// invoke command Open cmd:"QR":15 If $Test { For i=1:1 { If i>100 Quit Use cmd Read row If $ZEOF Quit If os="win" Set os=$Select(row["Name:": "", 1: os) Continue Set ipv4=..GetIPAddr("ipv4", row) If $Length(ipv4) Set $List(ip, 4)=ipv4 Set ipv6=..GetIPAddr("ipv6", row) If $Length(ipv6) Set $List(ip, 6)=ipv6 } Close cmd }
// disable end-of-file flagging Do $System.Process.SetZEOF(0)
// finished If $ListData(ip, 4)=0, $ListData(ip, 6)=0 Quit $$$ERROR($$$GeneralError, "Lookup failed.") Quit $$$OK }
ClassMethod GetIPAddr(pType As %String = "", pRow As %String = "") As %String { If pType="ipv4" { Set pos=$Locate(pRow, "((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.|$)){4}") If pos Quit $Piece($Extract(pRow, pos, *), " ") } ElseIf pType="ipv6" { Set pos=$Locate(pRow, "([0-9A-Fa-f]{0,4}:){2,7}([0-9A-Fa-f]{1,4}$|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4})") If pos Quit $Piece($Extract(pRow, pos, *), " ") } Quit "" }
} </lang>
- Examples:
USER>Do ##class(Utils.Net).QueryDNS("www.kame.net", .ip) USER>Write "IPv4 address = ", $ListGet(ip, 4, "Not found") IPv4 address = 203.178.141.194 USER>Write "IPv6 address = ", $ListGet(ip, 6, "Not found") IPv6 address = 2001:200:dff:fff1:216:3eff:feb1:44d7 USER>Do ##class(Utils.Net).QueryDNS("ipv6.google.com", .ip) USER>Write "IPv4 address = ", $ListGet(ip, 4, "Not found") IPv4 address = Not found USER>Write "IPv6 address = ", $ListGet(ip, 6, "Not found") IPv6 address = 2a00:1450:400c:c05::93
Clojure
<lang clojure>(import java.net.InetAddress java.net.Inet4Address java.net.Inet6Address)
(doseq [addr (InetAddress/getAllByName "www.kame.net")]
(cond (instance? Inet4Address addr) (println "IPv4:" (.getHostAddress addr)) (instance? Inet6Address addr) (println "IPv6:" (.getHostAddress addr))))</lang>
Output:
IPv4: 203.178.141.194 IPv6: 2001:200:dff:fff1:216:3eff:feb1:44d7
CoffeeScript
<lang coffeescript>
- runs under node.js
dns = require 'dns'
dns.resolve4 'www.kame.net', (err, addresses) ->
console.log 'IP4' console.log addresses
dns.resolve6 'www.kame.net', (err, addresses) ->
console.log 'IP6' console.log addresses
</lang>
Common Lisp
common lisp does not have a standard network api. the following examples are using native implementations
<lang lisp>(sb-bsd-sockets:host-ent-addresses
(sb-bsd-sockets:get-host-by-name "www.rosettacode.org"))
(#(71 19 147 227))</lang>
<lang lisp>(let ((hostname (extensions:lookup-host-entry "www.rosettacode.org")))
(print (map 'list #'extensions:ip-string (host-entry-addr-list hostname))))
("71.19.147.227")</lang> the usocket library contains a (get-hosts-by-name) function in all of its backends. unfortunately it does not expose the functions in its public interface. but since the license is MIT, it may be a suitable source to copy code for your own use.
is a portable library that:
<lang lisp>(iolib:lookup-hostname "www.kame.net" :ipv6 t)
- /IOLIB.SOCKETS:IP/203.178.141.194
(#/IOLIB.SOCKETS:IP/2001:200:dff:fff1:216:3eff:feb1:44d7) "orange.kame.net" (("orange.kame.net" . #/IOLIB.SOCKETS:IP/203.178.141.194)
("orange.kame.net" . #/IOLIB.SOCKETS:IP/2001:200:dff:fff1:216:3eff:feb1:44d7))</lang>
D
<lang d>import std.stdio, std.socket;
void main() {
auto domain = "www.kame.net", port = "80";
auto a = getAddressInfo(domain, port); writefln("IPv4 address for %s: %s", domain, a[0].address);
a = getAddressInfo(domain, port, AddressFamily.INET6); writefln("IPv6 address for %s: %s", domain, a[0].address);
}</lang>
IPv4 address for www.kame.net: 203.178.141.194:80 IPv6 address for www.kame.net: [2001:200:dff:fff1:216:3eff:feb1:44d7]:80
Delphi
The included Indy components wrap GetAddressInfo.
<lang Delphi>program DNSQuerying;
{$APPTYPE CONSOLE}
uses
IdGlobal, IdStackWindows;
const
DOMAIN_NAME = 'www.kame.net';
var
lStack: TIdStackWindows;
begin
lStack := TIdStackWindows.Create; try Writeln(DOMAIN_NAME); Writeln('IPv4: ' + lStack.ResolveHost(DOMAIN_NAME)); Writeln('IPv6: ' + lStack.ResolveHost(DOMAIN_NAME, Id_IPv6)); finally lStack.Free; end;
end.</lang>
Output:
www.kame.net IPv4: 203.178.141.194 IPv6: 2001:200:DFF:FFF1:216:3EFF:FEB1:44D7
Go
<lang go>package main
import (
"fmt" "net"
)
func main() {
if addrs, err := net.LookupHost("www.kame.net"); err == nil { fmt.Println(addrs) } else { fmt.Println(err) }
}</lang> Output:
[203.178.141.194 2001:200:dff:fff1:216:3eff:feb1:44d7]
Haskell
<lang haskell>module Main where
import Network.Socket
getWebAddresses :: HostName -> IO [SockAddr] getWebAddresses host = do
results <- getAddrInfo (Just defaultHints) (Just host) (Just "http") return [ addrAddress a | a <- results, addrSocketType a == Stream ]
showIPs :: HostName -> IO () showIPs host = do
putStrLn $ "IP addresses for " ++ host ++ ":" addresses <- getWebAddresses host mapM_ (putStrLn . (" "++) . show) addresses
main = showIPs "www.kame.net" </lang> Output:
IP addresses for www.kame.net: 203.178.141.194:80 [2001:200:dff:fff1:216:3eff:feb1:44d7]:80
Java
<lang java>import java.net.InetAddress; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.UnknownHostException;
class DnsQuery {
public static void main(String[] args) { try { InetAddress[] ipAddr = InetAddress.getAllByName("www.kame.net"); for(int i=0; i < ipAddr.length ; i++) { if (ipAddr[i] instanceof Inet4Address) { System.out.println("IPv4 : " + ipAddr[i].getHostAddress()); } else if (ipAddr[i] instanceof Inet6Address) { System.out.println("IPv6 : " + ipAddr[i].getHostAddress()); } } } catch (UnknownHostException uhe) { System.err.println("unknown host"); } }
} </lang> Output:
IPv4 : 203.178.141.194 IPv6 : 2001:200:dff:fff1:216:3eff:feb1:44d7
Lasso
The DNS lookup methods in Lasso do not support IPv6 addresses at this time, only IPv4. <lang Lasso>dns_lookup('www.kame.net', -type='A')</lang>
NetRexx
<lang netrexx> /* NetRexx */ options replace format comments java crossref symbols nobinary
ir = InetAddress addresses = InetAddress[] InetAddress.getAllByName('www.kame.net') loop ir over addresses
if ir <= Inet4Address then do say 'IPv4 :' ir.getHostAddress end if ir <= Inet6Address then do say 'IPv6 :' ir.getHostAddress end end ir
</lang>
- Output
IPv4 : 203.178.141.194 IPv6 : 2001:200:dff:fff1:216:3eff:feb1:44d7
OCaml
<lang ocaml>let dns_query ~host ~ai_family =
let opts = [ Unix.AI_FAMILY ai_family; Unix.AI_SOCKTYPE Unix.SOCK_DGRAM; ] in let addr_infos = Unix.getaddrinfo host "" opts in match addr_infos with | [] -> failwith "dns_query" | ai :: _ -> match ai.Unix.ai_addr with | Unix.ADDR_INET (addr, _) -> (Unix.string_of_inet_addr addr) | Unix.ADDR_UNIX addr -> failwith "addr_unix"
let () =
let host = "www.kame.net" in Printf.printf "primary addresses of %s are:\n" host;
Printf.printf " IPv4 address: %s\n" (dns_query host Unix.PF_INET); Printf.printf " IPv6 address: %s\n" (dns_query host Unix.PF_INET6);
- </lang>
Perl
Unfortunately IPv6 was only added to Perl 5.14, a relatively new version. <lang perl>require 5.014; # Older versions can't resolve IPv6 with just core Socket module
use Socket qw(getaddrinfo getnameinfo); my ($err, @res) = getaddrinfo("www.kame.net", 0,
{ protocol=>Socket::IPPROTO_TCP } );
die "getaddrinfo error: $err" if $err;
print getnameinfo($_->{addr}, Socket::NI_NUMERICHOST), "\n" for @res </lang>
PHP
Works for PHP5 (Windows > 5.3.0) <lang php><?php
$ipv4_record = dns_get_record("www.kame.net",DNS_A); $ipv6_record = dns_get_record("www.kame.net",DNS_AAAA); print "ipv4: " . $ipv4_record[0]["ip"] . "\n"; print "ipv6: " . $ipv6_record[0]["ipv6"] . "\n";
?></lang>
PicoLisp
<lang PicoLisp>(make
(in '(host "www.kame.net") (while (from "address ") (link (till "^J" T)) ) ) )</lang>
Output:
-> ("203.178.141.194" "2001:200:dff:fff1:216:3eff:feb1:44d7")
Python
<lang python>>>> import socket >>> ips = set(i[4][0] for i in socket.getaddrinfo('www.kame.net', 80)) >>> for ip in ips: print ip ... 2001:200:dff:fff1:216:3eff:feb1:44d7 203.178.141.194</lang>
Ruby
<lang ruby>irb(main):001:0> require 'socket' => true irb(main):002:0> Addrinfo.getaddrinfo("www.kame.net", nil, nil, :DGRAM) \ irb(main):003:0* .map! { |ai| ai.ip_address } => ["203.178.141.194", "2001:200:dff:fff1:216:3eff:feb1:44d7"]</lang>
Racket
The following finds an IPv4 address. Currently, the API does not support returning an IPv6 address.
<lang racket>
- lang racket
(require net/dns) (dns-get-address "8.8.8.8" "www.kame.net") </lang>
Scheme
<lang scheme>; Query DNS (define n (car (hostent:addr-list (gethost "www.kame.net"))))
- Display address as IPv4 and IPv6
(display (inet-ntoa n))(newline) (display (inet-ntop AF_INET n))(newline) (display (inet-ntop AF_INET6 n))(newline)</lang>
Output:
203.178.141.194 203.178.141.194 ::203.178.141.194
Seed7
The library socket.s7i defines the function inetSocketAddress, which returns an IPv4 address. It only returns an IPv6 address, when a host has no IPv4 address and the operating system supports IPv6. The function numericAddress is used to get the IP address of the specified host. <lang seed7>$ include "seed7_05.s7i";
include "socket.s7i";
const proc: main is func
begin writeln(numericAddress(inetSocketAddress("www.kame.net", 1024))); end func;</lang>
Output:
203.178.141.194
Tcl
While Tcl does internally do address resolution, it doesn't directly support looking up addresses without actually connecting to them. This is left to support packages to provide. An additional complexity is that while the DNS protocol itself is defined to work with both TCP and UDP as the transport layer, Tcl only supports TCP sockets by default (because they have a stream model) whereas DNS is typically only deployed with UDP enabled.
<lang tcl>package require udp; # Query by UDP more widely supported, but requires external package package require dns
set host "www.kame.net" set v4 [dns::resolve $host -type A]; # Specifically get IPv4 address set v6 [dns::resolve $host -type AAAA]; # Specifically get IPv6 address while {[dns::status $v4] eq "connect" || [dns::status $v6] eq "connect"} {
update; # Let queries complete
} puts "primary addresses of $host are:\n\tIPv4» [dns::address $v4]\n\tIPv6» [dns::address $v6]"</lang> Output:
primary addresses of www.kame.net are: IPv4» 203.178.141.194 IPv6» 2001:200:dff:fff1:216:3eff:feb1:44d7
- Programming Tasks
- Networking and Web Interaction
- Ada
- BBC BASIC
- C
- C sharp
- Caché ObjectScript
- Clojure
- CoffeeScript
- Common Lisp
- Iolib
- D
- Delphi
- Go
- Haskell
- Java
- Lasso
- NetRexx
- OCaml
- Perl
- PHP
- PicoLisp
- Python
- Ruby
- Racket
- Scheme
- Seed7
- Tcl
- Tcllib
- Udp
- PARI/GP/Omit
- Mathematica/Omit
- Maxima/Omit
- Lotus 123 Macro Scripting/Omit
- Locomotive Basic/Omit
- ML/I/Omit
- Retro/Omit
- REXX/Omit
- ZX Spectrum Basic/Omit
- Internet Protocol (Multiprotocol)