All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Heinz <creatix@hipac.org>
To: netfilter-devel@lists.netfilter.org
Subject: [PATCH] mac match extension
Date: Tue, 15 Oct 2002 21:44:03 +0200	[thread overview]
Message-ID: <3DAC7003.6000900@hipac.org> (raw)

[-- Attachment #1: Type: text/plain, Size: 501 bytes --]

Hi

Some days ago, Dan Searle asked for a mac match extension where it
should be possible to apply arbitrary masks to the mac address:
http://msgs.securepoint.com/cgi-bin/get/netfilter-0210/170.html

I extended the mac matching code and attached the patch to this
e-mail.

Although I think that this feature will be used very rarely it
might be helpful to have it in patch-o-matic. Anyway, it's your
decision. If you don't like it or believe that it is not useful
throw it away ;-)


Regards,

Thomas

[-- Attachment #2: ipt_mac-mask.patch --]
[-- Type: text/plain, Size: 1618 bytes --]

--- kernel-source-2.4.19/include/linux/netfilter_ipv4/ipt_mac.h	2002-10-15 17:16:09.000000000 +0200
+++ kernel-source-2.4.19.new/include/linux/netfilter_ipv4/ipt_mac.h	2002-10-15 18:30:44.000000000 +0200
@@ -2,7 +2,9 @@
 #define _IPT_MAC_H
 
 struct ipt_mac_info {
-    unsigned char srcaddr[ETH_ALEN];
-    int invert;
+	unsigned char srcaddr[ETH_ALEN];
+	unsigned char mask[ETH_ALEN];
+	int is_mask;
+	int invert;
 };
 #endif /*_IPT_MAC_H*/
--- kernel-source-2.4.19/net/ipv4/netfilter/ipt_mac.c	2002-10-15 20:48:39.000000000 +0200
+++ kernel-source-2.4.19.new/net/ipv4/netfilter/ipt_mac.c	2002-10-15 20:49:02.000000000 +0200
@@ -18,12 +18,30 @@
 {
     const struct ipt_mac_info *info = matchinfo;
 
-    /* Is mac pointer valid? */
-    return (skb->mac.raw >= skb->head
-	    && (skb->mac.raw + ETH_HLEN) <= skb->data
-	    /* If so, compare... */
-	    && ((memcmp(skb->mac.ethernet->h_source, info->srcaddr, ETH_ALEN)
+    if (info->is_mask) {
+	    if (skb->mac.raw >= skb->head &&
+		(skb->mac.raw + ETH_HLEN) <= skb->data) {
+		    int i;
+		    for (i = 0; i < ETH_HLEN; i++) {
+			    if ((skb->mac.ethernet->h_source[i] & 
+				 info->mask[i]) != 
+				(info->srcaddr[i] & info->mask[i])) {
+				    return info->invert;
+			    }
+		    }
+		    return !info->invert;
+	    } else {
+		    return 0;
+	    }
+    } else {
+	    /* Is mac pointer valid? */
+	    return (skb->mac.raw >= skb->head
+		    && (skb->mac.raw + ETH_HLEN) <= skb->data
+		    /* If so, compare... */
+		    && ((memcmp(skb->mac.ethernet->h_source,
+				info->srcaddr, ETH_ALEN)
 		== 0) ^ info->invert));
+    }
 }
 
 static int

[-- Attachment #3: ipt_mac-mask.patch.help --]
[-- Type: text/plain, Size: 436 bytes --]

Author: Thomas Heinz <creatix@hipac.org>
Status: should work :-)

This patch extends the mac match in a way that arbitrary masks can be applied.

Here is an example:
# iptables -A INPUT -m mac --mac-source 12:34:56:78:90:AB --mac-mask FF:FF:70:07:FF:FF -j REJECT

***** WARNING ***** This patch also patch the userspace directory which means that
                    you have to recompile and reinstall the iptables package after that.

[-- Attachment #4: ipt_mac-mask.patch.userspace --]
[-- Type: text/plain, Size: 3387 bytes --]

--- userspace/extensions/libipt_mac.c~	2002-10-15 17:12:27.000000000 +0200
+++ userspace/extensions/libipt_mac.c	2002-10-15 20:52:33.000000000 +0200
@@ -20,11 +20,14 @@
 "MAC v%s options:\n"
 " --mac-source [!] XX:XX:XX:XX:XX:XX\n"
 "				Match source MAC address\n"
+" --mac-mask XX:XX:XX:XX:XX:XX\n"
+"				Apply mask to source MAC address\n"
 "\n", IPTABLES_VERSION);
 }
 
 static struct option opts[] = {
 	{ "mac-source", 1, 0, '1' },
+	{ "mac-mask", 1, 0, '2' },
 	{0}
 };
 
@@ -37,12 +40,13 @@
 }
 
 static void
-parse_mac(const char *mac, struct ipt_mac_info *info)
+parse_mac(const char *mac, unsigned char macaddress[ETH_ALEN],
+	  char *errmsg)
 {
 	unsigned int i = 0;
 
 	if (strlen(mac) != ETH_ALEN*3-1)
-		exit_error(PARAMETER_PROBLEM, "Bad mac address `%s'", mac);
+		exit_error(PARAMETER_PROBLEM, "%s `%s'", errmsg, mac);
 
 	for (i = 0; i < ETH_ALEN; i++) {
 		long number;
@@ -53,10 +57,10 @@
 		if (end == mac + i*3 + 2
 		    && number >= 0
 		    && number <= 255)
-			info->srcaddr[i] = number;
+			macaddress[i] = number;
 		else
 			exit_error(PARAMETER_PROBLEM,
-				   "Bad mac address `%s'", mac);
+				   "%s `%s'", errmsg, mac);
 	}
 }
 
@@ -69,15 +73,40 @@
       struct ipt_entry_match **match)
 {
 	struct ipt_mac_info *macinfo = (struct ipt_mac_info *)(*match)->data;
+	static int mask_parsed = 0;
+	int i;
 
 	switch (c) {
 	case '1':
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_mac(argv[optind-1], macinfo);
+		parse_mac(argv[optind-1], macinfo->srcaddr, "Bad mac address");
 		if (invert)
 			macinfo->invert = 1;
+		if (!mask_parsed) {
+			macinfo->is_mask = 0;
+		} else if (macinfo->is_mask) {
+			for (i = 0; i < ETH_ALEN; i++)
+				macinfo->srcaddr[i] &= macinfo->mask[i];
+		}
 		*flags = 1;
 		break;
+		
+	case '2':
+		check_inverse(optarg, &invert, &optind, 0);
+		if (invert)
+			exit_error(PARAMETER_PROBLEM,
+				   "mac-mask: unexpected `!'");
+		parse_mac(argv[optind-1], macinfo->mask,
+			  "Bad mac mask");
+		macinfo->is_mask = 0;
+		mask_parsed = 1;
+		for (i = 0; i < ETH_ALEN; i++) {
+			macinfo->srcaddr[i] &= macinfo->mask[i];
+			if (macinfo->mask[i] != 0xFF) {
+				macinfo->is_mask = 1;
+			}
+		}
+		break;
 
 	default:
 		return 0;
@@ -86,13 +115,20 @@
 	return 1;
 }
 
-static void print_mac(unsigned char macaddress[ETH_ALEN], int invert)
+static void print_mac(unsigned char macaddress[ETH_ALEN],
+		      unsigned char macmask[ETH_ALEN],
+		      int invert)
 {
 	unsigned int i;
-
+	
 	printf("%s%02X", invert ? "! " : "", macaddress[0]);
 	for (i = 1; i < ETH_ALEN; i++)
 		printf(":%02X", macaddress[i]);
+	if (macmask != NULL) {
+		printf("/%02X", macmask[0]);
+		for (i = 1; i < ETH_ALEN; i++)
+			printf(":%02X", macmask[i]);
+	}
 	printf(" ");
 }
 
@@ -112,6 +148,8 @@
 {
 	printf("MAC ");
 	print_mac(((struct ipt_mac_info *)match->data)->srcaddr,
+		  ((struct ipt_mac_info *)match->data)->is_mask ? 
+		  ((struct ipt_mac_info *)match->data)->mask : NULL,
 		  ((struct ipt_mac_info *)match->data)->invert);
 }
 
@@ -120,7 +158,11 @@
 {
 	printf("--mac-source ");
 	print_mac(((struct ipt_mac_info *)match->data)->srcaddr,
-		  ((struct ipt_mac_info *)match->data)->invert);
+		  NULL, ((struct ipt_mac_info *)match->data)->invert);
+	if (((struct ipt_mac_info *)match->data)->is_mask) {
+		printf("--mac-mask ");
+		print_mac(((struct ipt_mac_info *)match->data)->mask, NULL, 0);
+	}
 }
 
 static

                 reply	other threads:[~2002-10-15 19:44 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3DAC7003.6000900@hipac.org \
    --to=creatix@hipac.org \
    --cc=netfilter-devel@lists.netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.