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 it's 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:
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 it's second argument into the memory
// pointed to by it's 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.