Getaddrinfo – Wikipedia

before-content-x4

Die Funktionen getaddrinfo() und getnameinfo() Konvertieren von Domänennamen, Hostnamen und IP-Adressen zwischen menschenlesbaren Textdarstellungen und strukturierten Binärformaten für die Netzwerk-API des Betriebssystems. Beide Funktionen sind in der POSIX-Standardanwendungsprogrammierschnittstelle (API) enthalten.

after-content-x4

getaddrinfo und getnameinfo sind inverse Funktionen zueinander. Sie sind netzwerkprotokollunabhängig und unterstützen sowohl IPv4 als auch IPv6. Es ist die empfohlene Schnittstelle für die Namensauflösung beim Erstellen protokollunabhängiger Anwendungen und für den Übergang von altem IPv4-Code zum IPv6-Internet.

Intern führen die Funktionen Auflösungen unter Verwendung des Domain Name System (DNS) durch, indem sie andere untergeordnete Funktionen aufrufen, beispielsweise gethostbyname().

Am 16. Februar 2016 wurde ein Sicherheitsfehler in der glibc-Implementierung von getaddrinfo() bekannt, der eine Pufferüberlauftechnik verwendet, die die Ausführung von beliebigem Code durch den Angreifer ermöglichen kann.[1]

struct addrinfo[edit]

Die C-Datenstruktur, die verwendet wird, um Adressen und Hostnamen innerhalb der Netzwerk-API darzustellen, ist die folgende:

struct addrinfo {
    int       ai_flags;
    int       ai_family;
    int       ai_socktype;
    int       ai_protocol;
    socklen_t ai_addrlen;
    struct    sockaddr* ai_addr;
    char*     ai_canonname;      /* canonical name */
    struct    addrinfo* ai_next; /* this struct can form a linked list */
};

In einigen älteren Systemen ist der Typ von ai_addrlen ist Größe_t anstatt socklen_t. Die meisten Steckdosenfunktionen, wie z akzeptieren() und getpeername(), erfordern, dass der Parameter den Typ hat Socken_t * und Programmierer geben die Adresse oft an die ai_addrlen Element der Adresse Struktur. Wenn die Typen nicht kompatibel sind, z. B. auf einem 64-Bit-Solaris 9-System, wo Größe_t ist 8 Byte und socklen_t 4 Byte beträgt, können Laufzeitfehler auftreten.

Die Struktur enthält Strukturen ai_familie und Sockenadresse mit eigenem sa_familie Bereich. Diese werden beim Erstellen der Struktur mit Funktion . auf den gleichen Wert gesetzt Getaddrinfo in einigen Implementierungen.

after-content-x4

getaddrinfo()[edit]

getaddrinfo() wandelt für Menschen lesbare Textstrings, die Hostnamen oder IP-Adressen darstellen, in eine dynamisch zugewiesene verknüpfte Liste von struct addrinfo-Strukturen um. Der Funktionsprototyp für diese Funktion wird wie folgt spezifiziert:

int getaddrinfo(const char* hostname,
                const char* service,
                const struct addrinfo* hints,
                struct addrinfo** res);
Hostname
kann entweder ein Domänenname wie “example.com”, eine Adresszeichenfolge wie “127.0.0.1” oder NULL sein, wobei in diesem Fall die Adresse 0.0.0.0 oder 127.0.0.1 abhängig von den Hinweis-Flags zugewiesen wird.
Service
kann eine als String übergebene Portnummer sein, zB “80”, oder ein Dienstname, zB “echo”. Im letzteren Fall verwendet eine typische Implementierung getservbyname() die Datei abfragen /etc/services um den Dienst in eine Portnummer aufzulösen.
Hinweise
kann entweder NULL oder an . sein Adresse Struktur mit der Art des angeforderten Dienstes.
res
ist ein Zeiger, der auf ein neues hinweist Adresse Struktur mit den nach erfolgreichem Abschluss der Funktion abgefragten Informationen.[2] Die Funktion gibt 0 bei Erfolg und einen Fehlerwert ungleich Null zurück, wenn sie fehlschlägt.[3]

