побитовое сравнение адреса IPV6

0

У меня есть два адреса IPv6 в строчном формате. Мне нужно сравнить первые 48 бит этого адреса.

inet_pton() дает мне in6_addr.

Как я извлекаю первые n бит из этих адресов?

  • 0
    Наименьшая единица адресуемой памяти - это байт. Таким образом, вы не можете извлечь n bits кроме случаев, когда n кратно размеру байта.
Теги:
networking
ipv6

3 ответа

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 байтов, я бы идеально сделал функцию для сравнения первых 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 байтов, а также не в строчном формате, но некоторые простые изменения дадут вам желаемый результат.

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
  }

Здесь я XORing каждый байт из 6 байтов, находящихся под угрозой, и ORing всех XOR вместе. Конечный результат становится zero только тогда, когда все 48 бит одинаковы.

1

48 бит = 6 байт
Вы можете просто получить доступ к байтам массива в структуре с помощью [0], [1]...
http://msdn.microsoft.com/de-de/library/windows/desktop/ms738560%28v=vs.85%29.aspx

Для сравнения, memcmp может помочь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню