2014-04-13 92 views
0

我有兩個字符串格式的IPv6地址。我需要比較這些地址的前48位。IPV6地址的按位比較

inet_pton()給我in6_addr。

如何從這些地址提取前n位?

+0

可尋址內存的最小單位是一個字節。所以除非n是字節大小的倍數,否則不能提取n'位。 – ajay

回答

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您的subnet.this的比較是如何提取的第6字節,我會做最好的功能,比較第一這個地址不需要每次都這樣做,它會讓你的工作更輕鬆。

這是來自unix網絡編程的richard stevens。這是一個簡單的函數來比較兩個IP address.you可以直接通過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結構。

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