字符串(C++)中的IP地址检测

IP address detection in string (C++)

本文关键字:IP 地址 检测 中的 C++ 字符串      更新时间:2023-10-16

我在C++中遇到了一个有趣的IP地址检测问题。我使用了inet_pton函数和sockaddr_in结构。如果字符串是有效的IPv4或IPv6,则函数将返回AF_INETAF_INET6。否则返回零。

下面的代码不起作用 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函数的第一次实现中,问题是什么?

在ipv6测试的情况下,您必须将指针传递到structin6_addr。

struct sockaddr_in sa;

这是IPv4的结构;它没有足够的空间容纳IPv6地址,所以在这种情况下,您会越界。

在函数中添加更多代码恰好为函数提供了更多内存—要么通过声明另一个变量,要么通过触发一些我们无法合理化的任意、实现定义的结构;因此,当您溢出sa时,您将溢出到进程拥有的内存中,因此不会触发访问冲突错误。然而,这仍然是非常错误的。

IPv6地址将被读取到CCD_ 2中;一个包含在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;
}