У меня есть два адреса IPv6 в строчном формате. Мне нужно сравнить первые 48 бит этого адреса.
inet_pton() дает мне in6_addr.
Как я извлекаю первые n бит из этих адресов?
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 байтов, я бы идеально сделал функцию для сравнения первых 6btyes адреса вместо того, чтобы делать это каждый раз, это облегчит вашу работу.
это от unix сетевого программирования richard stevens. это простая функция для сравнения двух 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
байтов, а также не в строчном формате, но некоторые простые изменения дадут вам желаемый результат.
Как предположил @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
}
Здесь я XORing каждый байт из 6 байтов, находящихся под угрозой, и ORing всех XOR вместе. Конечный результат становится zero
только тогда, когда все 48 бит одинаковы.
48 бит = 6 байт
Вы можете просто получить доступ к байтам массива в структуре с помощью [0]
, [1]
...
http://msdn.microsoft.com/de-de/library/windows/desktop/ms738560%28v=vs.85%29.aspx
Для сравнения, memcmp может помочь.
bits
кроме случаев, когда n кратно размеру байта.