We need better network address conv helpers.
This is what our applets want:

          sockaddr -> hostname
udhcp:    hostname -> ipv4 addr
nslookup: hostname -> list of names - done
tftp:     host,port -> sockaddr
nc:       host,port -> sockaddr
inetd: ?
traceroute: ?, hostname -> ipv4 addr
arping    hostname -> ipv4 addr
ping6     hostname -> ipv6 addr
ifconfig  hostname -> ipv4 addr (FIXME error check?)
ipcalc    ipv4 addr -> hostname
syslogd   hostname -> sockaddr
inet_common.c: buggy. hostname -> ipv4 addr
mount     hostname -> sockaddr_in

==================
HOWTO get rid of inet_ntoa/aton:

foo.sin_addr.s_addr = inet_addr(cp);
-
inet_pton(AF_INET, cp, &foo.sin_addr);

inet_aton(cp, &foo.sin_addr);
-
inet_pton(AF_INET, cp, &foo.sin_addr);

ptr = inet_ntoa(foo.sin_addr);
-
char str[INET_ADDRSTRLEN];
ptr = inet_ntop(AF_INET, &foo.sin_addr, str, sizeof(str));

===================

       struct addrinfo {
           int     ai_flags;
           int     ai_family;
           int     ai_socktype;
           int     ai_protocol;
           size_t  ai_addrlen;
           struct sockaddr *ai_addr;
           char   *ai_canonname;
           struct addrinfo *ai_next;
       };
       int getaddrinfo(const char *node, const char *service,
                       const struct addrinfo *hints,
                       struct addrinfo **res);

       void freeaddrinfo(struct addrinfo *res);

       const char *gai_strerror(int errcode);

       The members ai_family, ai_socktype, and ai_protocol have the same  meaning
       as  the corresponding parameters in the socket(2) system call.  The getad-
       drinfo(3) function returns socket addresses in either IPv4 or IPv6 address
       family, (ai_family will be set to either AF_INET or AF_INET6).

       The  hints  parameter specifies the preferred socket type, or protocol.  A
       NULL hints specifies that any network address or protocol  is  acceptable.
       If  this  parameter  is  not NULL it points to an addrinfo structure whose
       ai_family, ai_socktype, and  ai_protocol  members  specify  the  preferred
       socket type.  AF_UNSPEC in ai_family specifies any protocol family (either
       IPv4 or IPv6, for example).  0 in  ai_socktype  or  ai_protocol  specifies
       that any socket type or protocol is acceptable as well.  The ai_flags mem-
       ber specifies additional options, defined below.  Multiple flags are spec-
       ified  by  logically  OR-ing  them together.  All the other members in the
       hints parameter must contain either 0, or a null pointer.

       The node or service parameter, but not both, may be NULL.  node  specifies
       either  a  numerical network address (dotted-decimal format for IPv4, hex-
       adecimal format for IPv6) or a network hostname, whose  network  addresses
       are looked up and resolved.  If hints.ai_flags contains the AI_NUMERICHOST
       flag then the node parameter must be a  numerical  network  address.   The
       AI_NUMERICHOST  flag  suppresses  any  potentially  lengthy  network  host
       address lookups.

       The getaddrinfo(3) function creates a linked list of addrinfo  structures,
       one  for  each  network address subject to any restrictions imposed by the
       hints parameter.  The ai_canonname field of the first  of  these  addrinfo
       structures  is  set  to  point  to  the  official  name  of  the  host, if
       hints.ai_flags includes the AI_CANONNAME  flag.   ai_family,  ai_socktype,
       and  ai_protocol specify the socket creation parameters.  A pointer to the
       socket address is placed in the ai_addr member,  and  the  length  of  the
       socket address, in bytes, is placed in the ai_addrlen member.

       If  node is NULL, the network address in each socket structure is initial-
       ized according to the AI_PASSIVE flag, which  is  set  in  hints.ai_flags.
       The  network  address in each socket structure will be left unspecified if
       AI_PASSIVE flag is set.  This is used by server applications, which intend
       to  accept client connections on any network address.  The network address
       will be set to the loopback interface address if the  AI_PASSIVE  flag  is
       not  set.  This is used by client applications, which intend to connect to
       a server running on the same network host.

       If hints.ai_flags includes the AI_ADDRCONFIG flag, then IPv4 addresses are
       returned  in the list pointed to by result only if the local system has at
       least has at least one IPv4 address configured,  and  IPv6  addresses  are
       only  returned  if  the local system has at least one IPv6 address config-
       ured.

       If hint.ai_flags specifies the AI_V4MAPPED flag, and  hints.ai_family  was
       specified as AF_INET6, and no matching IPv6 addresses could be found, then
       return IPv4-mapped IPv6 addresses in the list pointed to  by  result.   If
       both  AI_V4MAPPED and AI_ALL are specified in hints.ai_family, then return
       both IPv6 and IPv4-mapped IPv6 addresses in the list pointed to by result.
       AI_ALL is ignored if AI_V4MAPPED is not also specified.

       service  sets the port number in the network address of each socket struc-
       ture.  If service is NULL the port number will be left uninitialized.   If
       AI_NUMERICSERV  is  specified  in  hints.ai_flags and service is not NULL,
       then service must point to a string  containing  a  numeric  port  number.
       This  flag  is used to inhibit the invocation of a name resolution service
       in cases where it is known not to be required.


