Index: ossp-pkg/sa/sa.c RCS File: /v/ossp/cvs/ossp-pkg/sa/sa.c,v rcsdiff -q -kk '-r1.39' '-r1.40' -u '/v/ossp/cvs/ossp-pkg/sa/sa.c,v' 2>/dev/null --- sa.c 2001/10/31 20:42:42 1.39 +++ sa.c 2002/01/02 12:31:19 1.40 @@ -717,9 +717,11 @@ int i; const unsigned char *ucp0; #endif + unsigned int np1, np2; + int bMatchPort; /* argument sanity check(s) */ - if (saa1 == NULL || saa2 == NULL || prefixlen < -1) + if (saa1 == NULL || saa2 == NULL) return SA_ERR_ARG; /* short circuiting for wildcard matching */ @@ -728,11 +730,13 @@ /* determine address representation pointer and size */ if (saa1->nFamily == AF_LOCAL) { + np1 = 0; + np2 = 0; 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 == -1) { + if (prefixlen < 0) { if (l1 != l2) return SA_ERR_MTC; nBits = l1; @@ -749,12 +753,16 @@ /* 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) { + np1 = (unsigned int)(((struct sockaddr_in6 *)saa1->saBuf)->sin6_port); + np2 = (unsigned int)(((struct sockaddr_in *)saa2->saBuf)->sin_port); 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 { + np1 = (unsigned int)(((struct sockaddr_in *)saa1->saBuf)->sin_port); + np2 = (unsigned int)(((struct sockaddr_in6 *)saa2->saBuf)->sin6_port); ucp1 = (const unsigned char *)&(((struct sockaddr_in *)saa1->saBuf)->sin_addr); ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr); ucp0 = ucp2; @@ -769,12 +777,16 @@ } #endif else if (saa1->nFamily == AF_INET) { + np1 = (unsigned int)(((struct sockaddr_in *)saa1->saBuf)->sin_port); + np2 = (unsigned int)(((struct sockaddr_in *)saa2->saBuf)->sin_port); 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 (saa1->nFamily == AF_INET6) { + np1 = (unsigned int)(((struct sockaddr_in6 *)saa1->saBuf)->sin6_port); + np2 = (unsigned int)(((struct sockaddr_in6 *)saa2->saBuf)->sin6_port); ucp1 = (const unsigned char *)&(((struct sockaddr_in6 *)saa1->saBuf)->sin6_addr); ucp2 = (const unsigned char *)&(((struct sockaddr_in6 *)saa2->saBuf)->sin6_addr); nBits = 128; @@ -784,12 +796,15 @@ return SA_ERR_INT; /* make sure we do not compare than possible */ - if (prefixlen > nBits) + if (prefixlen > (nBits+1)) return SA_ERR_ARG; - /* support equal matching (= all bits) */ - if (prefixlen == -1) + /* support equal matching (= all bits plus optionally port) */ + if (prefixlen < 0) { + if (prefixlen < -1) + bMatchPort = TRUE; prefixlen = nBits; + } /* perform address representation comparison (assumption guaranteed by API: network byte order is used) */ @@ -806,6 +821,12 @@ if ((uc1 & mask) != (uc2 & mask)) return SA_ERR_MTC; } + + /* optionally perform additional port matching */ + if (bMatchPort) + if (np1 != np2) + return SA_ERR_MTC; + return SA_OK; }