Разбор IPv6 в C - PullRequest
       19

Разбор IPv6 в C

11 голосов
/ 03 июня 2010

Я хотел знать, как я могу проанализировать IPv6-адрес в C и преобразовать его в 128-битное значение?

Таким образом, шестнадцатеричный адрес, такой как 1:22:333:aaaa:b:c:d:e, необходимо преобразовать в его 128-битный эквивалентный двоичный файл. Проблема заключается в том, что IP-адрес может иметь тип ::2 и его вариант, поскольку они являются действительными адресами IPv6.

Ввод с клавиатуры и, следовательно, в формате ASCII.

Ответы [ 7 ]

13 голосов
/ 03 июня 2010

Вы можете использовать POSIX inet_pton для преобразования строки в struct in6_addr.

#include <arpa/inet.h>

  ...

const char *ip6str = "::2";
struct in6_addr result;

if (inet_pton(AF_INET6, ip6str, &result) == 1) // success!
{
    //successfully parsed string into "result"
}
else
{
    //failed, perhaps not a valid representation of IPv6?
}
10 голосов
/ 03 июня 2010

getaddrinfo() может понимать адреса IPv6. Передайте ему AF_INET6 в подсказках, а также AI_NUMERICHOST (чтобы предотвратить поиск DNS) У Linux это есть, у Windows - как у Windows XP.

2 голосов
/ 11 июля 2017

Вы можете использовать функцию getaddrinfo() POSIX. Он более гибкий, чем inet_pton(), например, он автоматически определяет форматы адресов IPv4 и IPv6, он может разрешать даже имена хостов (с помощью разрешения DNS) и имена портов / служб (используя /etc/services).

#include <sys/types.h>
#include <netdb.h>
#include <netdb.h>

....

const char *ip6str = "::2";

struct sockaddr_storage result;
socklen_t result_len;

struct addrinfo *res = NULL;
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_DEFAULT | AI_NUMERICHOST | AI_NUMERICSERV;

rc = getaddrinfo(ip6str, NULL, &hints, &res);
if (rc != 0)
{
    fprintf(stderr, "Failure to parse host '%s': %s (%d)", ip6str, gai_strerror(rc), rc);
    return -1;
}

if (res == NULL)
{
    // Failure to resolve 'ip6str'
    fprintf(stderr, "No host found for '%s'", ip6str);
    return -1;
}

// We use the first returned entry
result_len = res->ai_addrlen;
memcpy(&result, res->ai_addr, res->ai_addrlen);

freeaddrinfo(res);

Адрес IPv6 хранится в переменной struct sockaddr_storage result.

if (result.ss_family == AF_INET6) // Ensure that we deal with IPv6
{
    struct sockaddr_in6 * sa6 = (struct sockaddr_in6 *) &result;
    struct in6_addr * in6 = &sa6->sin6_addr;
    in6->s6_addr[0]; // This is a first byte of the IPv6
    in6->s6_addr[15]; // This is a last byte of the IPv6
}
2 голосов
/ 03 июня 2010

Для разбора IPv6 в C вам нужно создать себе служебную функцию, которая разбивает строку на токены (двоеточие для шестнадцатеричных блоков и косая черта для битов подсети).

  1. Токенизация необработанной строки IPv6 в меньшую подстроку.
  2. Преобразование непустой подстроки в шестнадцатеричные блоки. (Преобразование ASCII в десятичное)
  3. Расширить шестнадцатеричный блок до 2 байтов, добавив ноль впереди. (обрезаются только ведущие нули)
  4. Полный IPv6 должен иметь 8 шестнадцатеричных блоков, рассчитать недостающие шестнадцатеричные блоки. (группировка нулей может произойти только один раз)
  5. Вставьте недостающий гекс-блок. (используйте индекс пустой подстроки)
0 голосов
/ 14 февраля 2017

, если вы можете использовать повышение, что-то вроде этого должно работать:

#include<boost/asio.hpp>

using boost::asio::ip;

bool parseIpv6String(std::string ipv6_string, char* dest){
    try{
        address_v6 addr = address_v6::from_string(ipv6_string);
        memcpy(dest,addr.to_bytes().data(), 16);
    }catch(...){
        return false;
    }
    return true;
}

Он немного более переносим, ​​чем, например, специальные функции POSIX.

0 голосов
/ 02 марта 2016

Rosetta имеет образцы на нескольких языках: https://rosettacode.org/wiki/Parse_an_IP_Address

0 голосов
/ 06 июня 2011

В Windows вы можете использовать WSAStringToAddress, который доступен с Windows 2000.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...