kern/95277: [netinet] IP Encapsulation mask_match() returns
wrong results
Bruce M Simpson
bms at incunabulum.net
Thu Sep 28 10:40:29 PDT 2006
The following reply was made to PR kern/95277; it has been noted by GNATS.
From: Bruce M Simpson <bms at incunabulum.net>
To: freebsd-gnats-submit at FreeBSD.org
Cc:
Subject: Re: kern/95277: [netinet] IP Encapsulation mask_match() returns wrong
results
Date: Thu, 28 Sep 2006 18:22:46 +0100
This is a multi-part message in MIME format.
--------------080009040700000209070407
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
I guess a patch for the desired behaviour would look something like this?
More detail needed...
--------------080009040700000209070407
Content-Type: text/x-patch;
name="maskmatch.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="maskmatch.diff"
==== //depot/user/bms/nethead/sys/netinet/ip_encap.c#1 - /home/bms/fp4/nethead/sys/netinet/ip_encap.c ====
--- /tmp/tmp.41786.0 Thu Sep 28 18:21:51 2006
+++ /home/bms/fp4/nethead/sys/netinet/ip_encap.c Thu Sep 28 18:21:09 2006
@@ -403,6 +403,7 @@
const struct sockaddr *sp;
const struct sockaddr *dp;
{
+ const int hdrlen = offsetof(struct sockaddr, sa_data);
struct sockaddr_storage s;
struct sockaddr_storage d;
int i;
@@ -419,32 +420,28 @@
matchlen = 0;
- p = (const u_int8_t *)sp;
- q = (const u_int8_t *)&ep->srcmask;
- r = (u_int8_t *)&s;
- for (i = 0 ; i < sp->sa_len; i++) {
+ p = (const u_int8_t *)&sp->sa_data;
+ q = (const u_int8_t *)&ep->srcmask + hdrlen;
+ r = (u_int8_t *)&s + hdrlen;
+ for (i = 0 ; i < sp->sa_len - hdrlen; i++) {
r[i] = p[i] & q[i];
/* XXX estimate */
matchlen += (q[i] ? 8 : 0);
}
- p = (const u_int8_t *)dp;
- q = (const u_int8_t *)&ep->dstmask;
- r = (u_int8_t *)&d;
- for (i = 0 ; i < dp->sa_len; i++) {
+ p = (const u_int8_t *)&dp->sa_data;
+ q = (const u_int8_t *)&ep->dstmask + hdrlen;
+ r = (u_int8_t *)&d + hdrlen;
+ for (i = 0 ; i < dp->sa_len - hdrlen; i++) {
r[i] = p[i] & q[i];
/* XXX rough estimate */
matchlen += (q[i] ? 8 : 0);
}
- /* need to overwrite len/family portion as we don't compare them */
- s.ss_len = sp->sa_len;
- s.ss_family = sp->sa_family;
- d.ss_len = dp->sa_len;
- d.ss_family = dp->sa_family;
-
- if (bcmp(&s, &ep->src, ep->src.ss_len) == 0 &&
- bcmp(&d, &ep->dst, ep->dst.ss_len) == 0) {
+ if (bcmp((u_int8_t *)&s + hdrlen, (const u_int8_t *)&ep->src + hdrlen,
+ ep->src.ss_len - hdrlen) == 0 &&
+ bcmp((u_int8_t *)&d + hdrlen, (const u_int8_t *)&ep->dst + hdrlen,
+ ep->dst.ss_len - hdrlen) == 0) {
return matchlen;
} else
return 0;
--------------080009040700000209070407--
More information about the freebsd-net
mailing list