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.




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