Search code examples
citerationipv6

Iterate range of addresses between two IPV6 addresses


I need some way to iterate over the range of addresses between two IPv6 addresses. i.e. if the first IP is 2a03:6300:1:103:219:5bff:fe31:13e1 and the second one is 2a03:6300:1:103:219:5bff:fe31:13f4, I would like to visit the 19 addresses in that range.

With IPv4 I just do inet_aton for string representation and get htonl of s_addr in the resulting struct, but how can I do that for IPv6?

For simplify:

struct in6_addr sn,en;
long i;

s="2a03:6300:1:103:219:5bff:fe31:13e1";
e="2a03:6300:1:103:219:5bff:fe31:13f4";

inet_pton(AF_INET6,s,&sn);
inet_pton(AF_INET6,e,&en);

[..]

for (i = _first_ipv6_representation; i<=_second_ipv6_representation; i++){
    /* stuck here */
}

Solution

  • Old answer stricken per your comments, updated to iterate a range of addresses:

    char output[64];
    struct in6_addr sn, en;
    int octet;
    
    s="2a03:6300:1:103:219:5bff:fe31:13e1";
    e="2a03:6300:1:103:219:5bff:fe31:13f4";
    
    inet_pton(AF_INET6,s,&sn);
    inet_pton(AF_INET6,e,&en);
    
    for ( ; ; ) {
        /* print the address */
        if (!inet_ntop(AF_INET6, &sn, output, sizeof(output))) {
            perror("inet_ntop");
            break;
        }
    
        printf("%s\n", output);
    
        /* break if we hit the last address or (sn > en) */
        if (memcmp(sn.s6_addr, en.s6_addr, 16) >= 0) break;
    
        /* increment sn, and move towards en */
        for (octet = 15; octet >= 0; --octet) {
            if (sn.s6_addr[octet] < 255) {
                sn.s6_addr[octet]++;
                break;
            } else sn.s6_addr[octet] = 0;
        }
    
        if (octet < 0) break; /* top of logical address range */
    }