Tuesday, April 26, 2011

Socket Programming in C (2): IP address/Hostname Translation

****************************************************************************
//Convert IP addresses from a dots-and-number string to a struct in_addr and back
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

(1) Old way, not support IPv6

char *inet_ntoa(struct in_addr in); // convert binary in network to string
int inet_aton(const char *cp, struct in_addr *inp); // convert dot-number string cp to struct in_addr pointer inp
in_addr_t inet_addr(const char *cp); // convert do-number string cp to in_addr_t

// ntoa: network to ASCII (readable)
// aton: ASCII to network
// atoi: ASCII to integer

(2) Use inet_pton() or inet_ntop(), support for IPv6 
#include <arpa/inet.h>
 

int inet_pton(int af, const char *src, void *dst); // convert string src to network dst. if af is AF_INET(IPv4), dst must be struct addr_in* type.
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); //convert network src to string dst. if af is AF_INET, src pints to a struct addr_in, and dst must be at least INET_ADDRSTRLEN bytes long

*******************************************************************************
//Convert IP addresses from host name string to a struct in_addr and back

#include <netdb.h>
#include <sys/socket.h>       /* for AF_INET */
struct hostent *gethostbyname(const char *name); // convert hostname/dotIP to a host struture, which includes network addr_in
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); // convert a network addr_in to host structure
struct hostent {
               char  *h_name;            /* full host name*/
               char **h_aliases;         /* alias list */
               int    h_addrtype;        /* host address type */
               int    h_length;           /* length of address */
               char **h_addr_list;      /* list of addresses, often use (struct addr_in*) h_addr */
}
#define h_addr h_addr_list[0]  /* often use this one, need cast to struct addr_in*  */

*******************************************************************************
Example:
/*
 * Converts ascii text to in_addr struct.
 * NULL is returned if the address can not be found.
 * */
struct in_addr *atoaddr(char *address)
{
  struct hostent *host;
  static struct in_addr saddr;

  /* First try it as aaa.bbb.ccc.ddd. */
  saddr.s_addr = inet_addr(address);
  if (saddr.s_addr != -1)
    return &saddr;

  host = gethostbyname(address);
  if (host != NULL)
    return (struct in_addr *) *host->h_addr_list;

  return NULL;
}

No comments: