简体   繁体   中英

make a reverse ipv6 for DNSBL in c++

i got a string called ipv6 with IPv6 address. I want to use the IP into DNSBL as zen spamhaus or others DNS. How can i do it ? The following code does not work as expected into compressed IPv6. How can i zero fill ? All the code in 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;
}

This program has multiple issues:

  1. string retorno = str2; has no namespace, and 'string' was not declared in this scope is the compiler error. Easy enough to fix.

     std::string retorno = str2; 
  2. struct in6_addr *addr; only allocates space for a pointer to a struct, but the memory for the struct itself is never allocated. This is the immediate cause of the crash.

    I'll just quick fix this by allocating it on the stack, and because it's no longer a pointer, access the struct members with . rather than -> .

     struct in6_addr addr; 

    Once you fix that, though, your program will crash again, due to:

  3. The char str2 is too small for the line being sprintf ed into it, which requires 47 printing characters and a null terminator.

    That's easily enough patched:

     char str2[48]; 
  4. The explicit typecast to int is unnecessary and can be omitted.

A working program would look like this:

#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());
}

This resolves all the crashes and prints output:

91.68.ba.c8.85.66.54.0b.a7.ec.a8.fd.b8.0d.01.20

But I think that that is not exactly the output you say you want. You will need to change the sprintf call to print exactly what you want in the format you want it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM