IPV6地址的按位比较

时间:2014-04-13 07:19:10

标签: c++ c networking ipv6

我有两个字符串格式的IPv6地址。我需要比较这些地址的前48位。

inet_pton()给了我in6_addr。

我如何从这些地址中提取前n位?

3 个答案:

答案 0 :(得分:1)

48位= 6字节
您只需使用[0][1] ...
来访问结构中数组的字节 http://msdn.microsoft.com/de-de/library/windows/desktop/ms738560%28v=vs.85%29.aspx

要进行比较,memcmp可以提供帮助。

答案 1 :(得分:1)

struct in6_addr {
unsigned char   s6_addr[16];   /* IPv6 address */
};

char str[INET6_ADDRSTRLEN] //I assumed this has been filled up//
struct in6_addr addr1;

inet_pton(AF_INET6,&str, &addr1)

inet_pton将为我们填写上述结构。如果你只想要前6个字节(48位),

unsigned char array[6];
for(int i=0;i<6;i++)
array[i] = addr1.s6_addr[i];

现在你可以传递array来比较你的子网。这就是你提取前6个字节的方法,我理想情况下会做一个函数来比较地址的前6个字节而不是每次都这样做,它会让你的工作更轻松。

这是来自unix网络编程的理查德史蒂文斯。这是一个比较两个ip地址的简单函数。你可以直接传递sockaddr_xx结构,函数将为你做任何事情

#ifdef  HAVE_SOCKADDR_DL_STRUCT
#include    <net/if_dl.h>
#endif

int
sock_cmp_addr(const struct sockaddr *sa1, const struct sockaddr *sa2,
         socklen_t salen)
{
if (sa1->sa_family != sa2->sa_family)
    return(-1);

switch (sa1->sa_family) {
case AF_INET: {
    return(memcmp( &((struct sockaddr_in *) sa1)->sin_addr,
                   &((struct sockaddr_in *) sa2)->sin_addr,
                   sizeof(struct in_addr)));
}

#ifdef  IPV6
        case AF_INET6: {
    return(memcmp( &((struct sockaddr_in6 *) sa1)->sin6_addr,
                   &((struct sockaddr_in6 *) sa2)->sin6_addr,
                   sizeof(struct in6_addr)));
}
#endif

#ifdef  AF_UNIX
        case AF_UNIX: {
    return(strcmp( ((struct sockaddr_un *) sa1)->sun_path,
                   ((struct sockaddr_un *) sa2)->sun_path));
}
#endif

#ifdef  HAVE_SOCKADDR_DL_STRUCT
        case AF_LINK: {
    return(-1);     /* no idea what to compare here ? */
}
#endif
}
return (-1);
}

您可以修改此程序以在第一个n字节的子网上工作,也可以不是字符串格式,但是一些简单的修改将为您提供所需的结果。

答案 2 :(得分:1)

正如@deviantfan建议的那样,您需要使用s6_addr结构中存在的sockaddr_in6结构。

  unsigned char r=0;
  int i;
  //assuming your addresses are in add1 and addr2 after `inet_pton`.
  for( i=0; i<6;i++ )
       r = (addr1.sin6_addr.s6_addr[i] ^ addr2.sin6_addr.s6_addr[i]) | r ;


  if(!r){
      //Same first 48 bits
  }
  else{
      //Not same
  }

这里,我正在对所关注的6个字节的每个字节进行异或运算并将所有异或进行或运算。仅当所有48位相同时,最终结果才变为zero