2012-12-05 14 views
6

Należy ustalić, czy określony ciąg znaków jest prawidłowym literałem adresu IPv4 lub IPv6. Jeśli dobrze rozumiem, prawidłowym sposobem na to w systemach POSIX jest użycie inet_pton, aby przekonwertować go na strukturę adresów sieciowych i sprawdzić, czy się uda. Windows Vista i nowsze mają InetPton, co w zasadzie to samo. Ale o ile mogę powiedzieć, Windows XP nie deklaruje żadnej z nich, i muszę to zrobić poprawnie na XP. Tak więc pytanie brzmi, jaką funkcję systemową użyć, aby to zrobić?Co to jest odpowiednik systemu Windows XP inet_pton lub InetPton?

W najgorszym przypadku mogę napisać funkcję do samodzielnego analizowania, ale wolałbym standardową funkcję systemu, która została w związku z tym dokładnie przetestowana i odpowiednio obsługuje wszystkie przypadki narożne i inne. Już wystarczająco źle, że Microsoft nie mógł po prostu zadeklarować inet_pton, tak jak wszyscy inni, i udał się z InetPton dla swoich nowszych systemów operacyjnych.

+3

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

Odpowiedz

3

poszukać w plikach nagłówkowych SDK I znaleźć inet_pton() zadeklarowane w "c: \ Program Files \ Microsoft SDK \ Windows \ v7.1 \ include \ WS2tcpip.h". InetPton to tylko # definicja tego.

Wygląda na to, że MS zapewnia właściwy interfejs, ale dopiero zaczynając od Vista. Ale XP nie ma wsparcia IPv6, o którym warto wspomnieć, jeśli dobrze pamiętam.

Inny wybór to zawijanie go dwoma wywołaniami do WSAAddressToString(), jednym z AF_INET, jednym z AF_INET6. Zgaduję tutaj z dokumentów, nie próbowałem tego.

5

Ale o ile mogę powiedzieć, Windows XP nie deklaruje żadnej z nich, i muszę to zrobić poprawnie na XP.

InetPton documentation stany następujące wymagania:

  • Minimalna obsługiwana klient: Windows Vista [aplikacje desktopowe tylko]
  • Minimalna obsługiwana Serwer: [tylko aplikacje desktopowe] Server 2008 w systemie Windows

W najgorszym przypadku mogę napisać funkcję do samodzielnego analizowania, ale wolę standardową, systemową funkcję, która została w związku z tym dokładnie przetestowana i prawidłowo obsługuje wszystkie przypadki narożne i inne.

Jak o polegając porcji kodu z narzędzia sieciowego OSS Wireshark?

Można znaleźć ich powtórną implementację inet_pton w ich source code repository.

Licencja (patrz poniżej) jest bardzo liberalna, więc może być dobrą alternatywą.

Pozwolenie na używanie, kopiowanie, modyfikowanie i rozpowszechnianie tego oprogramowania do jakiegokolwiek celu z lub bez opłat zostaje udzielona pod warunkiem, że powyższe prawach autorskich i niniejsze pozwolenie pojawią się we wszystkich kopiach.

8

w systemie Windows XP można użyć następujących funkcji:

#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; 
} 

to wszystko. Połącz z biblioteką ws2_32.

+1

Pamiętaj, że będziesz potrzebować wywołania WSAStartup do zainicjalizuj winsock2. – leiflundgren

Powiązane problemy