diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk4sock28.ctr |
Initial commit
Diffstat (limited to 'support/dktools/dk4sock28.ctr')
-rw-r--r-- | support/dktools/dk4sock28.ctr | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/support/dktools/dk4sock28.ctr b/support/dktools/dk4sock28.ctr new file mode 100644 index 0000000000..e54365d4be --- /dev/null +++ b/support/dktools/dk4sock28.ctr @@ -0,0 +1,205 @@ +%% 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 l<r, l==r or l>r. +*/ +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; +} + |