ossp-pkg/sa/sa.c 1.14 -> 1.15
--- 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)
{
|
|