Obwohl die Implementierungen von Plattform zu Plattform variieren, versucht die Funktion zunächst, eine Portnummer zu erhalten, normalerweise durch Verzweigung auf Service. Wenn der Zeichenfolgenwert eine Zahl ist, wird sie in eine ganze Zahl umgewandelt und aufgerufen htons(). Wenn es sich um einen Dienstnamen handelt, wie z www, der Dienst wird mit nachgeschlagen getservbyname(), unter Verwendung des Protokolls abgeleitet von Hinweise->ai_socktype als zweiter Parameter dieser Funktion. Dann wenn Hostname gegeben (nicht NULL), ein Aufruf an gethostbyname() löst es auf, oder sonst die Adresse 0.0.0.0 wird verwendet, wenn Hinweise->ai_flags ist eingestellt auf AI_PASSIV, und 127.0.0.1 ansonsten. Es hat eine neue zugewiesen Adresse Struktur gefüllt mit den entsprechenden sockaddr_in in einer dieser Bedingungen und fügt auch den zu Beginn abgerufenen Port hinzu. Endlich, das **res Parameter wird dereferenziert, damit er auf ein neu zugewiesenes . verweist Adresse Struktur.[4] In einigen Implementierungen, wie der Unix-Version für Mac OS, ist die Hinweise->ai_Protokoll überschreibt die Hinweise->ai_socktype Wert, während in anderen das Gegenteil der Fall ist, sodass beide mit äquivalenten Werten definiert werden müssen, damit der Code auf mehreren Plattformen funktioniert.

freeaddrinfo()[edit]

Diese Funktion gibt den von der Funktion zugewiesenen Speicher frei getaddrinfo(). Als Ergebnis des letzteren ist eine verkettete Liste von addrinfo-Strukturen beginnend bei der Adresse ai, freeaddrinfo() durchläuft die Liste und gibt jede der Reihe nach frei.

void freeaddrinfo(struct addrinfo *ai);

getnameinfo()[edit]

Die Funktion getnameinfo() wandelt die interne binäre Darstellung einer IP-Adresse in Form eines Zeigers in a . um struct sockaddr in Textstrings bestehend aus dem Hostnamen oder, falls die Adresse nicht in einen Namen aufgelöst werden kann, einer textuellen IP-Adressdarstellung sowie dem Service-Port-Namen oder der Nummer. Der Funktionsprototyp ist wie folgt spezifiziert:

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

Beispiel[edit]

Das folgende Beispiel verwendet getaddrinfo() um den Domainnamen aufzulösen www.beispiel.com in seine Adressliste und ruft dann an getnameinfo() bei jedem Ergebnis, um den kanonischen Namen für die Adresse zurückzugeben. Im Allgemeinen ergibt dies den ursprünglichen Hostnamen, es sei denn, die bestimmte Adresse hat mehrere Namen kanonisch Name wird zurückgegeben. In diesem Beispiel wird der Domänenname dreimal gedruckt, einmal für jedes der drei erhaltenen Ergebnisse.

#include 
#include 
#include 
#include 
#include 

#ifndef   NI_MAXHOST
#define   NI_MAXHOST 1025
#endif

int main(void)
{
    struct addrinfo* result;
    struct addrinfo* res;
    int error;

    /* resolve the domain name into a list of addresses */
    error = getaddrinfo("www.example.com", NULL, NULL, &result);
    if (error != 0) {   
        if (error == EAI_SYSTEM) {
            perror("getaddrinfo");
        } else {
            fprintf(stderr, "error in getaddrinfo: %sn", gai_strerror(error));
        }   
        exit(EXIT_FAILURE);
    }   

    /* loop over all returned results and do inverse lookup */
    for (res = result; res != NULL; res = res->ai_next) {   
        char hostname[NI_MAXHOST];
        error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0); 
        if (error != 0) {
            fprintf(stderr, "error in getnameinfo: %sn", gai_strerror(error));
            continue;
        }
        if (*hostname != '')
            printf("hostname: %sn", hostname);
    }   

    freeaddrinfo(result);
    return 0;
}

Siehe auch[edit]

Verweise[edit]

Externe Links[edit]

  • RFC 3493, Basic Socket Interface Extensions für IPv6

after-content-x4