Chcę zapisać dane w bazie danych za pomocą kanonicznego adresu IP.
Oprogramowanie w tym momencie może uzyskiwać adresy IPv4 lub IPv6. Chcę kanonizować, konwertując wszystkie adresy na adresy IPv6.
Wiem o tym inet_pton()
aby przekonwertować ciąg na adres binarny. Mogę więc spróbować raz z IPv6 i jeśli to się nie powiedzie, spróbuj ponownie z 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;
Tak więc szukam takiej funkcji, jak inet_convert_ipv4_to_ipv6(&sa4, &sa);
przekonwertować sockaddr_in
do a sockaddr_in6
. Czy mamy takie w bibliotece C?
Jeśli nie mamy takiej funkcji, rozwiązaniem byłoby użycie wprowadzenia ":: ffff:" jak w:
// 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);
Mam nadzieję, że mamy sposób na konwersję IPv4 sockaddr_in
do IPv6 sockaddr_in6
zamiast tego funkcja. Myślę, że byłoby czystsze ... Myślę, że ten ostatni fragment kodu nie jest w 100% bezpieczny (domyślam się, że mogę najpierw przetestować konwersję IPv4 i jeśli mu się uda, użyj konwersji IPv6, aby ją zabezpieczyć. Co za strata czasu!)
Odpowiedzi:
1 dla odpowiedzi № 1Możesz nadal używać sockaddr_in6 w obu wywołaniach inet_pton. Po pomyślnym przekonwertowaniu adresu IPv4 można wykonać przesunięcie do poprawnego miejsca. Tutaj jest przykładem tego w metodzie map4to6 ().
EDYCJA: Aby naprawić błędną nazwę wspomnianej metody.