/*
 * netdb.h
 */


#ifndef netdb_h
#define netdb_h


#include<inttypes.h>
#include<sys/socket.h>


enum{
	AI_PASSIVE=    1<<0,	/* Socket address is intended for bind(). */
	AI_CANONNAME=  1<<1,	/* Request for canonical name. */
	AI_NUMERICHOST=1<<2,	/* Return numeric host address as name. */
	AI_NUMERICSERV=1<<3,	/* Inhibit service name resolution. */
	AI_V4MAPPED=   1<<4,	/* If no IPv6 addresses are found, query for IPv4 addresses. */
	AI_ALL=        1<<5,	/* Query for both IPv4 and IPv6 addresses. */
	AI_ADDRCONFIG= 1<<6,
	AI_MASK=       (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST | AI_ADDRCONFIG),

	EAI_ADDRFAMILY=1,
    EAI_AGAIN,			/* The name could not be resolved at this time. Future attempts may succeed. */
    EAI_BADFLAGS,		/* The flags had an invalid value. */
    EAI_FAIL,			/* A non-recoverable error occurred. */
    EAI_FAMILY,			/* The address family was not recognized or the address length was invalid for the specified family. */
    EAI_MEMORY,			/* There was a memory allocation failure. */
	EAI_NODATA,
    EAI_NONAME,			/* The name does not resolve for the supplied parameters. */
    EAI_SERVICE,		/* The service passed was not recognized for the specified socket type. */
    EAI_SOCKTYPE,		/* The intended socket type was not recognized. */
    EAI_SYSTEM,			/* A system error occurred. The error code can be found in /errno/. */
    EAI_OVERFLOW,		/* An argument buffer overflowed. */
    EAI_MAX,
    EAI_RESNULL,
    EAI_BADHINTS,

	/* for use as error values for gethostbyaddr() and gethostbyname(). */
	HOST_NOT_FOUND=1,	/* No such host is known. */
	NO_DATA,			/* The server recognized the request and the name, but no address is available. */
	NO_RECOVERY,		/* An unexpected server failure occurred which cannot be recovered. */
	TRY_AGAIN,			/* A temporary and possibly transient error occurred, such as a failure of a server to respond. */
	
	/*
	 * Error return codes from gethostbyname() and gethostbyaddr()
	 * (left in extern int h_errno).
	 */
	NETDB_INTERNAL=	-1,	/* see errno */
	NETDB_SUCCESS=	0,	/* no problem */
};


#define	_PATH_HOSTS	"/etc/hosts"


struct hostent{
	char   *h_name;			/* Official name of the host. */
	char  **h_aliases;		/* A pointer to an array of pointers to alternative host names. */
	int     h_addrtype;		/* Address type. */
	int     h_length;		/* The length, in bytes, of the address. */
	char  **h_addr_list;	/* A pointer to an array of pointers to network addresses (in network byte order) for the host. */
#define	h_addr h_addr_list[0]
};

struct netent{
	char     *n_name;		/* Official, fully-qualified (including the domain) name of the host. */
	char    **n_aliases;	/* A pointer to an array of pointers to alternative network names. */
	int       n_addrtype;	/* The address type of the network. */
	uint32_t  n_net;		/* The network number, in host byte order. */
};

struct protoent{
	char   *p_name;		/* Official name of the protocol. */
	char  **p_aliases;	/* A pointer to an array of pointers to alternative protocol names. */
	int     p_proto;	/* The protocol number. */
};

struct servent{
	char   *s_name;		/* Official name of the service. */
	char  **s_aliases;	/* A pointer to an array of pointers to alternative service names. */
	int     s_port;		/* The port number at which the service resides, in network byte order. */
	char   *s_proto;	/* The name of the protocol to use when contacting the service. */
};

struct addrinfo{
	int               ai_flags;		/* Input flags. */
	int               ai_family;	/* Address family of socket. */
	int               ai_socktype;	/* Socket type. */
	int               ai_protocol;	/* Protocol of socket. */
	int         ai_addrlen;	/* Length of socket address. */
	struct sockaddr  *ai_addr;		/* Socket address of socket. */
	char             *ai_canonname;	/* Canonical name of service location. */
	struct addrinfo  *ai_next;		/* Pointer to next in list. */
};

extern int h_errno;

struct hostent  *gethostbyname(const char *);

void             endhostent(void);
void             endnetent(void);
void             endprotoent(void);
void             endservent(void);
void             freeaddrinfo(struct addrinfo *);
const char      *gai_strerror(int);
int              getaddrinfo(const char *, const char *,const struct addrinfo *,struct addrinfo **);
struct hostent	*gethostbyaddr(const char *, int, int);
struct hostent  *gethostent(void);
int              getnameinfo(const struct sockaddr *, int,char *, int, char *,int, unsigned);
struct netent   *getnetbyaddr(uint32_t, int);
struct netent   *getnetbyname(const char *);
struct netent   *getnetent(void);
struct protoent *getprotobyname(const char *);
struct protoent *getprotobynumber(int);
struct protoent *getprotoent(void);
struct servent  *getservbyname(const char *, const char *);
struct servent  *getservbyport(int, const char *);
struct servent  *getservent(void);
void             sethostent(int);
void             setnetent(int);
void             setprotoent(int);
void             setservent(int);
void             _map_v4v6_address(const char *src, char *dst);
void             _map_v4v6_hostent(struct hostent *hp, char **bp, int *len);

struct hostent	*gethostbyname (const char *);
struct hostent	*gethostbyname2 (const char *, int);
struct hostent	*gethostent (void);
struct netent	*getnetbyname (const char *);
struct netent	*getnetent (void);
struct protoent	*getprotobyname (const char *);
struct protoent	*getprotobynumber (int);
struct protoent	*getprotoent (void);
struct servent	*getservbyname (const char *, const char *);
struct servent	*getservbyport (int, const char *);
struct servent	*getservent (void);

struct hostent * _gethostbyhtname  (const char *, int);
struct hostent * _gethostbydnsname (const char *, int);
struct hostent * _gethostbynisname (const char *, int);
struct hostent * _gethostbyhtaddr  (const char *, int, int);
struct hostent * _gethostbydnsaddr (const char *, int, int);
struct hostent * _gethostbynisaddr (const char *, int, int);
struct netent *  _getnetbyhtname  (const char *);
struct netent *  _getnetbydnsname (const char *);
struct netent *  _getnetbynisname (const char *);
struct netent *  _getnetbyhtaddr  (unsigned long, int);
struct netent *  _getnetbydnsaddr (unsigned long, int);
struct netent *  _getnetbynisaddr (unsigned long, int);

void	_sethosthtent (int);
void	_endhosthtent (void);
void	_sethostdnsent (int);
void	_endhostdnsent (void);
void	_setnethtent (int);
void	_endnethtent (void);
void	_setnetdnsent (int);
void	_endnetdnsent (void);

void herror();
const char	*hstrerror(int);


#endif
