Jump to content

DNS query

From Rosetta Code
(Redirected from DNS querying)
Task
DNS query
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

Works with: GNAT GPL version Any - package Gnat.Sockets supports only IPv4 as of Jun 2011
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;
Works with: GNAT GPL version 2019 - support for IPv6 was added to Gnat.Sockets sometime before this
with Ada.Text_IO; use Ada.Text_IO;
with GNAT.Sockets; use Gnat.Sockets;
procedure DNSQuerying is
   procedure Print_Address_Info (Host, Serv : String; Family : Family_Type := Family_Unspec) is
      Addresses : Address_Info_Array := Get_Address_Info (Host, Serv, Family, Passive => False, Numeric_Host => False);
      Inet_Addr_V6: Inet_Addr_Type(Family_Inet6);
   begin
      Sort (Addresses, IPv6_TCP_Preferred'Access);
      Inet_Addr_V6 := Addresses(1).Addr.Addr;
      Put_Line("IPv6: " & Image(Value => Inet_Addr_V6));
   end Print_Address_Info;
begin
   Print_Address_Info ("ipv6.google.com", "https", Family_Inet6);
end DNSQuerying;

ARM Assembly

Works with: as version Raspberry Pi
/* ARM assembly Raspberry PI  */
/*  program dnsquery.s   */

/************************************/
/* Constantes                       */
/************************************/
.equ STDIN, 0         @ Linux input console
.equ STDOUT, 1        @ Linux output console

.equ EXIT,   1         @ Linux syscall END PROGRAM
.equ FORK,   2         @ Linux syscall
.equ READ,   3         @ Linux syscall
.equ WRITE,  4         @ Linux syscall
.equ OPEN,   5         @ Linux syscall
.equ CLOSE,  6         @ Linux syscall
.equ EXECVE, 0xB      @ Linux syscall
.equ PIPE,   0x2A     @ Linux syscall
.equ DUP2,   0x3F        @ Linux syscall
.equ WAIT4,  0x72     @ Linux syscall

.equ WUNTRACED,   2   @ Wait, return status of stopped child
.equ TAILLEBUFFER,  500
/*********************************/
/* Initialized data              */
/*********************************/
.data
szCarriageReturn:    .asciz "\n"
szMessFinOK:          .asciz "Fin normale du programme. \n"
szMessError:          .asciz "Error occured !!!"
szCommand:             .asciz "/usr/bin/host"  @ command host
szNameHost:            .asciz "www.kame.net"   @ string query name
.align 4
stArg1:                 .int szCommand           @ address command
                          .int szNameHost          @ address argument
                          .int 0,0                   @ zeroes

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
.align 4
iStatusThread:      .skip 4
pipefd:               .skip 8
sBuffer:              .skip  TAILLEBUFFER
stRusage:             .skip TAILLEBUFFER
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                                           @ entry of program 
    /* création pipe  */
    ldr r0,iAdrpipefd                          @ FDs address
    mov r7, #PIPE                               @ create pipe
    svc 0                                        @ call system Linux
    cmp r0,#0                                    @ error  ?
    blt 99f

    /* create child thread */
    mov r0,#0
    mov r7, #FORK                                @ call system
    svc #0 
    cmp r0,#0                                     @ error ?
    blt 99f
    bne parent                                  @ if <> zero r0 contains father pid
                                                  @ else is the child
/****************************************/
/*  Child thread                       */
/****************************************/
    /* redirection sysout -> pipe */ 
    ldr r0,iAdrpipefd
    ldr r0,[r0,#4]
    mov r7, #DUP2                                @ call system linux 
    mov r1, #STDOUT                             @
    svc #0
    cmp r0,#0                                    @ error ?
    blt 99f

    /* run command host      */
    ldr r0, iAdrszCommand                    @ r0 = address de "/usr/bin/host"
    ldr r1,iAdrstArg1                         @ address argument 1
    mov r2,#0
    mov r7, #EXECVE                            @ call system linux (execve)
    svc #0                                      @ if ok -> no return !!!
    b 100f                                      @ never exec this label
/****************************************/
/*  Father thread                       */
/****************************************/
parent:	
    mov r4,r0                                     @ save child pid
1:                                                @ loop child signal
    mov r0,r4
    ldr r1,iAdriStatusThread                  @ return status thread
    mov r2,#WUNTRACED                           @ flags 
    ldr r3,iAdrstRusage                        @ return structure thread
    mov r7, #WAIT4                               @ Call System 
    svc #0 
    cmp r0,#0                                    @ error ?
    blt 99f
    @ recup status 
    ldr r0,iAdriStatusThread                 @ analyse status
    ldrb r0,[r0]                                @ firest byte
    cmp r0,#0                                    @ normal end thread ?
    bne 1b                                      @ loop

    /* close entry pipe */ 
    ldr r0,iAdrpipefd
    mov r7,#CLOSE                               @ call system
    svc #0 

    /* read datas pipe */ 
    ldr r0,iAdrpipefd
    ldr r0,[r0]
    ldr r1,iAdrsBuffer                        @ buffer address
    mov r2,#TAILLEBUFFER                      @ buffer size
    mov r7, #READ                               @ call system
    svc #0 
    ldr r0,iAdrsBuffer                        @ display buffer
    bl affichageMess

    ldr r0,iAdrszMessFinOK                   @ display message Ok
    bl affichageMess
    mov r0, #0                                   @ return code
    b 100f
99:
    ldr r0,iAdrszMessError                   @ erreur
    bl affichageMess
    mov r0, #1                                   @ return code
    b 100f
100:                                            @ standard end of the program 
    mov r7, #EXIT                               @ request to exit program
    svc #0                                      @ perform the system call

iAdrszCarriageReturn:      .int szCarriageReturn
iAdrszMessFinOK:            .int szMessFinOK
iAdrszMessError:            .int szMessError
iAdrsBuffer:                 .int sBuffer
iAdrpipefd:                  .int pipefd
iAdrszCommand:              .int szCommand
iAdrstArg1:                  .int stArg1
iAdriStatusThread:         .int iStatusThread
iAdrstRusage:                .int stRusage


/******************************************************************/
/*     display text with size calculation                         */ 
/******************************************************************/
/* r0 contains the address of the message */
affichageMess:
    push {r0,r1,r2,r7,lr}                          @ save  registres
    mov r2,#0                                      @ counter length 
1:                                                 @ loop length calculation 
    ldrb r1,[r0,r2]                               @ read octet start position + index 
    cmp r1,#0                                      @ if 0 its over 
    addne r2,r2,#1                                @ else add 1 in the length 
    bne 1b                                        @ and loop 
                                                   @ so here r2 contains the length of the message 
    mov r1,r0                                      @ address message in r1 
    mov r0,#STDOUT                                @ code to write to the standard output Linux 
    mov r7, #WRITE                                @ code call system "write" 
    svc #0                                        @ call systeme 
    pop {r0,r1,r2,r7,lr}                           @ restaur des  2 registres */ 
    bx lr                                          @ return

ATS

Translation of: C

This has been tested on Gentoo Linux with PATSHOME properly set.

You need some X/Open standard stuff in your libc, so running the default patscc (which sets -std=c99) will not work. I have written the code so you can compile with myatscc.

(*

This program has to be compiled without -std=c99, which patscc will
insert unless you override the setting.

##myatsccdef=\
patscc \
  -atsccomp gcc \
  -I"${PATSHOME}" \
  -I"${PATSHOME}/ccomp/runtime" \
  -L"${PATSHOME}/ccomp/atslib/lib" \
  -DATS_MEMALLOC_LIBC \
  -o $fname($1) $1

*)

(* The code below is largely C, but the ATS interface enforces memory
   management. For instance, try removing the call to "addrinfo_free",
   and see what happens. You will get an error message from the
   compiler. *)

#include "share/atspre_staload.hats"
staload UN = "prelude/SATS/unsafe.sats"

#define ATS_EXTERN_PREFIX "rosetta_code_"

%{^

#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>

ATSinline() atstype_int
rosetta_code__getaddrinfo (atstype_ptr node,
                           atstype_ptr service,
                           atstype_int ai_flags,
                           atstype_int ai_family,
                           atstype_int ai_socktype,
                           atstype_int ai_protocol,
                           atstype_ptr res)
{
  struct addrinfo hints;
  memset (&hints, 0, sizeof hints);
  hints.ai_flags = ai_flags;
  hints.ai_family = ai_family;
  hints.ai_socktype = ai_socktype;
  hints.ai_protocol = ai_protocol;
  return getaddrinfo ((const char *) node,
                      (const char *) service,
                      &hints,
                      (struct addrinfo **) res);
}

ATSinline() atstype_void
rosetta_code__freeaddrinfo (atstype_ptr res)
{
  freeaddrinfo ((struct addrinfo *) res);
}

ATSinline() atstype_string
rosetta_code__gai_strerror (atstype_int errcode)
{
  return (atstype_string) gai_strerror (errcode);
}

ATSinline() atstype_ptr
rosetta_code__ai_next (atstype_ptr p)
{
  return (atstype_ptr) ((struct addrinfo *) p)->ai_next;
}

ATSinline() void
rosetta_code__ai_get_numeric_host (atstype_ptr addrinfo,
                                   atstype_ptr host,
                                   atstype_ptr errcode)
{
  struct addrinfo *p_addrinfo = (struct addrinfo *) addrinfo;
  char **p_host = (char **) host;
  int *p_errcode = (int *) errcode;

  char buf[NI_MAXHOST];
  *p_errcode = getnameinfo (p_addrinfo->ai_addr,
                            p_addrinfo->ai_addrlen,
                            buf, sizeof buf, NULL, 0,
                            NI_NUMERICHOST);
  *p_host = ( *p_errcode == 0 ) ? (strdup (buf)) : NULL;
}

%}

#define NIL list_vt_nil ()
#define ::  list_vt_cons

implement list_vt_freelin$clear<Strptr1> s = strptr_free s

macdef AF_UNSPEC = $extval (int, "AF_UNSPEC")
macdef SOCK_DGRAM = $extval (int, "SOCK_DGRAM")

absview addrinfo_v (p        : addr,
                    freeable : bool)

vtypedef addrinfo (p        : addr,
                   freeable : bool) =
  [null < p]
  @(addrinfo_v (p, freeable) |
    ptr p)

vtypedef addrinfo (p : addr) =
  [freeable : bool]
  addrinfo (p, freeable)

vtypedef addrinfo (freeable : bool) =
  [p : addr]
  addrinfo (p, freeable)

vtypedef addrinfo =
  [p : addr]
  [freeable : bool]
  addrinfo (p, freeable)

vtypedef freeable_addrinfo (p : addr) = addrinfo (p, true)
vtypedef freeable_addrinfo = addrinfo true
vtypedef unfreeable_addrinfo (p : addr) = addrinfo (p, false)
vtypedef unfreeable_addrinfo = addrinfo false

fn
addrinfo_strerror (errcode : int)
    : string =
  let
    extern fn _gai_strerror : int -<> string = "mac#%"
  in
    _gai_strerror errcode
  end

fn
addrinfo_fetch (node        : !Strptr0,
                service     : !Strptr0,
                ai_flags    : int,
                ai_family   : int,
                ai_socktype : int,
                ai_protocol : int,
                error       : &int? >> int)
    : Option_vt ([p : agz] addrinfo (p, true)) =
  let
    extern fn
    _getaddrinfo (node        : !Strptr0,
                  service     : !Strptr0,
                  ai_flags    : int,
                  ai_family   : int,
                  ai_socktype : int,
                  ai_protocol : int,
                  result      : &ptr? >> ptr p)
        : #[p : addr]
          int = "mac#%"

    var p : ptr
    val err = _getaddrinfo (node, service, ai_flags, ai_family,
                            ai_socktype, ai_protocol, p)
    prval [p : addr] EQADDR () = eqaddr_make_ptr p
  in
    error := err;
    if (err = 0) * (isneqz p) then
      let
        extern praxi make_view : () -<prf> addrinfo_v (p, true)
      in
        Some_vt @(make_view () | p)
      end
    else
      None_vt ()
  end

fn
addrinfo_free {p : addr}
              (addrinfo : freeable_addrinfo p)
    : void =
  let
    extern fn _freeaddrinfo : ptr -> void = "mac#%"
    extern praxi consume_view : addrinfo_v (p, true) -<prf> void

    val @(pf | p) = addrinfo
    prval () = consume_view pf
  in
    _freeaddrinfo p
  end

prfn
unfreeable_addrinfo_finalize {p : addr}
                             (addrinfo : unfreeable_addrinfo p)
    :<prf> void =
  let
    extern praxi consume_view : addrinfo_v (p, false) -<prf> void
  in
    consume_view (addrinfo.0)
  end

fn
addrinfo_next (addrinfo : !addrinfo)
    :<> Option_vt (addrinfo false) =
  let
    extern fn _ai_next : ptr -<> [q : agez] ptr q = "mac#%"
    val [q : addr] q = _ai_next (addrinfo.1)
  in
    if iseqz q then
      None_vt ()
    else
      let
        extern praxi make_view : () -<prf> addrinfo_v (q, false)
      in
        Some_vt @(make_view () | q)
      end
  end

fn
addrinfo_get_numeric_host (addrinfo : !addrinfo,
                           errcode  : &int? >> int)
    : Option_vt Strptr1 =
  let
    extern fn
    _ai_get_numeric_host (addrinfo : Ptr,
                          host     : &ptr? >> Ptr,
                          errcode  : &int? >> int)
        : void = "mac#%"

    var host : ptr
  in
    _ai_get_numeric_host (addrinfo.1, host, errcode);
    if (errcode = 0) * (isneqz host) then
      Some_vt ($UN.castvwtp0 host)
    else
      None_vt ()
  end

fn
get_numeric_hosts (addrinfo : !freeable_addrinfo)
    : Option_vt (List1_vt Strptr1) =
  let
    fun
    loop (ainfo : !unfreeable_addrinfo,
          accum : List1_vt Strptr1)
        : Option_vt (List1_vt Strptr1) =
      let
        var errcode : int
        val ai_opt = addrinfo_get_numeric_host (ainfo, errcode)
      in
        case+ ai_opt of
        | ~ None_vt () =>
          begin
            list_vt_freelin<Strptr1> accum;
            fprintln! (stderr_ref, "Error: ",
                       addrinfo_strerror errcode);
            None_vt ()
          end
        | ~ Some_vt host =>
          let
            val next_ai_opt = addrinfo_next ainfo
            and accum = host :: accum
          in
            case+ next_ai_opt of
            | ~ None_vt () => Some_vt (list_vt_reverse accum)
            | ~ Some_vt next_ai =>
              let
                val retval = loop (next_ai, accum)
                prval () = unfreeable_addrinfo_finalize next_ai
              in
                retval
              end
          end
      end

    var errcode : int
    val ai_opt = addrinfo_get_numeric_host (addrinfo, errcode)
  in
    case+ ai_opt of
    | ~ None_vt () =>
      begin
        fprintln! (stderr_ref, "Error: ", addrinfo_strerror errcode);
        None_vt ()
      end
    | ~ Some_vt host =>
      let
        val next_ai_opt = addrinfo_next addrinfo
        and accum = host :: NIL
      in
        case+ next_ai_opt of
        | ~ None_vt () => Some_vt accum
        | ~ Some_vt next_ai =>
          let
            val retval = loop (next_ai, accum)
            prval () = unfreeable_addrinfo_finalize next_ai
          in
            retval
          end
      end
  end

implement
main0 () =
  let
    val hostname = string0_copy "www.kame.net"
    val service = strptr_null ()
    var errcode : int
    val ai_opt = addrinfo_fetch (hostname, service, 0, AF_UNSPEC,
                                 SOCK_DGRAM, 0, errcode)
    val () = strptr_free hostname
    prval () = strptr_free_null service
  in
    case+ ai_opt of
    | ~ None_vt () =>
      begin
        fprintln! (stderr_ref, "Error: ", addrinfo_strerror errcode);
        exit 1
      end
    | ~ Some_vt addrinfo =>
      let
        val hosts_opt = get_numeric_hosts addrinfo
      in
        addrinfo_free addrinfo;
        case+ hosts_opt of
        | ~ None_vt () => exit 1
        | ~ Some_vt hosts =>
          begin
            println! ($UN.castvwtp1{List1 string} hosts);
            list_vt_freelin hosts
          end
      end
  end
Output:
$ myatscc dns-query.dats && ./dns-query
210.155.141.200, 2001:2f0:0:8800:226:2dff:fe0b:4311, 2001:2f0:0:8800::1:1

AutoHotkey

This code uses Windows built-in 'nslookup' command (and a temporary file):

Url := "www.kame.net" , LogFile := "Ping_" A_Now ".log"
Runwait, %comspec% /c nslookup %Url%>%LogFile%, , hide
FileRead, Contents, %LogFile%
FileDelete, %LogFile%
RegExMatch(Contents,"Addresses:.+(`r?`n\s+.+)*",Match)
MsgBox, % RegExReplace(Match,"(Addresses:|[ `t])")

Batch File

:: DNS Query Task from Rosetta Code Wiki
:: Batch File Implementation

@echo off

set "domain=www.kame.net"
echo DOMAIN: "%domain%"
echo(
call :DNS_Lookup "%domain%"
pause
exit /b

::Main Procedure
::Uses NSLOOKUP Command. Also uses a dirty "parsing" to detect IP addresses.
:DNS_Lookup [domain]

::Define Variables and the TAB Character
set "dom=%~1"
set "record="
set "reccnt=0"
for /f "delims=" %%T in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') do set "TAB=%%T"

setlocal enabledelayedexpansion
for /f "tokens=1* delims=:" %%x in ('nslookup "!dom!" 2^>nul') do (
    set "line=%%x"
    if /i "!line:~0,4!"=="Name" set "record=yes"
    if /i "!line:~0,5!"=="Alias" set "record="
    if "!record!"=="yes" (
        set /a reccnt+=1
        if "%%y"=="" (set "catch_!reccnt!=%%x") else (set "catch_!reccnt!=%%x:%%y")
    )
)
for /l %%c in (1,1,%reccnt%) do (
    if /i "!catch_%%c:~0,7!"=="Address" echo(!catch_%%c:*s:  =!
    if /i "!catch_%%c:~0,1!"=="%TAB%" echo(!catch_%%c:%TAB%  =!
)
endlocal
goto :EOF
Output:
DOMAIN: "www.kame.net"

2001:200:dff:fff1:216:3eff:feb1:44d7
203.178.141.194
Press any key to continue . . .

BBC BASIC

      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`

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.

#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;
}

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.

        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;
            }
        }

C++

This example makes use of the Boost library. The asio bit is header-only, but requires linking boost-system (e.g. -lboost_system). The compiler may also need to be told to use C++11 semantics (e.g. -std=c++11).

#include <boost/asio.hpp>
#include <iostream>

int main() {
  int rc {EXIT_SUCCESS};
  try {
    boost::asio::io_service io_service;
    boost::asio::ip::tcp::resolver resolver {io_service};
    auto entries = resolver.resolve({"www.kame.net", ""});
    boost::asio::ip::tcp::resolver::iterator entries_end;
    for (; entries != entries_end; ++entries) {
      std::cout << entries->endpoint().address() << std::endl;
    }
  }
  catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
    rc = EXIT_FAILURE;
  }
  return rc;
}

Caché ObjectScript

Class Utils.Net Extends %RegisteredObject
{

ClassMethod QueryDNS(pHost As %String, Output ip As %List) As %Status
{
	// some initialisation
	K ip S ip=""
 
	// check host operating system and input parameters
	S OS=$SYSTEM.Version.GetOS()
	I '$LF($LB("Windows","UNIX"), OS) Q $$$ERROR($$$GeneralError, "Not implemented.")
	I OS="Windows" S cmd="nslookup "_pHost
	I OS="UNIX" S cmd="host "_pHost
	I $MATCH(pHost, "^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$")=0 {
		Q $$$ERROR($$$GeneralError, "Invalid host name.")
	}
	
	// invoke command
	S list=##class(Utils.OS).Call(cmd, 0)
	
	// iterate through list
	S ptr=0, skip=1
    WHILE $LISTNEXT(list,ptr,value) {
	    I value="" CONTINUE
	    I skip, OS="Windows" S skip=$S(value["Name:": 0, 1: 1) CONTINUE
	    S ipv4=..GetIPAddr("ipv4", value) I $L(ipv4) S $LI(ip, 4)=ipv4
	    S ipv6=..GetIPAddr("ipv6", value) I $L(ipv6) S $LI(ip, 6)=ipv6
    }
	
	// finished
	I $LD(ip, 4)=0, $LD(ip, 6)=0 Q $$$ERROR($$$GeneralError, "Lookup failed.")
	QUIT $$$OK
}

ClassMethod GetIPAddr(pType As %String = "", pValue As %String = "") As %String
{
	I pType="ipv4" {
		S pos=$LOCATE(pValue, "((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.|$)){4}")
		I pos Q $P($E(pValue, pos, *), " ")
	}
	I pType="ipv6" {
		S pos=$LOCATE(pValue, "([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})")
		I pos Q $P($E(pValue, pos, *), " ")
	}
	QUIT ""
}

}
Class Utils.OS Extends %RegisteredObject
{

ClassMethod Call(cmd, echo = 1) As %List
{
	// instatiate pipe object
	S list=""
	S pipe=##class(%File).%New(cmd)
		
	TRY {
		// 
		S sc=pipe.Open("QR")
		I $$$ISERR(sc) Q
		
		// read queue/pipe and output to screen
		DO {
			K len S line=pipe.ReadLine(.len) I len=-1 Q
			S $LI(list,$I(pos))=line
			I echo W line,!
		} WHILE $G(pos)<1000
		
	} CATCH {
		S ZE=$ZE
		BREAK
	}
	
	// close pipe
	D pipe.Close()
	
	// return list value
	Q list
}

}
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

(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))))

Output:

IPv4: 203.178.141.194
IPv6: 2001:200:dff:fff1:216:3eff:feb1:44d7

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

Common Lisp

common lisp does not have a standard network api. the following examples are using native implementations

Works with: SBCL
(sb-bsd-sockets:host-ent-addresses 
      (sb-bsd-sockets:get-host-by-name "www.rosettacode.org"))
(#(71 19 147 227))
Works with: CMUCL
(let ((hostname (extensions:lookup-host-entry "www.rosettacode.org")))
                (print (map 'list #'extensions:ip-string (host-entry-addr-list hostname))))
("71.19.147.227")
Works with: Clozure
(ipaddr-to-dotted (lookup-hostname "www.rosettacode.org"))
"104.28.10.103"
Works with: Clisp
(hostent-addr-list (resolve-host-ipaddr "www.rosettacode.org"))
("104.28.11.103" "104.28.10.103")

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.

Library: iolib

is a portable library that:

Works with: SBCL
Works with: CMUCL
Works with: Clisp
Works with: Clozure
(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))

In Allegro Common Lisp there's a nice standard library called socket.

Works with: Allegro
(socket:ipaddr-to-dotted
 (socket:dns-query "www.rosettacode.org"))
"104.28.10.103"

In Lispworks the COMM package provides information about IP addresses.

Works with: Lispworks
(require "comm")
(comm:ip-address-string (comm:get-host-entry "www.rosettacode.org" :fields '(:address)))
"104.28.10.103"

Crystal

require "socket"

Socket::Addrinfo.resolve(
	"www.kame.net",
	80,
	type: Socket::Type::STREAM
).each { |a|
	puts a.ip_address.address
}
Output:
203.178.141.194
2001:200:dff:fff1:216:3eff:feb1:44d7

D

import std.stdio, std.socket;

void main() {
    auto domain = "www.kame.net", port = "80";

    auto a = getAddressInfo(domain, port, AddressFamily.INET);
    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);
}
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.

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.

Output:

www.kame.net
IPv4: 203.178.141.194
IPv6: 2001:200:DFF:FFF1:216:3EFF:FEB1:44D7

Erlang

33> {ok, {hostent, Host, Aliases, AddrType, Bytes, AddrList}} = inet:gethostbyname("www.kame.net", inet). 
{ok,{hostent,"orange.kame.net",
             ["www.kame.net"],
             inet,4,
             [{203,178,141,194}]}}
34> [inet_parse:ntoa(Addr) || Addr <- AddrList].                                                         
["203.178.141.194"]
35> f().                                                                                                 
ok
36> {ok, {hostent, Host, Aliases, AddrType, Bytes, AddrList}} = inet:gethostbyname("www.kame.net", inet6).
{ok,{hostent,"orange.kame.net",[],inet6,16,
             [{8193,512,3583,65521,534,16127,65201,17623}]}}
37> [inet_parse:ntoa(Addr) || Addr <- AddrList].                                                          
["2001:200:DFF:FFF1:216:3EFF:FEB1:44D7"]

Factor

USING: dns io kernel sequences ;

"www.kame.net" [ dns-A-query ] [ dns-AAAA-query ] bi
[ message>names second print ] bi@
Output:
203.178.141.194
2001:200:dff:fff1:216:3eff:feb1:44d7

FreeBASIC

#include "win\winsock2.bi"

Function GetSiteAddress(stuff As String = "www.freebasic.net") As Long
    Dim As WSADATA _wsadate
    Dim As in_addr addr
    Dim As hostent Ptr res
    Dim As Integer i = 0
    
    WSAStartup(MAKEWORD(2,2),@_wsadate)
    res = gethostbyname(stuff)
    
    If res Then
        Print !"\nURL: "; stuff
        While (res->h_addr_list[i] <> 0)
            addr.s_addr = *(Cast (Ulong Ptr,res->h_addr_list[i]))
            Print "IPv4 address: ";*inet_ntoa(addr)
            i+=1
        Wend
        WSACleanup()
        Return 1
    Else
        Print "website error?"
        Return 0
    End If
End Function

GetSiteAddress "rosettacode.org"
GetSiteAddress "www.kame.net"

Sleep
Output:
URL: rosettacode.org
IPv4 address: 108.175.15.182
IPv4 address: 74.208.203.152

URL: www.kame.net
IPv4 address: 210.155.141.200

Frink

for a = callJava["java.net.InetAddress", "getAllByName", "www.kame.net"]
   println[a.getHostAddress[]]
Output:
210.155.141.200
2001:2f0:0:8800:226:2dff:fe0b:4311
2001:2f0:0:8800:0:0:1:1


FutureBasic

FB has several ways to query a DNS server. In FB 7.0.23 the unix statement/function was added making such queries trivial:

print unix @"nslookup -querytype=A www.kame.net"
HandleEvents

Classic FB:

Str255 UnixCommand
Str255 UnixResponse

print "DNS IPv4 resolved for www.kame.net:"
UnixCommand = "nslookup -querytype=A www.kame.net"
open "UNIX", 1, UnixCommand
while ( not eof( 1 ) )
  input #1, UnixResponse
  print UnixResponse
wend
close 1

print ""

print "DNS IPv6 resolved for www.kame.net:"
UnixCommand = "nslookup -querytype=AAAA www.kame.net"
open "UNIX", 1, UnixCommand
while ( not eof( 1 ) )
  input #1, UnixResponse
  print UnixResponse
wend
close 1

HandleEvents
Output:
DNS IPv4 resolved for www.kame.net:
Server:		2001:1998:f00:2::1
Address:	2001:1998:f00:2::1#53

Non-authoritative answer:
www.kame.net	canonical name = mango.itojun.org.
Name:	mango.itojun.org
Address: 210.155.141.200


DNS IPv6 resolved for www.kame.net:
Server:		2001:1998:f00:2::1
Address:	2001:1998:f00:2::1#53

Non-authoritative answer:
www.kame.net	canonical name = mango.itojun.org.
mango.itojun.org	has AAAA address 2001:2f0:0:8800::1:1
mango.itojun.org	has AAAA address 2001:2f0:0:8800:226:2dff:fe0b:4311

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)
    }
}

Output:

[203.178.141.194 2001:200:dff:fff1:216:3eff:feb1:44d7]

Groovy

def addresses = InetAddress.getAllByName('www.kame.net')
println "IPv4: ${addresses.find { it instanceof Inet4Address }?.hostAddress}"
println "IPv6: ${addresses.find { it instanceof Inet6Address }?.hostAddress}"

Output:

IPv4: 203.178.141.194
IPv6: 2001:200:dff:fff1:216:3eff:feb1:44d7

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"

Output:

IP addresses for www.kame.net:
  203.178.141.194:80
  [2001:200:dff:fff1:216:3eff:feb1:44d7]:80

Icon and Unicon

The following was tested only in Unicon:

procedure main(A)
   host := gethost( A[1] | "www.kame.net") | stop("can't translate")
   write(host.name, ": ", host.addresses)
end

Sample Run:

--> dns
orange.kame.net: 203.178.141.194

--> dns www.gogole.com
www.gogole.com: 74.125.225.183,119.119.119.46,74.125.225.184

J

J currently doesn't have a native DNS implementation, and this task doesn't seem to be asking for us to implement DNS on top of UDP+TCP (a full implementation of DNS has to fall back to TCP for messages which cannot fit in a UDP packet).

Also, there's currently an issue with IPv6 DNS servers not being reachable, so that query did not resolve.

Anyways:

   2!:0'dig -4 +short www.kame.net'
orange.kame.net.
203.178.141.194

   2!:0'dig -6 +short www.kame.net'
|interface error
|       2!:0'dig -6 +short www.kame.net'

Put differently: in the IPv4 DNS system, www.kame.net is currently a CNAME record for orange.kame.net which had the address 203.178.141.194.

And, as mentioned above, the IPv6 DNS system was not reachable.

Java

This is the same implementation as below, just less code

import java.net.InetAddress;
import java.net.UnknownHostException;
public static void main(String[] args) throws UnknownHostException {
    /* 'getAllByName' will use the system configured 'resolver' */
    for (InetAddress ip : InetAddress.getAllByName("www.kame.net"))
        System.out.println(ip.getHostAddress());
}
210.155.141.200
2001:2f0:0:8800:226:2dff:fe0b:4311
2001:2f0:0:8800:0:0:1:1


An alternate demonstration

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");
        }
    }
}

Output:

IPv4 : 203.178.141.194
IPv6 : 2001:200:dff:fff1:216:3eff:feb1:44d7

JavaScript

const dns = require("dns");

dns.lookup("www.kame.net", {
             all: true
          }, (err, addresses) => {
              if(err) return console.error(err);
              console.log(addresses);
          })

Output:

[ { address: '203.178.141.194', family: 4 },
  { address: '2001:200:dff:fff1:216:3eff:feb1:44d7', family: 6 } ]

Julia

As entered at the REPL command line:

julia> using Sockets

julia> getaddrinfo("www.kame.net")
ip"203.178.141.194"

julia> getaddrinfo("www.kame.net", IPv6)
ip"2001:200:dff:fff1:216:3eff:feb1:44d7"

Kotlin

// version 1.1.3

import java.net.InetAddress
import java.net.Inet4Address
import java.net.Inet6Address

fun showIPAddresses(host: String) {
    try {
        val ipas = InetAddress.getAllByName(host)
        println("The IP address(es) for '$host' is/are:\n")
        for (ipa in ipas) {
            print(when (ipa) {
                is Inet4Address -> "  ipv4 : "
                is Inet6Address -> "  ipv6 : "
                else            -> "  ipv? : "
            })
            println(ipa.hostAddress)
        }
    }
    catch (ex: Exception) {
        println(ex.message)
    } 
}

fun main(args: Array<String>) {
    showIPAddresses("www.kame.net")
}
Output:
The IP address(es) for 'www.kame.net' is/are:

  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.

dns_lookup('www.kame.net', -type='A')

Lua

Works with: Lua version 5.1 - 5.3
Library: LuaSocket
local socket = require('socket')
local ip_tbl = socket.dns.getaddrinfo('www.kame.net')

for _, v in ipairs(ip_tbl) do
  io.write(string.format('%s: %s\n', v.family, v.addr))
end
Output:
inet: 203.178.141.194
inet6: 2001:200:dff:fff1:216:3eff:feb1:44d7

Neko

Neko does not yet support ipv6. ipv4 addresses are returned as Int32.

/* dns in neko */
var host_resolve = $loader.loadprim("std@host_resolve", 1);
var host_to_string = $loader.loadprim("std@host_to_string", 1);
var host_reverse = $loader.loadprim("std@host_reverse", 1);

var ip = host_resolve("www.kame.net");

$print("www.kame.net: ", ip, ", ", host_to_string(ip), "\n");
$print(host_to_string(ip), ": ", host_reverse(ip), "\n");
Output:
prompt$ nekoc dns.neko
prompt$ neko dns
www.kame.net: -1030901045, 203.178.141.194
203.178.141.194: orange.kame.net

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
Output
IPv4 : 203.178.141.194
IPv6 : 2001:200:dff:fff1:216:3eff:feb1:44d7

NewLISP

(define (dnsLookup site , ipv)
    ;; captures current IPv mode
    (set 'ipv (net-ipv))
    ;; IPv mode agnostic lookup
    (println "IPv4: " (begin (net-ipv 4) (net-lookup site)))
    (println "IPv6: " (begin (net-ipv 6) (net-lookup site)))
    ;; returns newLISP to previous IPv mode
    (net-ipv ipv)
)

(dnsLookup "www.kame.net")
Output
IPv4: 203.178.141.194
IPv6: 2001:200:dff:fff1:216:3eff:feb1:44d7

Nim

import nativesockets

iterator items(ai: ptr AddrInfo): ptr AddrInfo =
  var current = ai
  while current != nil:
    yield current
    current = current.aiNext

proc main() =
  let addrInfos = getAddrInfo("www.kame.net", Port 80, AfUnspec)
  defer: freeAddrInfo addrInfos

  for i in addrInfos:
    echo getAddrString i.aiAddr

when isMainModule: main()
Output:
2001:200:dff:fff1:216:3eff:feb1:44d7
203.178.141.194

Oberon-2

Works with: oo2c version 2

IO:Address module supports only IPv4

MODULE DNSQuery;
IMPORT
  IO:Address,
  Out := NPCT:Console;

PROCEDURE Do() RAISES Address.UnknownHostException;
VAR
  ip: Address.Inet;
BEGIN
  ip := Address.GetByName("www.kame.net");
  Out.String(ip.ToString());Out.Ln
END Do;

BEGIN
  Do;
END DNSQuery.
Output:
203.178.141.194

Objeck

use System.IO.Net;

class Rosetta {
  function : Main(args : String[]) ~ Nil {
    resoloved := TCPSocket->Resolve("www.kame.net");
    each(i : resoloved) {
      resoloved[i]->PrintLine();
    };
  }
}

Output:

203.178.141.194

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);
;;

PascalABC.NET

##
var ip := System.Net.Dns.GetHostEntry('www.kame.net');
foreach var address in ip.AddressList do 
  println(address);
Output:
2001:2f0:0:8800::1:1
2001:2f0:0:8800:226:2dff:fe0b:4311
210.155.141.200

Perl

use feature 'say';
use Socket qw(getaddrinfo getnameinfo);

my ($err, @res) = getaddrinfo('orange.kame.net', 0, { protocol=>Socket::IPPROTO_TCP } );
die "getaddrinfo error: $err" if $err;

say ((getnameinfo($_->{addr}, Socket::NI_NUMERICHOST))[1]) for @res
Output:
203.178.141.194
2001:200:dff:fff1:216:3eff:feb1:44d7

Phix

Translated from C/MSDN/several man pages.
NB: may warrant further testing, see output.

without js
include builtins\cffi.e
 
constant AF_UNSPEC = 0,
--       AF_INET = 2,
--       AF_INET6 = 23,
--       SOCK_STREAM = 1,
         SOCK_DGRAM = 2,
--       IPPROTO_TCP = 6,
         NI_MAXHOST = 1025,
         NI_NUMERICHOST = iff(platform()=LINUX?1:2)
 
constant tWAD = """
typedef struct WSAData {
  WORD           wVersion;
  WORD           wHighVersion;
  char           szDescription[257];
  char           szSystemStatus[129];
  unsigned short iMaxSockets;
  unsigned short iMaxUdpDg;
  char           *lpVendorInfo;
} WSADATA, *LPWSADATA;
""",
tWAS = """
int WSAStartup(
  _In_   WORD wVersionRequested,
  _Out_  LPWSADATA lpWSAData
);
""",
tWAC = """
int WSACleanup(void);
""",
tAI_W="""
typedef struct addrinfo {
  int             ai_flags;
  int             ai_family;
  int             ai_socktype;
  int             ai_protocol;
  size_t          ai_addrlen;
  char            *ai_canonname;
  struct sockaddr  *ai_addr;
  struct addrinfo  *ai_next;
} ADDRINFOA, *PADDRINFOA;
""",
tAI_L="""
typedef struct addrinfo {
    int              ai_flags;
    int              ai_family;
    int              ai_socktype;
    int              ai_protocol;
    int              ai_addrlen;
    struct sockaddr *ai_addr;
    char            *ai_canonname;
    struct addrinfo *ai_next;
};
""",
tGAI = """
int getaddrinfo(
  _In_opt_  PCSTR pNodeName,
  _In_opt_  PCSTR pServiceName,
  _In_opt_  const ADDRINFOA *pHints,
  _Out_     PADDRINFOA *ppResult
);
""",
--int getaddrinfo(const char *node, const char *service,
--                     const struct addrinfo *hints,
--                     struct addrinfo **res);
tGNI = """
int getnameinfo(
  _In_   sockaddr *sa,
  _In_   int salen,
  _Out_  char *host,
  _In_   DWORD hostlen,
  _Out_  char *serv,
  _In_   DWORD servlen,
  _In_   int flags
);
""",
--int getnameinfo(const struct sockaddr *addr, socklen_t addrlen,
--                     char *host, socklen_t hostlen,
--                     char *serv, socklen_t servlen, int flags);
tFAI = """
void freeaddrinfo(
  _In_  struct addrinfo *ai
);
"""
--void freeaddrinfo(struct addrinfo *res);
 
integer xgetaddrinfo = NULL, xgetnameinfo, xfreeaddrinfo, idAI,
        xwsastartup, xwsacleanup, error
 
function get_name_info(string fqdn)
    if xgetaddrinfo=NULL then
        atom lib
        if platform()=WINDOWS then
            integer idWAD = define_struct(tWAD)
            atom pWAD = allocate_struct(idWAD,cleanup:=true)
            lib = open_dll("Ws2_32.dll")
            xwsastartup = define_cffi_func(lib,tWAS)
            xwsacleanup = define_cffi_func(lib,tWAC)
            error = c_func(xwsastartup,{#00020002,pWAD})
            if error then ?9/0 end if
            idAI = define_struct(tAI_W)
        elsif platform()=LINUX then
            lib = open_dll("libc.so.6")
            idAI = define_struct(tAI_L)
        end if
        xgetaddrinfo = define_cffi_func(lib,tGAI)
        xgetnameinfo = define_cffi_func(lib,tGNI)
        xfreeaddrinfo = define_cffi_proc(lib,tFAI)
    end if
    atom hints = allocate_struct(idAI,cleanup:=true), 
         res = allocate(machine_word(),cleanup:=true),
         host = allocate(NI_MAXHOST,cleanup:=true)
    set_struct_field(idAI,hints,"ai_family",AF_UNSPEC)
--  set_struct_field(idAI,hints,"ai_socktype",SOCK_STREAM)
    set_struct_field(idAI,hints,"ai_socktype",SOCK_DGRAM)
    error = c_func(xgetaddrinfo,{fqdn,NULL,hints,res})
    if error then ?9/0 end if
    res = peekNS(res,machine_word(),false)
    atom ptr = res
    sequence results = {}
    while ptr!=NULL do
        atom addr = get_struct_field(idAI,ptr,"ai_addr")
        integer len = get_struct_field(idAI,ptr,"ai_addrlen")
        error = c_func(xgetnameinfo,{addr, len, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST})
        if error then ?9/0 end if
        results = append(results,peek_string(host))
        ptr = get_struct_field(idAI,ptr,"ai_next")
    end while
    c_proc(xfreeaddrinfo,{res})
    return results
end function
 
procedure WSACleanup()
    if platform()=WINDOWS then
        error = c_func(xwsacleanup,{})
        if error then crash("WSACleanup failed: %d\n",{error}) end if
    end if
end procedure
 
?get_name_info("www.kame.net")
WSACleanup()
Output:

Note that windows nslookup shows an IPv6 that this does not, whereas the exact reverse is true for linux on a VirtualBox (same machine)...

Windows:
>nslookup www.kame.net
Addresses:  2001:200:dff:fff1:216:3eff:feb1:44d7
          203.178.141.194
>p test
{"203.178.141.194"}

Linux:
$ nslookup www.kame.net
Address: 203.178.141.194
$ ./p test
{"203.178.141.194","2001:200:dff:fff1:216:3eff:feb1:44d7"}

PHP

Works for PHP5 (Windows > 5.3.0)

<?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";
?>

PicoLisp

(make
   (in '(host "www.kame.net")
      (while (from "address ")
         (link (till "^J" T)) ) ) )

Output:

-> ("203.178.141.194" "2001:200:dff:fff1:216:3eff:feb1:44d7")

Pike

> array ips = Protocols.DNS.gethostbyname("www.kame.net")[1] || ({});
> write(ips*"\n");

Output:

203.178.141.194
2001:0200:0DFF:FFF1:0216:3EFF:FEB1:44D7

PowerShell

$DNS = Resolve-DnsName -Name www.kame.net
Write-Host "IPv4:" $DNS.IP4Address "`nIPv6:" $DNS.IP6Address

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

R

R has no built-in function to accomplish the task, but with the help of the Rcpp package, it's possible to implement this functionality.

If the following is saved as dns.cpp:

#include <Rcpp.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace Rcpp ;

// [[Rcpp::export]]
CharacterVector getNameInfo(std::string fqdn) {

  struct addrinfo hints, *res, *res0;
	int error;
	char host[NI_MAXHOST];

  memset(&hints, 0, sizeof hints);
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;

	error = getaddrinfo(fqdn.c_str(), NULL, &hints, &res0);
	if (error) { return(NA_STRING);	}

  int i = 0 ;
	for (res = res0; res; res = res->ai_next) {
  	error = getnameinfo(res->ai_addr, res->ai_addrlen,
		    host, sizeof host, NULL, 0, NI_NUMERICHOST);
		if (!error) { i++ ; }
	}

  CharacterVector results(i) ;

  i = 0;

  for (res = res0; res; res = res->ai_next) {
		error = getnameinfo(res->ai_addr, res->ai_addrlen,
		    host, sizeof host, NULL, 0, NI_NUMERICHOST);
		if (!error) { results[i++] = host ; }
	}

  freeaddrinfo(res0);

  return(results) ;

}

It can be used to perform the task in R:

library(Rcpp)
sourceCpp("dns.cpp")
getNameInfo("www.kame.net")
## [1] "203.178.141.194"                     
## [2] "2001:200:dff:fff1:216:3eff:feb1:44d7"

Racket

The following finds an IPv4 address. Currently, the API does not support returning an IPv6 address.

#lang racket

(require net/dns)
(dns-get-address "8.8.8.8" "www.kame.net")

Raku

(formerly Perl 6)

Works with: Rakudo version 2017.01
use Net::DNS;

my $resolver = Net::DNS.new('8.8.8.8');

my $ip4 = $resolver.lookup('A',    'orange.kame.net');
my $ip6 = $resolver.lookup('AAAA', 'orange.kame.net');

say $ip4[0].octets.join: '.';
say $ip6[0].octets.».fmt("%.2X").join.comb(4).join: ':';
Output:
203.178.141.194
2001:0200:0dff:fff1:0216:3eff:feb1:44d7

REXX

This REXX version uses the Windows (DOS)   PING   command to resolve the domain name.

Execution note:   if the information for     PING   -6   ···     is blank, you may need to install   (on some
Microsoft Windows systems)   the IPV6 interface using the command:     IPV6   install

/*REXX program displays  IPV4 and IPV6  addresses for a supplied  domain name.*/
parse arg tar .                        /*obtain optional domain name from C.L.*/
if tar==''  then tar= 'www.kame.net'   /*Not specified?  Then use the default.*/
tFID    = '\TEMP\DNSQUERY.$$$'         /*define temp file to store IPV4 output*/
pingOpts= '-l 0    -n 1    -w 0'   tar /*define options for the PING command. */
trace off                              /*don't show PING none─zero return code*/
                                       /* [↓]  perform 2 versions of PING cmd.*/
  do j=4  to 6  by 2                   /*handle  IPV4  and  IPV6  addresses.  */
  'PING'  (-j)  pingOpts  ">"   tFID   /*restrict PING's output to a minimum. */
  q=charin(tFID, 1, 999)               /*read the output file from  PING  cmd.*/
  parse var  q   '['   ipaddr    "]"   /*parse  IP  address from the output.  */
  say 'IPV'j "for domain name  "  tar  '  is  '  ipaddr        /*IPVx address.*/
  call lineout tFID                    /* ◄──┬─◄  needed by some REXXes to    */
  end   /*j*/                          /*    └─◄  force (TEMP) file integrity.*/
                                       /*stick a fork in it,  we're all done. */
'ERASE'  tFID                          /*clean up (delete) the temporary file.*/

output   using the default input:

IPV4 for domain name   www.kame.net   is   203.178.141.194
IPV6 for domain name   www.kame.net   is   2001:200:dff:fff1:216:3eff:feb1:44d7

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"]

Rust

use std::net::ToSocketAddrs;

fn main() {
    let host = "www.kame.net";
    // Ideally, we would want to use std::net::lookup_host to resolve the host ips,
    // but at time of writing this, it is still unstable. Fortunately, we can
    // still resolve using the ToSocketAddrs trait, but we need to add a port,
    // so we use the dummy port 0.
    let host_port = (host, 0);
    let ip_iter = host_port.to_socket_addrs().unwrap();


    for ip_port in ip_iter {
        println!("{}", ip_port.ip());
    }
}

Output:

203.178.141.194
2001:200:dff:fff1:216:3eff:feb1:44d7

Scala

Library: Scala
import java.net._

InetAddress.getAllByName("www.kame.net").foreach(x => println(x.getHostAddress))

Scheme

Works with: Guile
; 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)

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.

$ include "seed7_05.s7i";
  include "socket.s7i";

const proc: main is func
  begin
    writeln(numericAddress(inetSocketAddress("www.kame.net", 1024)));
  end func;

Output:

203.178.141.194

Sidef

var (err, *res) = Socket.getaddrinfo(
        'www.kame.net', 0,
        Hash.new(protocol => Socket.IPPROTO_TCP)
);
err && die err;
res.each { |z|
    say [Socket.getnameinfo(z{:addr}, Socket.NI_NUMERICHOST)][1];
}
Output:
203.178.141.194
2001:200:dff:fff1:216:3eff:feb1:44d7

Standard ML

The basis library provides IPv4 support only:

- Option.map (NetHostDB.toString o NetHostDB.addr) (NetHostDB.getByName "www.kame.net");
val it = SOME "203.178.141.194": string option

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.

Library: Tcllib (Package: dns)
Library: udp
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]"

Output:

primary addresses of www.kame.net are:
	IPv4» 203.178.141.194
	IPv6» 2001:200:dff:fff1:216:3eff:feb1:44d7

TXR

At the listener prompt:

This is the TXR Lisp interactive listener of TXR 283.
Quit with :quit or Ctrl-D on an empty line. Ctrl-X ? for cheatsheet.
TXR's no-spray organic production means every bug is carefully removed by hand.
1> (flow (getaddrinfo "www.kame.net") (mapcar .(str-addr)) uniq)
("210.155.141.200" "2001:2f0:0:8800::1:1" "2001:2f0:0:8800:226:2dff:fe0b:4311")

UNIX Shell

Using dig

Aamrun ~ % dig www.kame.net A www.kame.net AAAA +short
mango.itojun.org.
210.155.141.200
mango.itojun.org.
2001:2f0:0:8800:226:2dff:fe0b:4311
2001:2f0:0:8800::1:1
Aamrun ~ %

Using nslookup

Aamrun ~ % nslookup
> set q=AAAA
> www.kame.net
Server:		192.168.1.1
Address:	192.168.1.1#53

Non-authoritative answer:
www.kame.net	canonical name = mango.itojun.org.
mango.itojun.org	has AAAA address 2001:2f0:0:8800:226:2dff:fe0b:4311
mango.itojun.org	has AAAA address 2001:2f0:0:8800::1:1

Authoritative answers can be found from:
> set q=A
> www.kame.net
Server:		192.168.1.1
Address:	192.168.1.1#53

Non-authoritative answer:
www.kame.net	canonical name = mango.itojun.org.
Name:	mango.itojun.org
Address: 210.155.141.200
> exit

Aamrun ~ %

VBScript

Function dns_query(url,ver)
	Set r = New RegExp
	r.Pattern = "Pinging.+?\[(.+?)\].+"
	Set objshell = CreateObject("WScript.Shell")
	Set objexec = objshell.Exec("%comspec% /c " & "ping -" & ver & " " & url)
	WScript.StdOut.WriteLine "URL: " & url
	Do Until objexec.StdOut.AtEndOfStream
		line = objexec.StdOut.ReadLine
		If r.Test(line) Then
			WScript.StdOut.WriteLine "IP Version " &_
				ver & ": " & r.Replace(line,"$1")
		End If
	Loop
End Function

Call dns_query(WScript.Arguments(0),WScript.Arguments(1))
Output:
F:\>cscript /nologo dns_query.vbs www.kame.net 4
URL: www.kame.net
IP Version 4: 203.178.141.194

F:\>cscript /nologo dns_query.vbs www.kame.net 6
URL: www.kame.net
IP Version 6: 2001:200:dff:fff1:216:3eff:feb1:44d7

V (Vlang)

Translation of: Kotlin
import net

fn main() {
	addr := 'www.kame.net:80'
	@type := net.SocketType.tcp
	family := net.AddrFamily.unspec
	mut addrs := []net.Addr{}
	mut results :=''

	addrs = net.resolve_addrs(addr, family, @type) or {println('Error: nothing resolved') exit(1)}
	for each in addrs {
		results += '${addr.split(':')[0]} * ${each} * ${each.family()} * ${@type} \n'
	}
	println(results)

}
Output:
www.kame.net * 210.155.141.200:80 * ip * tcp 
www.kame.net * [2001:2f0:0:8800:226:2dff:fe0b:4311]:80 * ip6 * tcp 
www.kame.net * [2001:2f0:0:8800::1:1]:80 * ip6 * tcp

Wren

Wren CLI doesn't currently expose a way to make a DNS query.

However, if Wren is embedded in (say) a suitable Go program, then we can ask the latter to do it for us.

/* DNS_query.wren */

class Net {
    foreign static lookupHost(host)
}

var host = "orange.kame.net"
var addrs = Net.lookupHost(host).split(", ")
System.print(addrs.join("\n"))

which we embed in the following Go program and run it:

Library: WrenGo
/* go run DNS_query.go */

package main

import(
    wren "github.com/crazyinfin8/WrenGo"
    "net"
    "strings"
)

type any = interface{}

func lookupHost(vm *wren.VM, parameters []any) (any, error) {
    host := parameters[1].(string)
    addrs, err := net.LookupHost(host)
    if err != nil {
        return nil, nil
    }
    return strings.Join(addrs, ", "), nil 
}

func main() {
    vm := wren.NewVM()
    fileName := "DNS_query.wren"
    methodMap := wren.MethodMap{"static lookupHost(_)": lookupHost}
    classMap := wren.ClassMap{"Net": wren.NewClass(nil, nil, methodMap)}
    module := wren.NewModule(classMap)
    vm.SetModule(fileName, module)
    vm.InterpretFile(fileName)
    vm.Free()
}
Output:
2001:200:dff:fff1:216:3eff:feb1:44d7
203.178.141.194

zkl

The addrInfo method is just a front end to POSIX getaddrinfo.

zkl: Network.TCPClientSocket.addrInfo("www.kame.net")
L("orange.kame.net",L("203.178.141.194","2001:200:dff:fff1:216:3eff:feb1:44d7"))
Cookies help us deliver our services. By using our services, you agree to our use of cookies.