Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 迭代两个IPV6地址之间的地址范围_C_Iteration_Ipv6 - Fatal编程技术网

C 迭代两个IPV6地址之间的地址范围

C 迭代两个IPV6地址之间的地址范围,c,iteration,ipv6,C,Iteration,Ipv6,我需要某种方法来迭代两个IPv6地址之间的地址范围。i、 e.如果第一个IP是2a03:6300:1:103:219:5bff:fe31:13e1,第二个IP是2a03:6300:1:103:219:5bff:fe31:13f4,我想访问该范围内的19个地址 对于IPv4,我只需对字符串表示执行inet\u aton,并在生成的结构中获得s\u addr的htonl,但对于IPv6,我如何才能做到这一点 为了简化: struct in6_addr sn,en; long i; s="2a03:

我需要某种方法来迭代两个IPv6地址之间的地址范围。i、 e.如果第一个IP是
2a03:6300:1:103:219:5bff:fe31:13e1
,第二个IP是
2a03:6300:1:103:219:5bff:fe31:13f4
,我想访问该范围内的19个地址

对于IPv4,我只需对字符串表示执行
inet\u aton
,并在生成的结构中获得
s\u addr
htonl
,但对于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=\u first\u ipv6\u表示;i这确实很棘手(我喜欢这个问题)。基本上,您需要递增和比较这样存储的整数:
uint8\u t s6\u addr[16]

  • 找到一种很酷的方法将这些数组转换为128b整数,并从中开始工作
  • 定义增加/比较此类数组的两个函数
    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;
        }
}

比较函数要简单得多。

根据您的评论选择旧答案,更新后可迭代一系列地址:

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 */
}
char输出[64];
6地址序列号中的结构,en;
int八位组;
s=“2a03:6300:1:103:219:5BF:fe31:13e1”;
e=“2a03:6300:1:103:219:5bff:fe31:13f4”;
网络(AF\U网络6、s和sn);
内特普顿(AF_INET6、e和en);
对于(;;){
/*打印地址*/
if(!inet_ntop(AF_INET6,&sn,output,sizeof(output))){
perror(“inet_ntop”);
打破
}
printf(“%s\n”,输出);
/*如果我们点击最后一个地址或(sn>en),则中断*/
如果(memcmp(序号s6地址,en.s6地址,16)>=0)中断;
/*增加sn,并向en移动*/
用于(八位字节=15;八位字节>=0;--八位字节){
if(序列号s6地址[八位字节]<255){
序列号s6_地址[八位组]+;
打破
}else序列号s6_addr[八位组]=0;
}
如果(八位组<0)中断;/*逻辑地址范围的顶部*/
}
如需澄清:

我将其用于一些具有大量绑定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解决方案工作得很好。

您的问题中有两个问题,它们看起来不相关,我很难准确理解您想要做什么。只有一个问题:如何“为”做在两个ipv6地址之间循环迭代?例如,您想将
s
e
都存储在可以循环的地方?或者您想比较这两个地址吗?@sixlettervariables:是的,我想将
s
e
都存储在我可以循环的地方只是好奇您使用它的目的。这个循环可以d根据输入运行很长一段时间。-)非常感谢,我会试试这个,因为
uint8\u t
中的算术是以256模执行的,如果(++addr[I])中断,您只需执行
if作为循环体。@caf Right。我忘了定义了无符号整数溢出。不,您不明白,我需要在范围内的所有地址之间迭代(即从第一个ip到第二个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;
}