diff -urN linux-2.6.22.17/net/Kconfig linux-2.6.22.17-mackill/net/Kconfig
--- linux-2.6.22.17/net/Kconfig	2005-06-08 15:01:05.000000000 +0200
+++ linux-2.6.22.17-mackill/net/Kconfig	2005-06-08 15:36:33.000000000 +0200
@@ -205,6 +205,15 @@
 	To compile this code as a module, choose M here: the
 	module will be called tcp_probe.
 
+config NET_MACKILL
+	tristate "Mackill proc file"
+	---help---
+	  This module will add the file /proc/net/mackill used for
+	  configuration of packet dropping for specific MAC addresses
+
+	  To compile this code as a module, choose M here: the
+	  module will be called mackill.
+
 endmenu
 
 endmenu
diff -urN linux-2.6.22.17/net/core/Makefile linux-2.6.22.17-mackill/net/core/Makefile
--- linux-2.6.22.17/net/core/Makefile	2005-03-02 08:38:26.000000000 +0100
+++ linux-2.6.22.17-mackill/net/core/Makefile	2005-06-08 15:36:33.000000000 +0200
@@ -16,3 +16,4 @@
 obj-$(CONFIG_NETPOLL) += netpoll.o
 obj-$(CONFIG_NET_DMA) += user_dma.o
 obj-$(CONFIG_FIB_RULES) += fib_rules.o
+obj-$(CONFIG_NET_MACKILL) += mackill.o
diff -urN linux-2.6.22.17/net/core/dev.c linux-2.6.22.17-mackill/net/core/dev.c
--- linux-2.6.22.17/net/core/dev.c	2005-06-08 15:01:06.000000000 +0200
+++ linux-2.6.22.17-mackill/net/core/dev.c	2005-06-08 16:01:10.658177368 +0200
@@ -156,6 +156,10 @@
 static spinlock_t net_dma_event_lock;
 #endif
 
+/* MAC-filter BEGIN */
+int (*mac_kill)(struct sk_buff *)=NULL;
+/* MAC-filter END */
+
 /*
  * The @dev_base_head list is protected by @dev_base_lock and the rtnl
  * semaphore.
@@ -1640,6 +1644,13 @@
 	struct softnet_data *queue;
 	unsigned long flags;
 
+	/* MAC-filter BEGIN */
+	if (mac_kill && (*mac_kill)(skb)) {
+		kfree_skb(skb);
+		return NET_RX_DROP;
+	}
+	/* MAC-filter END */
+
 	/* if netpoll wants it, pretend we never saw it */
 	if (netpoll_rx(skb))
 		return NET_RX_DROP;
@@ -3786,3 +3787,7 @@
 #endif
 
 EXPORT_PER_CPU_SYMBOL(softnet_data);
