#include "cdevAddr.h"

// *****************************************************************************
// * cdevInetAddr::set :
// *	Allows the caller to set the address using a port number and 
// *	internet address.
// *****************************************************************************
int cdevInetAddr::set (unsigned short portnum, long ip_addr)
	{
	setType(AF_INET);
	setSize(sizeof(inet_addr));
	inet_addr.sin_family = AF_INET;
	inet_addr.sin_port   = htons(portnum);

	if(ip_addr == INADDR_ANY) inet_addr.sin_addr.s_addr=INADDR_ANY;
	else memcpy((void *)&inet_addr.sin_addr, 
	            (void *)&ip_addr, 
	            sizeof(inet_addr.sin_addr));
	return 0;
	}


// *****************************************************************************
// * cdevInetAddr::set :
// *	Allows the caller to set the address using a port number and host name.
// *****************************************************************************
int cdevInetAddr::set (unsigned short portnum, const char hostname[])
	{
	hostent * server_info;
	long      addr;
	int       retval;

	setType(AF_INET);
	setSize(sizeof(inet_addr));
	memset((void *)&inet_addr, 0, sizeof(inet_addr));

	if(hostname==NULL || *hostname==0)
		{
		errno  = EINVAL;
		retval = -1;
		}
	else if((addr=::inet_addr(hostname))!=-1 ||
	        ::strcmp(hostname, "255.255.255.255")==0)
		{
		retval = set(portnum, addr);
		}
	else if((server_info=::gethostbyname(hostname)) != 0)
		{
		::memcpy((void *)&addr, (void *)server_info->h_addr, server_info->h_length);
		retval = set(portnum, addr);
		}
	else retval = -1;
	
	return retval;
	}
	

// *****************************************************************************
// * cdevInetAddr::set :
// *	Allows the caller to set the address using a sockaddr_in structure
// *	and its length.
// *****************************************************************************
int cdevInetAddr::set (const sockaddr_in *addr, int len)
	{
	setType(AF_INET);
	setSize(len);
	memcpy((void *)&inet_addr, (void *)addr, len);
	return 0;
	}


// *****************************************************************************
// * cdevInetAddr::cdevInetAddr :
// *	This constructor creates an empty address object.
// *****************************************************************************
cdevInetAddr::cdevInetAddr ( void )
	: cdevAddr(AF_INET, sizeof(sockaddr_in))
	{
	::memset((void *)&inet_addr, 0, sizeof(inet_addr));
	}
	

// *****************************************************************************
// * cdevInetAddr::cdevInetAddr :
// *	This constructor copies the contents of one cdevInetAddr object to
// *	the new cdevInetAddr object.
// *****************************************************************************
cdevInetAddr::cdevInetAddr ( const cdevInetAddr & addr )
	: cdevAddr(AF_INET, sizeof(inet_addr))
	{
	memcpy((void *)&inet_addr, (void *)&addr.inet_addr, sizeof(inet_addr));	
	}
	

// *****************************************************************************
// * cdevInetAddr::cdevInetAddr :
// *	This constructor creates a new cdevInetAddr object that contains the
// *	address provided in the sockaddr_in object.
// *****************************************************************************
cdevInetAddr::cdevInetAddr (const sockaddr_in *addr, int len)
	{
	set(addr, len);
	}
	

// *****************************************************************************
// * cdevInetAddr::cdevInetAddr :
// *	This constructor initializes the new cdevInetAddr object using the
// *	specified port number and host name.
// *****************************************************************************
cdevInetAddr::cdevInetAddr (unsigned short portnum, char hostname[])
	{
	set(portnum, hostname);
	}


// *****************************************************************************
// * cdevInetAddr::cdevInetAddr :
// *	This constructor initializes the new cdevInetAddr object with the 
// *	specified port number and ip address.
// *****************************************************************************
cdevInetAddr::cdevInetAddr (unsigned short portnum, long ip_addr)
	{
	set(portnum, ip_addr);
	}
	
	
// *****************************************************************************
// * cdevInetAddr::getHostName :
// *	This method allows the caller to return the name of the host that 
// *	the cdevInetAddr structure identifies.
// *****************************************************************************
const char *   cdevInetAddr::getHostName ( void ) const
	{
	char    * retval;
	hostent * hp;
	int       len = sizeof(inet_addr.sin_addr.s_addr);

	if((hp = ::gethostbyaddr((char *)&inet_addr.sin_addr, len, addr_type))==0)
		{
		retval = NULL;
		}
	else retval = hp->h_name;
	
	return retval;
	}


// *****************************************************************************
// * cdevInetAddr::getHostAddr :
// *	This method allows the caller to retrieve the internet address (in
// *	string format) of the host that the cdevInetAddr object identifies.
// *****************************************************************************
const char *   cdevInetAddr::getHostAddr ( void ) const
	{
	return ::inet_ntoa(inet_addr.sin_addr);
	}


// *****************************************************************************
// * cdevInetAddr::getInetAddr :
// *	This method allows the caller to obtain the internet address of the
// *	host that the cdevInetAddr object identifies.
// *****************************************************************************
unsigned long  cdevInetAddr::getInetAddr ( void ) const
	{
	return ntohl((unsigned long)inet_addr.sin_addr.s_addr);
	}


// *****************************************************************************
// * cdevInetAddr::getPortNum  :
// *	This method allows the caller to retrieve the port number that is 
// *	associated with this cdevInetAddr.
// *****************************************************************************
unsigned short cdevInetAddr::getPortNum  ( void ) const
	{
	return ntohs (inet_addr.sin_port);
	}


// *****************************************************************************
// * cdevInetAddr::getAddress :
// *	Returns the address of the sockaddr_in structure.
// *****************************************************************************
void * cdevInetAddr::getAddress ( void ) const
	{
	return (void *)&inet_addr;
	}

