Date: Thu, 28 Sep 2006 17:10:26 GMT From: Bruce M Simpson <bms@incunabulum.net> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/95277: [netinet] IP Encapsulation mask_match() returns wrong results Message-ID: <200609281710.k8SHAQlw064697@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/95277; it has been noted by GNATS. From: Bruce M Simpson <bms@incunabulum.net> To: freebsd-gnats-submit@FreeBSD.org Cc: Subject: Re: kern/95277: [netinet] IP Encapsulation mask_match() returns wrong results Date: Thu, 28 Sep 2006 18:07:34 +0100 This is a multi-part message in MIME format. --------------050007060704060608050700 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit I don't quite get this. Test case attached. --------------050007060704060608050700 Content-Type: text/x-csrc; name="maskmatch.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="maskmatch.c" /* * test case for mask_match() bug */ #include <sys/types.h> #include <sys/socket.h> #include <net/route.h> #include <netinet/in.h> #include <netinet/ip_mroute.h> #include <stddef.h> #include <stdarg.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <err.h> #include <errno.h> /* XXX */ struct encaptab { int af; int proto; struct sockaddr_storage src; struct sockaddr_storage srcmask; struct sockaddr_storage dst; struct sockaddr_storage dstmask; }; int mask_match(ep, sp, dp) const struct encaptab *ep; const struct sockaddr *sp; const struct sockaddr *dp; { struct sockaddr_storage s; struct sockaddr_storage d; int i; const u_int8_t *p, *q; u_int8_t *r; int matchlen; if (sp->sa_len > sizeof(s) || dp->sa_len > sizeof(d)) { fprintf(stderr, "lengths too big\n"); return 0; } if (sp->sa_family != ep->af || dp->sa_family != ep->af) { fprintf(stderr, "af dont match \n"); return 0; } if (sp->sa_len != ep->src.ss_len || dp->sa_len != ep->dst.ss_len) { fprintf(stderr, "lengths dont match \n"); return 0; } 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++) { 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++) { 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) { fprintf(stderr, "match\n"); return matchlen; } else { fprintf(stderr, "no match\n"); return 0; } } int main(int argc, char *argv[]) { struct encaptab e; struct sockaddr_storage ss1; struct sockaddr_storage ss2; struct sockaddr_in *psin_1; struct sockaddr_in *psin_2; int result; bzero(&e, sizeof(e)); e.af = AF_INET; e.proto = -1; psin_1 = (struct sockaddr_in *)&e.src; psin_1->sin_family = AF_INET; psin_1->sin_len = sizeof(struct sockaddr_in); psin_1->sin_addr.s_addr = inet_addr("1.2.3.4"); psin_1 = (struct sockaddr_in *)&e.srcmask; psin_1->sin_family = AF_INET; psin_1->sin_len = sizeof(struct sockaddr_in); psin_1->sin_addr.s_addr = inet_addr("255.255.255.0"); psin_1 = (struct sockaddr_in *)&e.dst; psin_1->sin_family = AF_INET; psin_1->sin_len = sizeof(struct sockaddr_in); psin_1->sin_addr.s_addr = inet_addr("4.3.2.1"); psin_1 = (struct sockaddr_in *)&e.dstmask; psin_1->sin_family = AF_INET; psin_1->sin_len = sizeof(struct sockaddr_in); psin_1->sin_addr.s_addr = inet_addr("0.0.0.0"); bzero(&ss1, sizeof(ss1)); bzero(&ss2, sizeof(ss2)); psin_1 = (struct sockaddr_in *)&ss1; psin_2 = (struct sockaddr_in *)&ss2; psin_1->sin_len = sizeof(struct sockaddr_in); psin_1->sin_family = AF_INET; psin_1->sin_addr.s_addr = inet_addr("192.168.0.1"); psin_2->sin_len = sizeof(struct sockaddr_in); psin_2->sin_family = AF_INET; psin_2->sin_addr.s_addr = inet_addr("4.3.2.2"); result = mask_match(&e, &ss1, &ss2); printf("result is %d\n", result); exit(0); } --------------050007060704060608050700--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200609281710.k8SHAQlw064697>