+
+/* MAC-filter BEGIN */
+EXPORT_SYMBOL(mac_kill);
+/* MAC-filter END */
diff -urN linux-2.6.22.17/net/core/mackill.c linux-2.6.22.17-mackill/net/core/mackill.c
--- linux-2.6.22.17/net/core/mackill.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.6.22.17-mackill/net/core/mackill.c	2005-06-08 15:36:33.000000000 +0200
@@ -0,0 +1,341 @@
+/*****************************************************************************
+ *
+ * Copyright (C) 2001 Uppsala University and Ericsson Telecom AB.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Authors: Erik Nordström, <erno3431@student.uu.se>  Initial Linux 2.4 version
+ *          Henrik Riomar <henrik.riomar@ericsson.se> Ported to Linux 2.6
+ *
+ *****************************************************************************/
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0))
+#define LINUX26
+#endif
+	
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <linux/ip.h> 
+#include <linux/if_ether.h> 
+#include <linux/proc_fs.h>
+#include <linux/ioctl.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+
+#ifndef LINUX26
+#include <asm/softirq.h>
+#endif
+
+#include <asm/uaccess.h>
+
+#define MACKILL_PROC_FS_NAME "mackill"
+
+extern int (*mac_kill)(struct sk_buff *);
+
+typedef struct mac_list_element {
+  struct list_head list;
+  int dropped;
+  unsigned char mac[ETH_ALEN];
+} mac_list_element_t;
+
+typedef struct mac_list {
+  int len;
+  struct list_head list;
+  spinlock_t lock;
+} mac_list_t;
+
+static mac_list_element_t *mac_list_find(unsigned char *mac);
+
+mac_list_t *ml = NULL;
+
+static mac_list_t *mac_list_create() {
+  mac_list_t *l;
+  
+  l = kmalloc(sizeof(mac_list_t), GFP_KERNEL);
+  if (l == NULL) {
+    return NULL;
+  }
+  l->len = 0;
+  INIT_LIST_HEAD(&l->list);
+  spin_lock_init(&l->lock);
+  return l;
+}
+static int mac_list_flush() {
+  struct list_head *i;
+  
+  spin_lock_irq(&ml->lock);
+  for (i = ml->list.prev; i != &ml->list; i = i->prev) {
+    mac_list_element_t *e = list_entry(i, mac_list_element_t, list);
+    list_del(&e->list);
+    kfree(e);
+    ml->len--;
+  }
+  spin_unlock_irq(&ml->lock);
+  return 0;
+}
+
+static int mac_list_add(unsigned char *mac) {
+  mac_list_element_t *e;
+  
+  if(mac_list_find(mac))
+    return 0;
+
+  e = kmalloc(sizeof(*e), GFP_ATOMIC);
+  if (e == NULL) {
+    printk(KERN_ERR "maclist: Failed kmalloc\n");
+    return -ENOMEM;
+  }
+  /* Set MAC address in list element.. */
+  memcpy(e->mac, mac, ETH_ALEN);
+  e->dropped = 0;
+
+  spin_lock_irq(&ml->lock);
+  list_add(&e->list, &ml->list);
+  ml->len++;
+  spin_unlock_irq(&ml->lock);
+  
+  return 0;
+}
+
+static int mac_list_remove(unsigned char *mac) {
+  struct list_head *i;
+  
+  spin_lock_irq(&ml->lock);
+  for (i = ml->list.prev; i != &ml->list; i = i->prev) {
+    mac_list_element_t *e = list_entry(i, mac_list_element_t, list);
+    
+    if (memcmp(e->mac, mac, ETH_ALEN) == 0) {
+      list_del(&e->list);
+      kfree(e);
+      ml->len--;
+      spin_unlock_irq(&ml->lock);
+      return 1;
+    }
+  }
+  spin_unlock_irq(&ml->lock);
+  return 0;
+}
+
+static mac_list_element_t *mac_list_find(unsigned char *mac) {
+  struct list_head *i;
+  
+  spin_lock_irq(&ml->lock);
+  for (i = ml->list.prev; i != &ml->list; i = i->prev) {
+    mac_list_element_t *e = list_entry(i, mac_list_element_t, list);
+    
+    if (memcmp(e->mac, mac, ETH_ALEN) == 0) {
+      spin_unlock_irq(&ml->lock);
+      return e;
+    }
+  }
+  spin_unlock_irq(&ml->lock);
+  return NULL;
+}
+
+static int is_digit(char c) {
+  if(c >= '0' && c <= '9')
+    return 1;
+  else
+    return 0;
+} 
+
+/* Originally from wireless tools: */
+static int mac_to_bin(char *bufp, unsigned char *mac) {
+  char c, *orig;
+  int i, val;
+
+  i = 0;
+  orig = bufp;
+  while((*bufp != '\0') && (i < ETH_ALEN)) {
+    val = 0;
+    c = *bufp++;
+    if (is_digit(c)) val = c - '0';
+    else if (c >= 'a' && c <= 'f') val = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'F') val = c - 'A' + 10;
+    else 
+      return(-1);
+       
+    val <<= 4;
+    c = *bufp++;
+    if (is_digit(c)) val |= c - '0';
+    else if (c >= 'a' && c <= 'f') val |= c - 'a' + 10;
+    else if (c >= 'A' && c <= 'F') val |= c - 'A' + 10;
+    else 
+      return(-1);
+	
+    *mac++ = (unsigned char) (val & 0377);
+    i++;
+
+    if (*bufp == ':') {
+      if (i == ETH_ALEN)
+	; /* nothing */
+      bufp++;
+    }
+  }
+  
+  /* That's it.  Any trailing junk? */
+  if ((i == ETH_ALEN) && (*bufp != '\0'))
+    return(-1);
+
+  return(0);
+}
+
+static int mackill_write_proc(struct file* file, const char* buffer, 
+			      unsigned long count, void* data) {
+  char cmd[20];
+  unsigned char mac[ETH_ALEN];
+  int ret = 0;
+  
+  memset(cmd, '\0', 20);
+  
+  /* We only accept either a '0' or '[+|-]<MAC address>' */
+  if(!(count == 19 || (count == 2))) {
+     return -EINVAL;
+  }
+  /* Don't read the '\n' or '\0' character... */
+  if(copy_from_user(cmd, buffer, count-1))
+    return -EFAULT;
+
+  switch(cmd[0]) {
+  case '-':
+    ret = mac_to_bin(cmd+1, mac);
+    if(ret < 0)
+      return -EINVAL;
+    mac_list_add(mac);
+    break;
+  case '+':
+    ret = mac_to_bin(cmd+1, mac);
+    if(ret < 0)
+      return -EINVAL;
+    mac_list_remove(mac);
+    break;
+  case '0':
+    if(count == 2) {
+     /*   printk("mackill: flushing list!\n"); */
+      mac_list_flush();
+    } else {
+      /*  printk("mackill: Unknown proc command!\n"); */
+      return -EINVAL;
+    }
+    break;
+  default:
+    /*   printk("mackill: Unknown proc command!\n"); */
+    return -EINVAL;
+  }
+  return count;
+}
+
+static int mackill_read_proc(char *buffer, char **start, 
+			     off_t offset, int length, int* eof, void* data) {
+  struct list_head *i;
+  int len;
+  
+  len = sprintf(buffer, "HWadrr            Dropped packets\n");
+  
+  spin_lock_irq(&ml->lock); 
+  for (i = ml->list.prev; i != &ml->list; i = i->prev) {
+    mac_list_element_t *e = list_entry(i, mac_list_element_t, list);
+    len += sprintf(buffer+len, "%02X:%02X:%02X:%02X:%02X:%02X %u\n", 
+		   (e->mac[0] & 0xFF), (e->mac[1] & 0xFF), (e->mac[2] & 0xFF),
+		   (e->mac[3] & 0xFF), (e->mac[4] & 0xFF), (e->mac[5] & 0xFF), 
+		   e->dropped);
+  }
+  spin_unlock_irq(&ml->lock); 
+  
+  *start = buffer + offset;
+  len -= offset;
+  if (len > length)
+    len = length;
+  else if (len < 0)
+    len = 0;
+  return len;
+}
+
+/* This function is called from withín net/core/dev.c (
+   net_rx_action()). If 1 is returned the packet is dropped, if 0 is
+   returned the packet goes through normal processing... */
+int __mac_kill(struct sk_buff *skb) {
+  struct ethhdr *eth_h;
+  mac_list_element_t *e;
+ 
+  if(ml->len == 0)
+    return 0;
+
+  eth_h = eth_hdr(skb);
+
+  
+  if((e = mac_list_find(eth_h->h_source)) != NULL) {
+    spin_lock_irq(&ml->lock);
+    e->dropped++;
+    spin_unlock_irq(&ml->lock);
+    return 1;
+  }
+
+  return 0;
+}
+
+static int __init init(void) {
+  struct proc_dir_entry *proc;
+
+  #ifndef LINUX26
+  /* Obsolete in 2.6 */
+  EXPORT_NO_SYMBOLS;
+  #endif 
+
+  ml = mac_list_create();
+  
+  if(ml == NULL) {
+    printk(KERN_ERR "mackill: Could not create MAC list\n");
+    return 0;
+  }
+
+  /* Create proc file */
+  proc = create_proc_entry(MACKILL_PROC_FS_NAME, S_IRUGO | S_IWUSR, proc_net);
+  if (proc) {
+    proc->owner = THIS_MODULE;
+    proc->read_proc = mackill_read_proc;
+    proc->write_proc = mackill_write_proc;
+  } else {
+    kfree(ml);
+    return -ENOMEM;
+  }
+  /* Enable the mac_kill hook */
+  mac_kill = __mac_kill; 
+  return 0;
+}
+
+static void __exit fini(void) {
+  proc_net_remove(MACKILL_PROC_FS_NAME);
+  mac_list_flush();
+  kfree(ml);
+  /* Un-hook mac_kill function */
+  mac_kill = NULL; 
+  return;
+}
+
+
+MODULE_DESCRIPTION("MAC-kill by Erik Nordström - APE project, Uppsala University");
+MODULE_AUTHOR("Erik Nordström");
+MODULE_LICENSE( "GPL" );
+
+module_init(init);
+module_exit(fini);
