2010-09-17 28 views
7

Tôi có một chương trình có thành phần bên ngoài chuyển cho tôi một chuỗi chứa địa chỉ IP. Sau đó tôi cần biến nó thành một URI. Đối với IPv4, điều này rất dễ dàng; Tôi thêm vào http: // và nối thêm /. Tuy nhiên, đối với IPv6 tôi cũng cần phải bao quanh nó trong ngoặc [].Cho biết chuỗi văn bản có phải là địa chỉ IPv6 hoặc địa chỉ IPv4 bằng cách sử dụng ổ cắm chuẩn API API

Có cuộc gọi API ổ cắm tiêu chuẩn nào để xác định họ địa chỉ của địa chỉ không?

+0

Tôi biết rằng nó không phải là một phần của API socket, nhưng nếu IP4 và IP6 là những khả năng duy nhất, bạn không thể làm điều này với 'strlen'? ;-) –

+0

@Steve Jessop xem xét ví dụ: ff02 :: 2 và 8.8.8.8 – nos

+0

@nos: đủ công bằng, không nhận ra địa chỉ cũ là địa chỉ hợp lệ. Nói chung, có cách nào đó để kiểm tra các chuỗi, đó là mã đơn giản hơn so với sử dụng API socket? Trong trường hợp này, cấu trúc chứa địa chỉ được phân tích cú pháp là không cần thiết. –

Trả lời

13

Sử dụng getaddrinfo() và đặt cờ gợi ý AI_NUMERICHOST, gia đình thành AF_UNSPEC, sau khi trở về thành công từ getaddrinfo, cấu trúc kết quả addrinfo .ai_family thành viên sẽ là AF_INET hoặc AF_INET6.

EDIT, ví dụ nhỏ

#include <sys/types.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netdb.h> 

int main(int argc, char *argv[]) 
{ 
    struct addrinfo hint, *res = NULL; 
    int ret; 

    memset(&hint, '\0', sizeof hint); 

    hint.ai_family = PF_UNSPEC; 
    hint.ai_flags = AI_NUMERICHOST; 

    ret = getaddrinfo(argv[1], NULL, &hint, &res); 
    if (ret) { 
     puts("Invalid address"); 
     puts(gai_strerror(ret)); 
     return 1; 
    } 
    if(res->ai_family == AF_INET) { 
     printf("%s is an ipv4 address\n",argv[1]); 
    } else if (res->ai_family == AF_INET6) { 
     printf("%s is an ipv6 address\n",argv[1]); 
    } else { 
     printf("%s is an is unknown address format %d\n",argv[1],res->ai_family); 
    } 

    freeaddrinfo(res); 
    return 0; 
} 

$ ./a.out 127.0.0.1 
127.0.0.1 is an ipv4 address 
$ ./a.out ff01::01 
ff01::01 is an ipv6 address 
16

Loại. Bạn có thể sử dụng inet_pton() để thử phân tích cú pháp chuỗi đầu tiên dưới dạng IPv4 (AF_INET) rồi đến IPv6 (AF_INET6). Mã trả về sẽ cho bạn biết nếu hàm đã thành công và chuỗi do đó chứa địa chỉ của loại đã cố gắng.

Ví dụ:

#include <arpa/inet.h> 
#include <stdio.h> 

static int 
ip_version(const char *src) { 
    char buf[16]; 
    if (inet_pton(AF_INET, src, buf)) { 
     return 4; 
    } else if (inet_pton(AF_INET6, src, buf)) { 
     return 6; 
    } 
    return -1; 
} 

int 
main(int argc, char *argv[]) { 
    for (int i = 1; i < argc; ++i) { 
     printf("%s\t%d\n", argv[i], ip_version(argv[i])); 
    } 

    return 0; 
} 
+1

getaddrinfo() có nhiều phí nhưng về cơ bản cũng gọi inet_pton(). inet_pton() thực sự là tất cả những gì bạn cần và IMHO câu trả lời tốt nhất cho câu hỏi này. Nó cũng không yêu cầu chức năng dọn dẹp. – rockdaboot

Các vấn đề liên quan