The gethostbyname function

Description

The gethostbyname function returns information about a host identified by name. The host information is returned in a structure of type hostent. This structure is allocated by the WinSock2 library, and your program should not attempt to modify or de-allocate, the structure or any of its components.

Only one copy of the hostent structure is allocated per calling thread, and since Irie Pascal programs only have one thread, there will be only one copy of this structure allocated for your program. As a result, you should copy any host information you need from the structure before calling any other Windows Sockets functions.

Declaration

The system include file WinSock2.inc contains the following declaration for the hostent and p_hostent types and the gethostbyname function:

 hostent = packed record
  h_name : address;
  h_aliases : address;
  h_addrtype : shortint;
  h_length : shortint;
  h_addr_list : address;
 end;

 p_hostent = ^hostent;

 function gethostbyname(name : address) : p_hostent;
  external dll='ws2_32.dll';

Arguments

The First Argument

The first, and only, argument passed to the gethostbyname function is the operating system address of the buffer containing the name of the host you want to get information about. The type of this argument is the built-in type address, so you must use the built-in function addr to get the operating system address of the buffer. The host name contained in the buffer must be a null-terminated string (i.e. a cstring).

The buffer pointed to by this argument must contain a valid host name and not an address. If you have the address (as a null-terminated string) of a host instead of the name of the host, and you want to get information about that host then you should do the following:

  1. Use the inet_addr function to convert the address, represented as a string into an actual address (in numeric format).
  2. Use the gethostbyaddr function to get the host information.

Return Values

The gethostbyname function returns a pointer to the hostent structure that contains the host information, if the call is successful. If the call fails then the value nil is returned, and in this case you can use the WSAGetLastError function to retrieve a code that identifies the error that caused the call to fail.

Example

