OSSP CVS Repository

ossp - Check-in [1206]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1206
Date: 2001-Oct-24 14:11:31 (local)
2001-Oct-24 12:11:31 (UTC)
User:rse
Branch:
Comment: Add support for ACLs with "IPv4-mapped IPv6 addresses" (e.g. "::ffff:1.2.3.4") as defined by RFC 2373. This is important for security reasons because these are IPv6 addresses but which have to match incoming IPv4 addresses in ACLs.
Tickets:
Inspections:
Files:
ossp-pkg/sa/sa.c      1.35 -> 1.36     32 inserted, 9 deleted

ossp-pkg/sa/sa.c 1.35 -> 1.36

--- sa.c 2001/10/24 11:43:28     1.35
+++ sa.c 2001/10/24 12:11:31     1.36
@@ -697,9 +697,12 @@
     const unsigned char *ucp1, *ucp2;
     unsigned int uc1, uc2, mask;
     size_t l1, l2;
-    int nFamily;
     int nBytes;
     int nBits;
+#ifdef AF_INET6
+    int i;
+    const unsigned char *ucp0;
+#endif
 
     /* argument sanity check(s) */
     if (saa1 == NULL || saa2 == NULL || prefixlen < -1)
@@ -709,13 +712,8 @@
     if (prefixlen == 0)
         return SA_OK;
 
-    /* short circuiting handling different families */
-    if (saa1->nFamily != saa2->nFamily)
-        return SA_ERR_MTC;
-
     /* determine address representation pointer and size */
-    nFamily = saa1->nFamily;
-    if (nFamily == AF_LOCAL) {
+    if (saa1->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;
@@ -731,13 +729,38 @@
             nBits = prefixlen;
         }
     }
-    else if (nFamily == AF_INET) {
+#ifdef AF_INET6
+    else if (   (saa1->nFamily == AF_INET  && saa2->nFamily == AF_INET6)
+             || (saa1->nFamily == AF_INET6 && saa2->nFamily == AF_INET )) {
+        /* special case of comparing a regular IPv4 address (1.2.3.4) with an 
+           "IPv4-mapped IPv6 address" (::ffff:1.2.3.4). For details see RFC 2373. */
+        if (saa1->nFamily == AF_INET6) {
+            ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr);
+            ucp2 = (const unsigned char *)&(((struct sockaddr_in  *)saa2->saBuf)->sin_addr);
+            ucp0 = ucp1;
+            ucp1 += 12;
+        }
+        else {
+            ucp1 = (const unsigned char *)&(((struct sockaddr_in  *)saa1->saBuf)->sin_addr);
+            ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr);
+            ucp0 = ucp2;
+            ucp2 += 12;
+        }
+        for (i = 0; i < 10; i++)
+            if (ucp0[i] != 0x00)
+                return SA_ERR_MTC;
+        if (!(ucp0[10] == 0xFF && ucp0[11] == 0xFF))
+            return SA_ERR_MTC;
+        nBits = 32;
+    }
+#endif
+    else if (saa1->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) {
+    else if (saa1->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;

CVSTrac 2.0.1