我有两个字符串格式的IPv6地址。我需要比较这些地址的前48位。
inet_pton()给了我in6_addr。
我如何从这些地址中提取前n位?
答案 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个字节而不是每次都这样做,它会让你的工作更轻松。
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
。