C++ 是否有按位和ipv6地址以及网络掩码(前缀)的代码?

C++ 是否有按位和ipv6地址以及网络掩码(前缀)的代码?,c++,c,networking,ipv6,C++,C,Networking,Ipv6,我想问一下ipv6网络和主机端的计算 例如,我有IPv6地址2001:470:1f15:1bcd:34::41和前缀96 您知道在IPv6地址和前缀之间按位执行和的简单方法吗 根据IPv4: 192.168.1.2 255.255.255.0 network : 192.168.1.0 这么简单 我想对IPv6地址做同样的事情。但是IPv6地址是16个字节,所以不能使用unsigned int 有什么API可以做到这一点吗?还是应该使用数组?您可以使用将地址按网络字节顺序转换为二进制。然后

我想问一下ipv6网络和主机端的计算

例如,我有IPv6地址
2001:470:1f15:1bcd:34::41
和前缀
96

您知道在IPv6地址和前缀之间按位执行
的简单方法吗

根据IPv4:

192.168.1.2  255.255.255.0  network : 192.168.1.0
这么简单

我想对IPv6地址做同样的事情。但是IPv6地址是16个字节,所以不能使用
unsigned int


有什么API可以做到这一点吗?还是应该使用数组?

您可以使用将地址按网络字节顺序转换为二进制。然后一次设置/清除一个字节。

像16字节数组一样威胁IP,跳过下一个字节中的
屏蔽/8
字节屏蔽较高的
屏蔽%8
位,将其他位设置为
0