The following procedure was taken from one of the sample programs distributed with Irie Pascal and shows one way to use the gethostbyname function.

 //PURPOSE: Given the name of a host performs a DNS lookup
 //PARAMETER(s):
 //    1. sName - contains the name of the host
 procedure DNSLookUp(strName : string);
 var
  pHostEnt : p_hostent;
  cstrName : cstring;
 begin
  //Convert the name to a cstring since 'gethostbyname' expects a cstring
  cstrName := strName;
  pHostEnt := gethostbyname(addr(cstrName));
  if pHostEnt = nil then
   writeln('Can not find host ''', cstrName, '''')
  else
   DisplayHostEntInfo(pHostEnt);
 end;

The procedure DisplayHostEntInfo is defined by the sample program and displays the host information stored in the hostent structure. The procedure DisplayHostEntInfo is below and shows one way to access the host information.

 //PURPOSE: Displays the information that was obtained from a DNS or Reverse DNS lookup
 //PARAMETER(s):
 //    1. pHostEnt - a pointer to the sockets API hostent structure that contains
 //       the result of the lookup.
 //NOTES:
 //    This procedure uses the Windows API functions 'lstrlen' and 'lstrcpy' to
 //manipulate strings in C format (i.e. null-terminated arrays of char). These
 //functions are used because the strings in the hostent structure are in C format.
 //Since these functions are not described in the online help (because they are
 //Windows API functions not Irie Pascal functions) a brief description is given
 //below for persons not already familiar with these functions:
 // 'lstrlen' returns the length of the string (not counting the null terminator).
 // 'lstrcpy' copies the string pointed to by its second argument into the memory
 //   pointed to by its first argument (the null terminator is also copied).
 procedure DisplayHostEntInfo(pHostEnt : p_hostent);
 const
  MAX_ASCII_ADDRESS = 15;
 var
  AddrTemp, AddrAddr, AddrRet : address;
  iRet : integer;
  strAddress : cstring[MAX_ASCII_ADDRESS];
  strName : cstring;

  //PURPOSE: Returns the address pointed to be another address.
  //PARAMETER(s):
  //    1. a - an address pointing to another address
  //RETURNS:
  //    The address pointed to by the parameter 'a'.
  //NOTES:
  //Irie Pascal pointer variables contain virtual addresses that are only
  //meaningful to the Irie Pascal Run Time Engine. However when using the
  //Windows API you occassionally need to manipulate non-virtual addresses.
  //To make this easier Irie Pascal supports a new type called 'address'.
  //However you can't use ^ to dereference an address, because addresses
  //are like untyped pointers (i.e. the compiler does not know the type of
  //the value pointed to by the address, so it can not generate code to return
  //the value pointed to be the address). The address type is assignment
  //compatible with all pointer types and vice/versa, so the solution to this
  //problem is to assign the address to suitable pointer variable and then
  //dereference the pointer variable.
  //In the case of the function below the address is known to be pointing
  // to another address. So the address to be deferenced is assigned to
  // a pointer to an address, and then this pointer is dereferenced.
  function DereferenceAddress(a : address) : address;
  var
   p : ^address;
  begin
   p := a;
   DereferenceAddress := p^;
  end;

 begin (* DisplayHostEntInfo *)
  //pHostEnt^.h_name is the address of a null-terminated string containing
  //the name of the host.
  writeln('NAME:');
  if pHostEnt^.h_name=NULL then
   writeln('NOT FOUND')
  else if (lstrlen(pHostEnt^.h_name)+1) > sizeof(strName) then
   writeln('TOO LONG')
  else
   begin
    iRet := lstrcpy(addr(strName), pHostEnt^.h_name);
    writeln(strName);
   end;
  writeln;

  //pHostEnt^.h_aliases is the address of a null terminated array of addresses
  //of null-terminated strings containing alternative names for the host.
  writeln('ALIASES:');
  AddrAddr := pHostEnt^.h_aliases;
  if AddrAddr = NULL then
   writeln('None')
  else
   begin
    AddrTemp := DereferenceAddress(AddrAddr);
    while AddrTemp <> NULL do
     begin
      if lstrlen(AddrTemp) > 0 then
       begin
        if (lstrlen(addrTemp)+1) > sizeof(strName) then
         writeln('TOO LONG')
        else
         begin
          iRet := lstrcpy(addr(strName), AddrTemp);
          writeln(strName);
         end;
       end
      else
       writeln('EMPTY');

      AddrAddr := AddrAddr + sizeof(address);
      AddrTemp := DereferenceAddress(AddrAddr);
     end;
   end;
  writeln;

  if pHostEnt^.h_addrtype <> AF_INET then
   writeln('Invalid address type')
  else if pHostEnt^.h_length <> sizeof(address) then
   writeln('Invalid address length')
  else
   begin
    //pHostEnt^.h_addr_list is the address of a null terminated array of
    //addresses of IP addresses of the host.
    writeln('ADDRESSES:');
    AddrAddr := pHostEnt^.h_addr_list;
    if AddrAddr = NULL then
     writeln('None')
    else
     begin
      //Get the first element of the array
      AddrTemp := DereferenceAddress(AddrAddr);
      while AddrTemp <> NULL do
       begin
        //Dereference the current array element to get the
        //IP address.
        AddrTemp := DereferenceAddress(AddrTemp);
        //Convert the IP address from binary format to a human
        //readable format (like nnnn.nnnn.nnnn.nnn)
        AddrRet := inet_ntoa(AddrTemp);
        if (AddrRet=null) or ((lstrlen(AddrRet)+1)>sizeof(strAddress)) then
         writeln('[ERROR]')
        else
         begin
          iRet := lstrcpy(addr(strAddress), AddrRet);
          writeln(strAddress);
         end;

        AddrAddr := AddrAddr + sizeof(address);
        //Get the next element of the array
        AddrTemp := DereferenceAddress(AddrAddr);
       end;
     end;
    writeln;
   end;
 end; (* DisplayHostEntInfo *)

Reference Information

The authoritative source of information about the WinSock2 library is the Microsoft Developers Network (MSDN). You can access the MSDN on the Microsoft website at msdn.microsoft.com.