Я получил строку под названием IPv6 с IPv6-адресом.
Я хочу использовать IP-адрес в DNSBL в качестве zen spamhaus или другого DNS.
Как мне это сделать ? Следующий код не работает должным образом в сжатый IPv6. Как я могу заполнить ноль? Весь код на C ++.
std::string invertirv6 (const std::string &str) {
struct in6_addr *addr;
inet_pton(AF_INET6,str.c_str(),&addr);
char str2[41];
sprintf(str2,"%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x",
(int)addr->s6_addr[15], (int)addr->s6_addr[14],
(int)addr->s6_addr[13], (int)addr->s6_addr[12],
(int)addr->s6_addr[11], (int)addr->s6_addr[10],
(int)addr->s6_addr[9], (int)addr->s6_addr[8],
(int)addr->s6_addr[7], (int)addr->s6_addr[6],
(int)addr->s6_addr[5], (int)addr->s6_addr[4],
(int)addr->s6_addr[3], (int)addr->s6_addr[2],
(int)addr->s6_addr[1], (int)addr->s6_addr[0]);
string retorno = str2;
return retorno;
}
Эта программа имеет несколько проблем:
string retorno = str2;
не имеет пространства имен, и 'string' was not declared in this scope
это ошибка компилятора Достаточно легко исправить.
std::string retorno = str2;
struct in6_addr *addr;
только выделяет место для указатель в структуру, но память для самой структуры никогда не выделяется. Это непосредственная причина аварии.
Я просто быстро исправлю это, разместив его в стеке, и, поскольку он больше не является указателем, получайте доступ к членам структуры с помощью .
скорее, чем ->
,
struct in6_addr addr;
Однако, как только вы это исправите, ваша программа снова потерпит крах из-за:
char str2
слишком мала для линии sprintf
в него, что требует 47 печатных символов и нулевого терминатора.
Это достаточно легко исправлено:
char str2[48];
Явный тип, приведенный к int
является ненужным и может быть опущено.
Рабочая программа будет выглядеть так:
#include <cstdio>
#include <string>
#include <arpa/inet.h>
#include <sys/socket.h>
std::string invertirv6 (const std::string &str) {
struct in6_addr addr;
inet_pton(AF_INET6,str.c_str(),&addr);
char str2[48];
sprintf(str2,"%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x",
addr.s6_addr[15], addr.s6_addr[14],
addr.s6_addr[13], addr.s6_addr[12],
addr.s6_addr[11], addr.s6_addr[10],
addr.s6_addr[9], addr.s6_addr[8],
addr.s6_addr[7], addr.s6_addr[6],
addr.s6_addr[5], addr.s6_addr[4],
addr.s6_addr[3], addr.s6_addr[2],
addr.s6_addr[1], addr.s6_addr[0]);
std::string retorno = str2;
return retorno;
}
int main(void) {
std::string a = "2001:db8:fda8:eca7:b54:6685:c8ba:6891";
std::string b = invertirv6(a);
printf("%s\n", b.c_str());
}
Это разрешает все сбои и печатает вывод:
91.68.ba.c8.85.66.54.0b.a7.ec.a8.fd.b8.0d.01.20
Но я думаю, что это не совсем тот результат, который вы хотите сказать. Вам нужно будет изменить sprintf
позвоните, чтобы напечатать именно то, что вы хотите в формате, который вы хотите.
Других решений пока нет …