Die in Arbeit befindliche Spezifikation des Institute of Electrical and Electronic Engineers (IEEE) POSIX 1003.1g definiert eine protokollunabhängige Funktion getaddrinfo() zur Übersetzung eines Rechnernamens in eine IP-Adresse. Die Beschreibung dieser Funktion wurde ebenfalls in [Gilligan 97] wiedergegeben:
int getaddrinfo(const char *hostname , const char *servname , const struct addrinfo *hints , struct addrinfo **res );
Im üblichen Client-Szenario, so auch im Beispiel IPv6/IPv4-TCP-Client, werden an die Funktion sowohl ein hostname als auch ein servname übergeben, die beide nicht NULL sind:
if (result = getaddrinfo(argv[1], argv[2], &hints, pai)) { fprintf(stderr, "getnameinfo: %s\n", gai_strerror(result)); exit(1); }
argv[1] und argv[2] enthalten Namen und Port des Servers.
hints wurde zuvor mit Hinweisen auf den gewünschten Socket-Typ und weiteren Flags gefüllt:
memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME;
In pai wird ein Zeiger auf eine verkettete Liste von einer oder mehreren komplettierten addrinfo-Strukturen zurückgeliefert.
Die addrinfo-Struktur ist folgendermaßen definiert:
#include <sys/socket.h> #include <netdb.h> struct addrinfo { int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ int ai_family; /* PF_xxx */ int ai_socktype; /* SOCK_xxx */ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ size_t ai_addrlen; /* length of ai_addr */ char *ai_canonname; /* canonical name for hostname */ struct sockaddr *ai_addr; /* binary address */ struct addrinfo *ai_next; /* next structure in linked list */ };
Im Beispiel werden zur Verdeutlichung die einzelnen Feldinhalte ausgegeben.
Ist ai als struct addrinfo definiert, kann nach dem obigen Funktionsaufruf in dieser Weise ein Socket erzeugt werden:
if ((sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) { printf("socket: %s(%d)\n", strerror(errno), errno); continue; };
So kann ein Verbindungswunsch geäußert werden:
if (connect(sock, ai->ai_addr, ai->ai_addrlen) < 0) { printf("connect: %s(%d)\n", strerror(errno), errno); continue; };
Im üblichen Server-Szenario wird die getaddrinfo()-Funktion ohne Angabe des Rechnernamens im ersten Parameter aufgerufen, was der Spezifikation einer ,,Wildcard``-Adresse entspricht:
if (result = getaddrinfo(NULL, port, &hints, pai)) { fprintf(stderr, "getnameinfo: %s\n", gai_strerror(result)); exit(1); }
Die bind()-Funktion kann analog zur connect-Funktion verwendet werden:
if (bind(sock, ai->ai_addr, ai->ai_addrlen)) { perror("bind"); exit(1); }