Check-in Number:
|
1120 | |
Date: |
2001-Oct-09 15:19:25 (local)
2001-Oct-09 13:19:25 (UTC) |
User: | rse |
Branch: | |
Comment: |
Implement new sa_addr_match() function which can be used for Access
Control List (ACL) implementations. It is capable of matching Unix
Domain and Internet Addresses (both IPv4 and IPv6) with prefix lengths. |
Tickets: |
|
Inspections: |
|
Files: |
|
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)
{
|
|
ossp-pkg/sa/sa.h 1.15 -> 1.16
--- 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);
|
|
ossp-pkg/sa/sa.pod 1.8 -> 1.9
--- 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<Socket Object Operations>:
@@ -197,6 +198,8 @@
=item sa_rc_t B<sa_addr_a2s>(sa_addr_t *I<saa>, struct sockaddr **I<sabuf>, socklen_t *I<salen>);
+=item sa_rc_t B<sa_addr_match>(sa_addr_t *I<saa1>, sa_addr_t *I<saa2>, size_t I<prefixlen>);
+
=back
=head2 Socket Object Operations
|
|