我需要一些方法来迭代两个IPv6地址之间的地址范围。也就是说,如果第一个IP是2a03:6300:1:103:219:5bff:fe31:13e1,第二个是2a03:6300:1:103:219:5bff:fe31:13f4,我想访问该范围内的19个地址。
使用IPv4时,我只是对字符串表示执行inet_aton,并在结果结构中获取htonl of s_addr,但如何才能对IPv6执行此操作?
对于简化:
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 */
}发布于 2011-06-29 04:50:09
根据你的评论,旧答案受到了打击,更新后迭代了一系列地址:
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 */
}发布于 2011-06-29 03:47:19
这确实很棘手(我喜欢这个问题)。基本上,您需要递增和比较像这样存储的整数:uint8_t s6_addr[16]。
inc_s6和cmp_s6开始工作,这两个函数递增/比较这样的数组这是对inc_s6的一次尝试
void inc_s6(uint8_t *addr)
{
int i = 0;
for (i = 15; i >= 0; i--) {
if (++addr[i])
break;
}
}比较函数要简单得多。
发布于 2013-05-10 23:16:32
需要澄清的是:
我将它用于一些代理服务器,这些代理服务器有很多绑定的IPv6,并为每个请求委派新的IP。
我的增量函数有一些额外的解释:
const char *s="2a03:6300:2:200:0:0:0:1"; // first ip in range
struct in6_addr sn;
inet_pton(AF_INET6,s,&sn);
static struct in6_addr cn = sn; //current ip in6_addr struct
unsigned int skipBits=126;
unsigned __int128 icn,skip; // works only with gcc
if (skipBits!=0){ // now we need to skip netmask bits to get next ip
skip=pow(2,(128-skipBits))-2;
u_int32_t swap;
swap=ntohl(cn.s6_addr32[3]);
cn.s6_addr32[3]=ntohl(cn.s6_addr32[0]);
cn.s6_addr32[0]=swap;
swap=ntohl(cn.s6_addr32[2]);
cn.s6_addr32[2]=ntohl(cn.s6_addr32[1]);
cn.s6_addr32[1]=swap;
memcpy(&icn,&cn,sizeof icn);
// increment, works very fast because gcc will compile it into sse2 intrinsic (double int64 operations)
icn+=skip;
memcpy(&cn,&icn,sizeof icn);
swap=ntohl(cn.s6_addr32[3]);
cn.s6_addr32[3]=ntohl(cn.s6_addr32[0]);
cn.s6_addr32[0]=swap;
swap=ntohl(cn.s6_addr32[2]);
cn.s6_addr32[2]=ntohl(cn.s6_addr32[1]);
cn.s6_addr32[1]=swap;
}我没有显示比较函数,因为@sixlettervariables解决方案已经足够好用了。
https://stackoverflow.com/questions/6512138
复制相似问题