2014-11-08 26 views
0

我在C++中使用IP地址檢測有一個有趣的問題。我用inet_pton函數和sockaddr_in結構。如果字符串是有效的IPv4或IPv6,函數將返回AF_INETAF_INET6。否則返回零。字符串中的IP地址檢測(C++)

以下代碼無效。SIGSEGV當輸入有效時,IPv6地址(IPv4地址和無效地址正常)處於IPv6檢測狀態。同樣的問題是在去除IPv4條件之後。

#include <string> 
#include <iostream> 
#include <arpa/inet.h> 

using namespace std; 

int isIP(string); 

int main(int argc, char *argv[]){ 
     string s = "::1"; 
     int test = isIP(s); 
     return 0; 
} 

int isIP(string addr){ 
     struct sockaddr_in sa; 
     if((inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr)))) 
       return AF_INET; 
     if((inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr)))) 
       return AF_INET6; 
     return 0; 
} 

但是,當是功能ISIP改變像下面的代碼,一切正常

int isIP(string addr){ 
     struct sockaddr_in sa; 
     cout << addr + "\n"; 
     if(inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr))) 
       return AF_INET; 
     if(inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr))) 
       return AF_INET6; 
     return 0; 
} 

int isIP(string addr){ 
     struct sockaddr_in sa, sa2; 
     if((inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr)))) 
       return AF_INET; 
     if((inet_pton(AF_INET6, addr.c_str(), &(sa2.sin_addr)))) 
       return AF_INET6; 
     return 0; 
} 

int isIP(string addr){ 
     struct sockaddr_in sa; 
     int r1 = inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr)); 
     int r2 = inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr)); 

     if(r1) 
       return AF_INET; 
     if(r2) 
       return AF_INET6; 
     return 0; 
} 

什麼是第一次執行的ISIP功能這個問題?

+0

是sockaddr_in6的比SOCKADDR_IN – stark 2014-11-08 21:53:49

回答

0
struct sockaddr_in sa; 

這是IPv4的結構;它沒有足夠的空間用於IPv6地址,所以在這些情況下你會走出界限。

向函數添加更多代碼只是通過聲明另一個變量或者通過觸發一些任意的,實現定義的結構,使我們無法合理化—,使得當您溢出sa,你溢出到進程擁有的內存中,因此不會觸發訪問衝突錯誤。但是,它仍然是非常錯誤的。

將IPv6地址讀入struct in6_addr;一個是包含在struct sockaddr_in6如此,例如:

bool isIPv6(const string& addr) 
{ 
    struct sockaddr_in6 sa; 
    if (inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr))) 
     return true; 
    return false; 
} 
+0

明白了較大。謝謝。 – 2014-11-09 22:20:20

1

在ipv6測試的情況下,您必須將指針傳遞給struct in6_addr。