2012-12-05 6 views
6

Ich muss feststellen, ob eine bestimmte Zeichenfolge ein gültiges IPv4- oder IPv6-Adressliteral ist. Wenn ich das richtig verstanden habe, ist der richtige Weg, dies auf POSIX-Systemen zu tun, die Verwendung inet_pton, um es in eine Netzwerkadressstruktur zu konvertieren und zu sehen, ob es erfolgreich ist. Windows Vista und später haben InetPton, die im Wesentlichen das gleiche tut. Aber soweit ich das beurteilen kann, deklariert Windows XP keines von beiden, und ich muss das unter XP richtig machen können. Die Frage ist also, welche Systemfunktion dafür verwendet werden soll.Was ist das Windows XP-Äquivalent von inet_pton oder InetPton?

Im schlimmsten Fall kann ich eine Funktion schreiben, um es selbst zu analysieren, aber ich würde eine Standard-Systemfunktion bevorzugen, die daher gründlich getestet wurde und richtig alle Ecken Fälle behandelt und was nicht. Es ist schon schlimm genug, dass Microsoft nicht wie alle anderen nur inet_pton deklarieren konnte und ging mit InetPton für ihre neueren Betriebssysteme.

+3

Versuchen Sie [WSAAddressToString] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms741516 (v = vs.85) .aspx) – soulseekah

Antwort

3

Beim Durchsuchen der SDK-Header-Dateien finde ich inet_pton() in deklariert "c: \ Programme \ Microsoft SDKs \ Windows \ v7.1 \ Include \ WS2tcpip.h". InetPton ist nur ein #define dazu.

So scheint es, MS bietet schließlich die richtige Schnittstelle, aber nur mit Vista beginnen. Aber XP hat keine IPv6-Unterstützung, die erwähnenswert ist, wenn ich mich richtig erinnere.

Die andere Wahl ist, es mit zwei Rufe zu WSAAddressToString(), eins mit AF_INET, eins mit AF_INET6 selbst zu wickeln. Ich vermute hier von der Docs, habe es nicht ausprobiert.

5

Aber soweit ich das beurteilen kann, deklariert Windows XP keines von beiden, und ich muss dies unter XP richtig machen können.

InetPton documentation Staaten die folgenden Anforderungen:

  • Minimum unterstützten Client: Windows Vista [Desktop-Anwendungen nur]
  • Mindest unterstützten Server: Windows Server 2008 [Desktop-Anwendungen nur]

Im schlimmsten Fall kann ich eine Funktion schreiben, um es selbst zu analysieren, aber ich würde eine Standard-Systemfunktion bevorzugen, die daher gründlich getestet wurde und alle Eckenfälle und was auch immer behandelt.

Wie wäre es unter Berufung auf einen Teil des Codes aus dem OSS Netzwerk-Tool Wireshark?

Sie können ihre Reimplementation inet_pton in ihren source code repository finden.

Die Lizenz (siehe unten) ist sehr freizügig, so dass dies eine gute Alternative sein kann.

Erlaubnis, Kopie zu verwenden, ändern und verteilen diese Software für jeden Zweck mit oder ohne Gebühr wird hiermit erteilt, sofern der oben Copyright-Hinweis und diese Genehmigung in allen Kopien erscheinen.

8

In Windows XP können Sie diese Funktionen nutzen:

#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 

#include <winsock2.h> 
#include <ws2tcpip.h> 


int inet_pton(int af, const char *src, void *dst) 
{ 
    struct sockaddr_storage ss; 
    int size = sizeof(ss); 
    char src_copy[INET6_ADDRSTRLEN+1]; 

    ZeroMemory(&ss, sizeof(ss)); 
    /* stupid non-const API */ 
    strncpy (src_copy, src, INET6_ADDRSTRLEN+1); 
    src_copy[INET6_ADDRSTRLEN] = 0; 

    if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0) { 
    switch(af) { 
     case AF_INET: 
    *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; 
    return 1; 
     case AF_INET6: 
    *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; 
    return 1; 
    } 
    } 
    return 0; 
} 

const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) 
{ 
    struct sockaddr_storage ss; 
    unsigned long s = size; 

    ZeroMemory(&ss, sizeof(ss)); 
    ss.ss_family = af; 

    switch(af) { 
    case AF_INET: 
     ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src; 
     break; 
    case AF_INET6: 
     ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src; 
     break; 
    default: 
     return NULL; 
    } 
    /* cannot direclty use &size because of strict aliasing rules */ 
    return (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) == 0)? 
      dst : NULL; 
} 

Das ist es. Verknüpfen Sie mit der Bibliothek ws2_32.

+1

Beachten Sie, dass Sie einen Aufruf von WSAStartup benötigen werden initialisiere winsock2. – leiflundgren