Определение IP-адреса в строке (C ++)

0

У меня есть интересная проблема с обнаружением IP-адреса в C++. Я использовал функцию inet_pton и структуру sockaddr_in. Если строка действительна IPv4 или IPv6, функция вернет AF_INET или AF_INET6. В противном случае возвращается ноль.

Код ниже не работает. SIGSEGV в состоянии обнаружения IPv6 при правильном вводе адреса IPv6 (адрес IPv4 и неверный адрес в порядке). Такая же проблема возникает после удаления условия 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
Теги:
network-programming

2 ответа

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
    Понял. Благодарю.
1

Вы должны передать указатель на struct in6_addr в случае теста ipv6.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню