%% options copyright owner = Dirk Krause copyright year = 2015-xxxx license = bsd %% module #include "dk4conf.h" #include "dk4types.h" #include "dk4error.h" #include "dk4sock.h" #include "dk4sto.h" $!trace-include #if DK4_HAVE_STRUCT_SOCKADDR_IN6 /** Compare IPv6 address structures. @param left Left address in comparison. @param mask Network mask to use, may be NULL. @param right Right address in comparison. @return -1, 0 or 1 if lr. */ static int dk4socket_compare_in6_addr3( const struct in6_addr *left, const struct in6_addr *mask, const struct in6_addr *right ) { const unsigned char *ucl; const unsigned char *ucm; const unsigned char *ucr; unsigned char ul; unsigned char ur; size_t i; int back = 0; ucl = &(left->s6_addr[0]); ucm = &(mask->s6_addr[0]); ucr = &(right->s6_addr[0]); for (i = 0; ((16 > i) && (0 == back)); i++) { ul = ucl[i]; ur = ucr[i]; if (NULL != mask) { ul &= ucm[i]; ur &= ucm[i]; } if (ul > ur) { back = 1; } else { if (ul < ur) { back = -1; } } } return back; } #endif int dk4socket_allowed_peer_compare( const void *pl, const void *pr, int cr ) { const dk4_allowed_peer_t *ppl; const dk4_allowed_peer_t *ppr; const struct sockaddr *pso; const struct sockaddr_in *ps4; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 const struct sockaddr_in6 *ps6; #endif unsigned long ul1; unsigned long ul2; unsigned long ul3; int back = 0; $? "+ dk4socket_allowed_peer_compare %d", cr if (NULL != pl) { if (NULL != pr) { switch (cr) { case 1: { $? ". peer /sockaddr" ppl = (const dk4_allowed_peer_t *)pl; pso = (const struct sockaddr *)pr; $? ". ppl->af = %d pso->af = %d", ppl->af, pso->sa_family if (ppl->af < pso->sa_family) { $? ". families differ" back = -1; } else { if (ppl->af > pso->sa_family) { $? ". families differ" back = 1; } } if (0 == back) { $? ". same family" switch (ppl->af) { case AF_INET : { $? ". IPv4" ul1 = (ppl->data).ipv4.ad.s_addr; ul3 = (ppl->data).ipv4.ma.s_addr; ps4 = (const struct sockaddr_in *)pso; ul2 = ps4->sin_addr.s_addr; ul1 = dk4socket_ntohl(ul1); ul2 = dk4socket_ntohl(ul2); ul3 = dk4socket_ntohl(ul3); $? ". ul1 = %lu.%lu.%lu.%lu", ((ul1 >> 24) & 0xFFUL), ((ul1 >> 16) & 0xFFUL), ((ul1 >> 8) & 0xFFUL), (ul1 & 0xFFUL) $? ". ul2 = %lu.%lu.%lu.%lu", ((ul2 >> 24) & 0xFFUL), ((ul2 >> 16) & 0xFFUL), ((ul2 >> 8) & 0xFFUL), (ul2 & 0xFFUL) $? ". ul3 = %lu.%lu.%lu.%lu", ((ul3 >> 24) & 0xFFUL), ((ul3 >> 16) & 0xFFUL), ((ul3 >> 8) & 0xFFUL), (ul3 & 0xFFUL) ul1 &= ul3; ul2 &= ul3; $? ". ul1 = %lu.%lu.%lu.%lu", ((ul1 >> 24) & 0xFFUL), ((ul1 >> 16) & 0xFFUL), ((ul1 >> 8) & 0xFFUL), (ul1 & 0xFFUL) $? ". ul2 = %lu.%lu.%lu.%lu", ((ul2 >> 24) & 0xFFUL), ((ul2 >> 16) & 0xFFUL), ((ul2 >> 8) & 0xFFUL), (ul2 & 0xFFUL) if (ul1 > ul2) { back = 1; } else { if (ul1 < ul2) { back = -1; } } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { $? ". IPv6" ps6 = (const struct sockaddr_in6 *)pso; back = dk4socket_compare_in6_addr3( &((ppl->data).ipv6.ad), &((ppl->data).ipv6.ma), &(ps6->sin6_addr) ); } break; #endif } } } break; default : { $? ". peer / peer" ppl = (const dk4_allowed_peer_t *)pl; ppr = (const dk4_allowed_peer_t *)pr; if (ppl->af < ppr->af) { back = -1; } else { if (ppl->af > ppr->af) { back = 1; } } if (0 == back) { switch (ppl->af) { case AF_INET : { ul1 = (ppl->data).ipv4.ad.s_addr; ul2 = (ppr->data).ipv4.ad.s_addr; ul1 = dk4socket_ntohl(ul1); ul2 = dk4socket_ntohl(ul2); if (ul1 > ul2) { back = 1; } else { if (ul1 < ul2) { back = -1; } } ul1 = (ppl->data).ipv4.ma.s_addr; ul2 = (ppr->data).ipv4.ma.s_addr; ul1 = dk4socket_ntohl(ul1); ul2 = dk4socket_ntohl(ul2); if (ul1 > ul2) { back = 1; } else { if (ul1 < ul2) { back = -1; } } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { back = dk4socket_compare_in6_addr3( &((ppl->data).ipv6.ad), NULL, &((ppr->data).ipv6.ad) ); if (0 == back) { back = dk4socket_compare_in6_addr3( &((ppl->data).ipv6.ma), NULL, &((ppr->data).ipv6.ma) ); } } break; #endif } } } break; } } else { back= 1; } } else { if (NULL != pr) { back = -1; } } $? "- dk4socket_allowed_peer_compare %d", back return back; }