Существуют ли функции C для преобразования sockaddr_in в структуру sockaddr_in6?

Я хочу сохранить данные в базе данных, используя канонизированный IP-адрес.

На этом этапе программное обеспечение может получать адреса IPv4 или IPv6. Я хочу канонизировать путем преобразования всех адресов в IPv6-адрес.

я знаю inet_pton() преобразовать строку в двоичный адрес. Так что я могу попробовать один раз с IPv6, и если это не удается, попробуйте еще раз с IPv4:

struct sockaddr_in6 sa;
int r = inet_pton(AF_INET6, input_addr, &sa.sin6_addr);
if(r != 1)
{
    // try again with IPv4
    struct sockaddr_in sa4;
    int r = inet_pton(AF_INET, input_addr, &sa4.sin_addr);

    // is there such a function?!
    inet_convert_ipv4_to_ipv6(&sa4, &sa);
}
char output_addr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &sa, output_addr, sizeof(output_addr));

// in C++, I can do that if function returns std::string
// in C you cannot return a pointer on the stack, watch out!
return output_addr;

Итак, я ищу такую ​​функцию, как inet_convert_ipv4_to_ipv6(&sa4, &sa); преобразовать sockaddr_in к sockaddr_in6, Есть ли у нас такие в библиотеке C?

Если у нас нет такой функции, будет ли решение использовать интродьюсер::ffff: как в:

// try again with IPv4
std::string ipv4_to_ipv6("::ffff:");
ipv4_to_ipv6 += input_addr;
int r = inet_pton(AF_INET6, ipv4_to_ipv6.c_str(), &sa.sin_addr);

Я надеюсь, что у нас есть способ конвертировать IPv4 sockaddr_in на IPv6 sockaddr_in6 функция вместо Я думаю, что это будет чище... Я думаю, что этот последний кусок кода не на 100% безопасен (я думаю, что я могу сначала протестировать преобразование IPv4 и, если это удастся, затем использовать преобразование IPv6, чтобы сделать его безопасным. Какая трата времени!)

1 ответ

Вы можете продолжать использовать sockaddr_in6 в обоих вызовах inet_pton. Когда вы успешно конвертируете IPv4, вы можете перейти в нужное место. Вот пример этого в методе map4to6().

РЕДАКТИРОВАТЬ: исправить неправильное имя метода, упомянутого.

unsigned char *ip = in6_addr.s6_addr;
((uint64*)ip)[0] = 0;
((uint16*)ip)[4] = 0;
ip[10] = 0xFF;
ip[11] = 0xFF;
((in_addr_t*)(ip + 12))[0] = in_addr.s_addr
Другие вопросы по тегам