int offset=masked/8;
char remmask=0;
int rem = masked%8;
while(rem)
{
   rem--;
   remmask|= 0x80>>rem; //0x80 is the highest bit in a byte set

}
offset++;
(((char*)ipv6)+offset) &= remmask;
while(offset<16)
{
   (((char*)ipv6)+offset=0;
   offset++;
}
int offset=masked/8;
char-remmask=0;
int rem=屏蔽的%8;
while(rem)
{
雷姆--;
remmask |=0x80>>rem;//0x80是字节集中的最高位
}
offset++;
(((char*)ipv6)+offset)&=remmask;

而(偏移量根据前缀长度计算掩码:

struct sockaddr_in6 netmask;
for (long i = prefixLength, j = 0; i > 0; i -= 8, ++j)
  netmask.sin6_addr.s6_addr[ j ] = i >= 8 ? 0xff
                                    : (ULONG)(( 0xffU << ( 8 - i ) ) & 0xffU );

伙计们,我解决了我的问题源代码如下使用它并继续编码:D:警告函数假设IPv6地址有效。, 我的类型是:

typedef uint16_t ip6_addr[8];


void ipv6_app_mask(const char *ip6addr, unsigned int mask, ip6_addr ip6){

    ip6_addr in_ip6;
    inet_pton(PF_INET6, ip6addr, ip6);


    for(int i = 0; i < 8; i++){
        in_ip6[i] = ntohs(ip6[i]);
    }

    int index = (int) (mask / 16);
    int remain_mask = mask % 16;

     if(remain_mask == 0 && index == 8)
      return;

     switch(remain_mask){
        case 0:in_ip6[index++] = 0; break;
        case 1:in_ip6[index++]&=0x8000; break;
        case 2:in_ip6[index++]&=0xc000; break;
        case 3:in_ip6[index++]&=0xe000; break;
        case 4:in_ip6[index++]&=0xf000; break;

        case 5:in_ip6[index++]&=0xf800; break;
        case 6:in_ip6[index++]&=0xfc00; break;
        case 7:in_ip6[index++]&=0xfe00; break;
        case 8:in_ip6[index++]&=0xff00; break;

        case  9:in_ip6[index++]&=0xff80; break;
        case 10:in_ip6[index++]&=0xffc0; break;
        case 11:in_ip6[index++]&=0xffe0; break;
        case 12:in_ip6[index++]&=0xfff0; break;

        case 13:in_ip6[index++]&=0xfff8; break;
        case 14:in_ip6[index++]&=0xfffc; break;
        case 15:in_ip6[index++]&=0xfffe; break;
    }

    for (int i = index; i < 8; i++){
       in_ip6[i] = 0;
    }

    for(int i = 0; i < 8; i++){
       ip6[i] = htons(in_ip6[i]);
    } 

 return;
}
typedef uint16_t ip6_addr[8];
无效ipv6应用程序掩码(常量字符*ip6addr,无符号整数掩码,ip6地址ip6){
ip6地址为ip6;
inet_pton(PF_inet 6,ip6addr,ip6);
对于(int i=0;i<8;i++){
inip6[i]=ntohs(ip6[i]);
}
整数指数=(整数)(掩码/16);
int remain_mask=掩码%16;
如果(保持掩码==0&&index==8)
返回;
开关(保持屏蔽){
案例0:in_ip6[index++]=0;中断;
案例1:in_ip6[index++]&=0x8000;中断;
案例2:in_ip6[索引++]&=0xc000;中断;
案例3:in_ip6[index++]&=0xe000;中断;
案例4:in_ip6[index++]&=0xf000;中断;
案例5:in_ip6[index++]&=0xf800;中断;
案例6:in_ip6[索引++]&=0xfc00;中断;
案例7:in_ip6[index++]&=0xfe00;中断;
案例8:in_ip6[index++]&=0xff00;中断;
案例9:in_ip6[index++]&=0xff80;中断;
案例10:in_ip6[索引++]&=0xffc0;中断;
案例11:in_ip6[index++]&=0xffe0;中断;
案例12:in_ip6[index++]&=0xfff0;中断;
案例13:in_ip6[index++]&=0xfff8;中断;
案例14:in_ip6[index++]&=0xfffc;中断;
案例15:in_ip6[index++]&=0xfffe;中断;
}
for(int i=索引;i<8;i++){
inip6[i]=0;
}
对于(int i=0;i<8;i++){
ip6[i]=htons(in_ip6[i]);
} 
返回;
}

<代码> > p>好,我是用C而不是C++来做的,但是它应该工作。而且,它使用的是一个GNU扩展的BSWAP64,所以可能对任何事情都不起作用。 amd64上的速度似乎非常快,并且比Yasar提出的当前解决方案更快:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include <arpa/inet.h>

#if defined __GNUC__ && __GNUC__ >= 2
#include <byteswap.h>
#else
#error "Sorry, you need GNU for this"
#endif

struct split
{
  uint64_t start;
  uint64_t end;
};

void ipv6_prefix (unsigned char *masked, unsigned char *packed, int prefix)
{
  struct split parts;
  uint64_t mask = 0;
  unsigned char *p = masked;

  memset(masked, 0, sizeof(struct in6_addr));
  memcpy(&parts, packed, sizeof(parts));

  if (prefix <= 64)
  {
    mask = bswap_64(bswap_64(parts.start) & ((uint64_t) (~0) << (64 - prefix)));
    memcpy(masked, &mask, sizeof(uint64_t));
    return;
  }

  prefix -= 64;

  memcpy(masked, &(parts.start), sizeof(uint64_t));
  p += sizeof(uint64_t);
  mask = bswap_64(bswap_64(parts.end) & (uint64_t) (~0) << (64 - prefix));
  memcpy(p, &mask, sizeof(uint64_t));
}

int main (int argc, char **argv)
{
  unsigned char packed[sizeof(struct in6_addr)];
  unsigned char masked[sizeof(struct in6_addr)];
  char buf[INET6_ADDRSTRLEN], *p;
  int prefix = 56;

  if (argc < 2)
    return 1;

  if ((p = strchr(argv[1], '/')))
  {
    *p++ = '\0';
    prefix = atoi(p);
  }

  inet_pton(AF_INET6, argv[1], packed);

  ipv6_prefix(masked, packed, prefix);

  inet_ntop(AF_INET6, masked, buf, INET6_ADDRSTRLEN);
  printf("prefix = %s/%d\n", buf, prefix);
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#如果已定义,则&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&2
#包括
#否则
#错误“抱歉,您需要GNU来完成此操作”
#恩迪夫
结构拆分
{
uint64_t启动;
uint64_t端;
};
无效ipv6_前缀(无符号字符*掩码,无符号字符*压缩,整数前缀)
{
结构拆分部件;
uint64_t mask=0;
无符号字符*p=屏蔽;
memset(掩码,0,sizeof(struct in6_addr));
memcpy(和零件,包装,尺寸(零件));
如果(前缀这里是简单计时器:

bool timer_check()
{
    static int count = 0;
    time_t seconds1;

    if(val)
    {
        time(&seconds);
        val = false;
        printf("In the first if loop\n");
    }

    time(&seconds1);

    if( (seconds1 - seconds) <= 10 && count < 10 )
    {
       count ++;
    }
    if ((seconds1 - seconds) >= 10)
    {
        count = 0;
        seconds = seconds1;
    }

    if (count < 10)
       return true;
    return false;
}
bool timer\u check()
{
静态整数计数=0;
时间秒1;
if(val)
{
时间(秒);
val=假;
printf(“在第一个if循环中\n”);
}
时间(秒1);
如果((秒1-秒)=10)
{
计数=0;
秒=秒1;
}
如果(计数<10)
返回true;
返回false;
}

如果您将255.255.255.0写为/24,那么位篡改几乎是相同的。请注意,您也不应该在IPv4中使用
无符号int
;您应该使用
uint32\u t
(或它的typedef)。哇,这与“mask”一词的模糊用法纠缠不清.刚刚在i686 virtualbox上试用过,而且速度明显更快。内存损坏警报!提示:如果前缀长度为3,循环会迭代多少次?@JdeBP仅以8的倍数进行测试(tm):-)
bool timer_check()
{
    static int count = 0;
    time_t seconds1;

    if(val)
    {
        time(&seconds);
        val = false;
        printf("In the first if loop\n");
    }

    time(&seconds1);

    if( (seconds1 - seconds) <= 10 && count < 10 )
    {
       count ++;
    }
    if ((seconds1 - seconds) >= 10)
    {
        count = 0;
        seconds = seconds1;
    }

    if (count < 10)
       return true;
    return false;
}