==============

       int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                       char *host, size_t hostlen,
                       char *serv, size_t servlen, int flags);

       The  getnameinfo(3)  function is defined for protocol-independent
       address-to-nodename translation.  It combines the functionality
       of gethostbyaddr(3) and getservbyport(3) and is the inverse of
       getaddrinfo(3).  The sa argument is a pointer to a generic socket address
       structure (of type sockaddr_in or  sockaddr_in6)  of  size  salen  that
       holds  the  input IP address and port number.  The arguments host and
       serv are pointers to buffers (of size hostlen and servlen respectively)
       to hold the return values.

       The caller can specify that no hostname (or no service name) is required
       by providing a NULL host (or serv) argument or a zero hostlen (or servlen)
       parameter. However, at least one of hostname or service name must be requested.

       The flags argument modifies the behaviour of getnameinfo(3) as follows:

       NI_NOFQDN
              If set, return only the hostname part of the FQDN for local hosts.

       NI_NUMERICHOST
              If set, then the numeric form of the hostname is returned.
              (When not set, this will still happen in case the node's name
              cannot be looked up.)

       NI_NAMEREQD
              If set, then a error is returned if the hostname cannot be looked up.

       NI_NUMERICSERV
              If set, then the service address is returned in numeric form,
              for example by its port number.

       NI_DGRAM
              If  set, then the service is datagram (UDP) based rather than stream
              (TCP) based. This is required for the few ports (512-514) that have different
              services for UDP and TCP.

=================

Modified IPv6-aware C code:

    struct addrinfo *res, *aip;
    struct addrinfo hints;
    int sock = -1;
    int error;

    /* Get host address. Any type of address will do. */
    memset(&hints, 0, sizeof(hints));
    hints.ai_flags = AI_ALL|AI_ADDRCONFIG;
    hints.ai_socktype = SOCK_STREAM;

    error = getaddrinfo(hostname, servicename, &hints, &res);
    if (error != 0) {
       (void) fprintf(stderr,
          "getaddrinfo: %s for host %s service %s\n",
          gai_strerror(error), hostname, servicename);
       return -1;
    }
    /* Try all returned addresses until one works */
    for (aip = res; aip != NULL; aip = aip->ai_next) {
       /*
       * Open socket. The address type depends on what
       * getaddrinfo() gave us.
       */
       sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol);
       if (sock == -1) {
          perror("socket");
          freeaddrinfo(res);
          return -1;
       }

       /* Connect to the host. */
       if (connect(sock, aip->ai_addr, aip->ai_addrlen) == -1) {
          perror("connect");
          (void) close(sock);
          sock = -1;
          continue;
       }
       break;
    }
    freeaddrinfo(res);

Note that for new applications, if you write address-family-agnostic data structures,
there is no need for porting.

However, when it comes to server-side programming in C/C++, there is an additional wrinkle.
Namely, depending on whether your application is written for a dual-stack platform, such
as Solaris or Linux, or a single-stack platform, such as Windows, you would need to
structure the code differently.

Here's the corresponding server C code for a dual-stack platform:

    int ServSock, csock;
    /* struct sockaddr is too small! */
    struct sockaddr_storage addr, from;
    ...
    ServSock = socket(AF_INET6, SOCK_STREAM, PF_INET6);
    bind(ServSock, &addr, sizeof(addr));
    do {
       csock = accept(ServSocket, &from, sizeof(from));
       doClientStuff(csock);
    } while (!finished);
