bin/80913: [patch] /sbin/ipfw2 silently discards MAC addr arg
with improper characters
Andrey V. Elsukov
bu7cher at yandex.ru
Thu May 3 04:40:11 UTC 2007
The following reply was made to PR bin/80913; it has been noted by GNATS.
From: "Andrey V. Elsukov" <bu7cher at yandex.ru>
To: bug-followup at FreeBSD.org, gfb at vta.com,
Maxim Konovalov <maxim at FreeBSD.org>
Cc:
Subject: Re: bin/80913: [patch] /sbin/ipfw2 silently discards MAC addr arg
with improper characters
Date: Thu, 03 May 2007 08:38:01 +0400
This is a multi-part message in MIME format.
--------------080506050005050409040606
Content-Type: text/plain; charset=KOI8-R; format=flowed
Content-Transfer-Encoding: 7bit
Hi, can you test the following patch? (for CURRENT or RELENG_6)
--
WBR, Andrey V. Elsukov
--------------080506050005050409040606
Content-Type: text/plain;
name="ipfw2.c.diff.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="ipfw2.c.diff.txt"
--- src/sbin/ipfw/ipfw2.c Wed Apr 18 18:03:08 2007
+++ src/sbin/ipfw/ipfw2.c Wed May 2 20:05:20 2007
@@ -47,6 +47,7 @@
#include <unistd.h>
#include <fcntl.h>
+#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/pfvar.h>
@@ -4374,36 +4375,51 @@
}
static void
-get_mac_addr_mask(char *p, uint8_t *addr, uint8_t *mask)
+get_mac_addr_mask(const char *p, uint8_t *addr, uint8_t *mask)
{
int i, l;
+ char *ap, *ptr, *optr;
+ struct ether_addr *mac;
+ const char *macset = "0123456789abcdefABCDEF:";
- for (i=0; i<6; i++)
+ if (strcmp(p, "any") == 0) {
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
addr[i] = mask[i] = 0;
- if (strcmp(p, "any") == 0)
return;
+ }
- for (i=0; *p && i<6;i++, p++) {
- addr[i] = strtol(p, &p, 16);
- if (*p != ':') /* we start with the mask */
- break;
- }
- if (*p == '/') { /* mask len */
- l = strtol(p+1, &p, 0);
- for (i=0; l>0; l -=8, i++)
- mask[i] = (l >=8) ? 0xff : (~0) << (8-l);
- } else if (*p == '&') { /* mask */
- for (i=0, p++; *p && i<6;i++, p++) {
- mask[i] = strtol(p, &p, 16);
- if (*p != ':')
- break;
+ optr = ptr = strdup(p);
+ if ((ap = strsep(&ptr, "&/")) != NULL && *ap != 0) {
+ l = strlen(ap);
+ if (strspn(ap, macset) != l || (mac = ether_aton(ap)) == NULL)
+ errx(EX_DATAERR, "Incorrect MAC address");
+ bcopy(mac, addr, ETHER_ADDR_LEN);
+ } else
+ errx(EX_DATAERR, "Incorrect MAC address");
+
+ if (ptr != NULL) { /* we have mask? */
+ if (p[ptr - optr - 1] == '/') { /* mask len */
+ l = strtol(ptr, &ap, 10);
+ if (*ap != 0 || l > ETHER_ADDR_LEN * 8 || l < 0)
+ errx(EX_DATAERR, "Incorrect mask length");
+ for (i = 0; l > 0 && i < ETHER_ADDR_LEN; l -=8, i++)
+ mask[i] = (l >= 8) ? 0xff: (~0) << (8 - l);
+ } else { /* mask */
+ l = strlen(ptr);
+ if (strspn(ptr, macset) != l ||
+ (mac = ether_aton(ptr)) == NULL)
+ errx(EX_DATAERR, "Incorrect mask");
+ bcopy(mac, mask, ETHER_ADDR_LEN);
}
- } else if (*p == '\0') {
- for (i=0; i<6; i++)
+ } else { /* default mask: ff:ff:ff:ff:ff:ff */
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
mask[i] = 0xff;
}
- for (i=0; i<6; i++)
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++)
addr[i] &= mask[i];
+
+ free(optr);
}
/*
--------------080506050005050409040606--
More information about the freebsd-ipfw
mailing list