两个sockaddr相同的条件
1、ss_family相同
2、sin_addr.s_addr相同
int sockaddr_equal(const struct sockaddr_storage *a,
const struct sockaddr_storage *b) {
if (a->ss_family == AF_INET && b->ss_family == AF_INET) {
struct sockaddr_in *sa, *sb;
sa = (struct sockaddr_in *) a;
sb = (struct sockaddr_in *) b;
return sa->sin_addr.s_addr == sb->sin_addr.s_addr;
} if (a->ss_family == AF_INET6 && b->ss_family == AF_INET6) {
struct sockaddr_in6 *sa, *sb;
sa = (struct sockaddr_in6 *) a;
sb = (struct sockaddr_in6 *) b;
return memcmp(sa->sin6_addr.s6_addr, sb->sin6_addr.s6_addr, sizeof(sa->sin6_addr.s6_addr)) == 0;
}
return 0;
}
比较netmask
分别ip地址&网络掩码
int sockaddr_equal_netmask(const struct sockaddr_storage *a,
const struct sockaddr_storage *b, u16 nbits) {
unsigned char netmask[IP6_ADDR_LEN];
addr_btom(nbits, netmask, sizeof(netmask));
if (a->ss_family == AF_INET && b->ss_family == AF_INET) {
struct in_addr *sa, *sb, *sn;
sa = &((struct sockaddr_in *) a)->sin_addr;
sb = &((struct sockaddr_in *) b)->sin_addr;
sn = (struct in_addr *) netmask;
return (sa->s_addr & sn->s_addr) == (sb->s_addr & sn->s_addr);
} else if (a->ss_family == AF_INET6 && b->ss_family == AF_INET6) {
struct in6_addr *sa, *sb, *sn;
unsigned int i;
sa = &((struct sockaddr_in6 *) a)->sin6_addr;
sb = &((struct sockaddr_in6 *) b)->sin6_addr;
sn = (struct in6_addr *) netmask;
for (i = 0; i < sizeof(sa->s6_addr); i++) {
if ((sa->s6_addr[i] & sn->s6_addr[i]) != (sb->s6_addr[i] & sn->s6_addr[i])) {
return 0;
}
}
return 1;
}
return 0;
}