Index: ossp-pkg/sa/sa.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.c,v rcsdiff -q -kk '-r1.14' '-r1.15' -u '/v/ossp/cvs/ossp-pkg/sa/sa.c,v' 2>/dev/null --- sa.c 2001/10/08 15:15:25 1.14 +++ sa.c 2001/10/09 13:19:25 1.15 @@ -706,6 +706,82 @@ return SA_OK; } +sa_rc_t sa_addr_match(sa_addr_t *saa1, sa_addr_t *saa2, size_t prefixlen) +{ + const unsigned char *ucp1, *ucp2; + unsigned int uc1, uc2, mask; + size_t l1, l2; + int nFamily; + int nBytes; + int nBits; + + /* argument sanity check(s) */ + if (saa1 == NULL || saa2 == NULL) + return SA_ERR_ARG; + + /* match short circuiting */ + if (saa1->nFamily != saa2->nFamily) + return SA_ERR_MTC; + + /* determine address representation pointer and size */ + nFamily = saa1->nFamily; + if (nFamily == AF_LOCAL) { + ucp1 = (const unsigned char *)(((struct sockaddr_un *)saa1->saBuf)->sun_path); + ucp2 = (const unsigned char *)(((struct sockaddr_un *)saa2->saBuf)->sun_path); + l1 = strlen(((struct sockaddr_un *)saa1->saBuf)->sun_path) * 8; + l2 = strlen(((struct sockaddr_un *)saa2->saBuf)->sun_path) * 8; + if (prefixlen == 0) { + if (l1 != l2) + return SA_ERR_MTC; + nBits = l1; + } + else { + if (l1 < prefixlen || l2 < prefixlen) + return SA_ERR_MTC; + nBits = prefixlen; + } + } + else if (nFamily == AF_INET) { + ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr); + ucp2 = (const unsigned char *)&(((struct sockaddr_in *)saa2->saBuf)->sin_addr); + nBits = 32; + } +#ifdef AF_INET6 + else if (nFamily == AF_INET6) { + ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr); + ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr); + nBits = 128; +#endif + } + else + return SA_ERR_INT; + + /* make sure we do not compare than possible */ + if (prefixlen > nBits) + return SA_ERR_ARG; + + /* support equal matching (= all bits) */ + if (prefixlen == 0) + prefixlen = nBits; + + /* perform address representation comparison + (assumption guaranteed by API: network byte order is used) */ + nBytes = (prefixlen / 8); + nBits = (prefixlen % 8); + if (nBytes > 0) { + if (memcmp(ucp1, ucp1, nBytes) != 0) + return SA_ERR_MTC; + } + if (nBits > 0) { + uc1 = ucp1[nBytes]; + uc2 = ucp2[nBytes]; + mask = (0xFF << (8-nBits)) & 0xFF; + if ((uc1 & mask) != (uc2 & mask)) + return SA_ERR_MTC; + } + return SA_OK; +} + /* internal lazy/delayed initialization of underlying socket */ static sa_rc_t sa_socket_init(sa_t *sa, int nFamily) { Index: ossp-pkg/sa/sa.h RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.h,v rcsdiff -q -kk '-r1.15' '-r1.16' -u '/v/ossp/cvs/ossp-pkg/sa/sa.h,v' 2>/dev/null --- sa.h 2001/10/08 15:01:26 1.15 +++ sa.h 2001/10/09 13:19:25 1.16 @@ -110,6 +110,7 @@ SA_ERR_MEM, /* out of memory */ SA_ERR_SYS, /* system error (see errno) */ SA_ERR_EOF, /* end of file/socket communication */ + SA_ERR_MTC, /* error in match */ SA_ERR_INT /* internal error */ } sa_rc_t; @@ -147,6 +148,7 @@ sa_rc_t sa_addr_s2a (sa_addr_t *saa, const struct sockaddr *sabuf, socklen_t salen); sa_rc_t sa_addr_a2u (sa_addr_t *saa, char **uri); sa_rc_t sa_addr_a2s (sa_addr_t *saa, struct sockaddr **sabuf, socklen_t *salen); +sa_rc_t sa_addr_match (sa_addr_t *saa1, sa_addr_t *saa2, size_t prefixlen); /* socket object operations */ sa_rc_t sa_create (sa_t **sa); Index: ossp-pkg/sa/sa.pod RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.pod,v rcsdiff -q -kk '-r1.8' '-r1.9' -u '/v/ossp/cvs/ossp-pkg/sa/sa.pod,v' 2>/dev/null --- sa.pod 2001/10/08 10:03:54 1.8 +++ sa.pod 2001/10/09 13:19:25 1.9 @@ -54,7 +54,8 @@ sa_addr_u2a, sa_addr_s2a, sa_addr_a2u, -sa_addr_a2s. +sa_addr_a2s, +sa_addr_match. =item B: @@ -197,6 +198,8 @@ =item sa_rc_t B(sa_addr_t *I, struct sockaddr **I, socklen_t *I); +=item sa_rc_t B(sa_addr_t *I, sa_addr_t *I, size_t I); + =back =head2 Socket Object Operations