reply target

Grzegorz Borowiak <[email protected]>
Newsgroups gmane.linux.network.bridge.ebtables.devel
Message-ID <[email protected]>
And now, for something completely different...
It's...

Patches for reply target for both kernel and userspace utility.
This target allows instant reply for ARP requests, with arbitrary MAC
addresss. You write:

ebtables -t nat -A PREROUTING -p ARP --arp-ip-dst 192.168.1.2 \
	-j reply --reply-mac 00:47:72:7a:65:73

and since now any ARP request "who-has 192.168.1.2" is replied
with an ARP-reply frame "192.168.1.2 is-at 00:47:72:7a:65:73".

The target returns EBT_DROP if this was an ARP-request frame or
EBT_CONTINUE otherwise (i.e. if it was not an ARP-request frame, or if it
was not even an ARP frame).

Target should be placed in nat table of PREROUTING chain or in broute
table of BROUTE chain.

I have alpha-tested it. It's nice. Works for me.

This target is useful for emulating non-existent hosts (along with
redirect and snat targets) or for ARP-proxying, for example in VPNs.

Coming soon:

Two large targets for total snatting/dnatting IP and ARP frames by their
src/dst IP addresses in opaque way. These target will carry a 256-entry
table which will tell what IP address should be mapped onto what MAC
address. This will be simply faster than inserting a sequence of rules
with snat and dnat targets, because computational complexity of the former
will be O(1) and for the latter is O(n), where n is the number of IP
addresses to be natted. Thus, it will be useful in cases where we have to
nat large number of different addresses and we have fast link and slow
machine (like I have :-)).

-- 
Grzesław
ebt-user-reply.patch (text/plain, 3.8 KB)
diff -Naur ebtables-v2.0.5/extensions/ebt_reply.c ebtables-v2.0.5-with-reply/extensions/ebt_reply.c
--- ebtables-v2.0.5/extensions/ebt_reply.c	1970-01-01 01:00:00.000000000 +0100
+++ ebtables-v2.0.5-with-reply/extensions/ebt_reply.c	2003-08-07 19:39:59.000000000 +0200
@@ -0,0 +1,103 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netinet/ether.h>
+#include <getopt.h>
+#include "../include/ebtables_u.h"
+#include <linux/netfilter_bridge/ebt_reply.h>
+
+static int mac_supplied;
+
+#define REPLY_MAC '2'
+static struct option opts[] =
+{
+	{ "reply-mac" , required_argument, 0, REPLY_MAC },
+	{ 0 }
+};
+
+static void print_help()
+{
+	printf(
+	"reply target options:\n"
+	" --reply-mac XX:XX:XX:XX:XX:XX : source MAC of generated reply\n");
+}
+
+static void init(struct ebt_entry_target *target)
+{
+	struct ebt_reply_info *replyinfo =
+	   (struct ebt_reply_info *)target->data;
+
+	memset(replyinfo->mac, 0, ETH_ALEN);
+	mac_supplied = 0;
+}
+
+#define OPT_REPLY_MAC   0x01
+static int parse(int c, char **argv, int argc,
+   const struct ebt_u_entry *entry, unsigned int *flags,
+   struct ebt_entry_target **target)
+{
+	struct ebt_reply_info *replyinfo =
+	   (struct ebt_reply_info *)(*target)->data;
+	struct ether_addr *addr;
+	
+	switch (c) {
+	case REPLY_MAC:
+		if (!(addr = ether_aton(optarg)))
+			print_error("Problem with specified "
+			            "--reply-mac mac");
+		memcpy(replyinfo->mac, addr, ETH_ALEN);
+		mac_supplied = 1;
+		break;
+	default:
+		return 0;
+	}
+	return 1;
+}
+
+static void final_check(const struct ebt_u_entry *entry,
+   const struct ebt_entry_target *target, const char *name,
+   unsigned int hookmask, unsigned int time)
+{
+	if (time == 0 && mac_supplied == 0)
+		print_error("No reply mac supplied");
+}
+
+static void print(const struct ebt_u_entry *entry,
+   const struct ebt_entry_target *target)
+{
+	struct ebt_reply_info *replyinfo =
+	   (struct ebt_reply_info *)target->data;
+	
+	printf("--reply-mac ");
+	printf("%s", ether_ntoa((struct ether_addr *)replyinfo->mac));
+}
+
+static int compare(const struct ebt_entry_target *t1,
+   const struct ebt_entry_target *t2)
+{
+	struct ebt_reply_info *replyinfo1 =
+	   (struct ebt_reply_info *)t1->data;
+	struct ebt_reply_info *replyinfo2 =
+	   (struct ebt_reply_info *)t2->data;
+
+	return memcmp(replyinfo1->mac, replyinfo2->mac, ETH_ALEN) == 0;
+}
+
+static struct ebt_u_target reply_target =
+{
+	EBT_REPLY_TARGET,
+	sizeof(struct ebt_reply_info),
+	print_help,
+	init,
+	parse,
+	final_check,
+	print,
+	compare,
+	opts
+};
+
+static void _init(void) __attribute__ ((constructor));
+static void _init(void)
+{
+	register_target(&reply_target);
+}
diff -Naur ebtables-v2.0.5/extensions/Makefile ebtables-v2.0.5-with-reply/extensions/Makefile
--- ebtables-v2.0.5/extensions/Makefile	2003-07-26 14:04:08.000000000 +0200
+++ ebtables-v2.0.5-with-reply/extensions/Makefile	2003-08-07 19:35:46.000000000 +0200
@@ -1,6 +1,7 @@
 #! /usr/bin/make
 
 EXT_FUNC+=802_3 nat arp ip standard log redirect vlan mark_m mark pkttype stp
+EXT_FUNC+=reply
 EXT_TABLES+=filter nat broute
 EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o)
 EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o)
diff -Naur ebtables-v2.0.5/include/linux/netfilter_bridge/ebt_reply.h ebtables-v2.0.5-with-reply/include/linux/netfilter_bridge/ebt_reply.h
--- ebtables-v2.0.5/include/linux/netfilter_bridge/ebt_reply.h	1970-01-01 01:00:00.000000000 +0100
+++ ebtables-v2.0.5-with-reply/include/linux/netfilter_bridge/ebt_reply.h	2003-08-07 20:40:00.000000000 +0200
@@ -0,0 +1,11 @@
+#ifndef __LINUX_BRIDGE_EBT_REPLY_H
+#define __LINUX_BRIDGE_EBT_REPLY_H
+
+struct ebt_reply_info
+{
+	unsigned char mac[ETH_ALEN];
+	char pad[2];
+};
+#define EBT_REPLY_TARGET "reply"
+
+#endif
ebt-kernel-reply.patch (text/plain, 4.5 KB)
diff -Naur linux-2.4.21-ebt/include/linux/netfilter_bridge/ebt_reply.h linux-2.4.21-ebt-with-reply/include/linux/netfilter_bridge/ebt_reply.h
--- linux-2.4.21-ebt/include/linux/netfilter_bridge/ebt_reply.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21-ebt-with-reply/include/linux/netfilter_bridge/ebt_reply.h	2003-08-07 20:55:07.000000000 +0200
@@ -0,0 +1,11 @@
+#ifndef __LINUX_BRIDGE_EBT_REPLY_H
+#define __LINUX_BRIDGE_EBT_REPLY_H
+
+struct ebt_reply_info
+{
+	unsigned char mac[ETH_ALEN];
+	char pad[2];
+};
+#define EBT_REPLY_TARGET "reply"
+
+#endif
diff -Naur linux-2.4.21-ebt/net/bridge/netfilter/Config.in linux-2.4.21-ebt-with-reply/net/bridge/netfilter/Config.in
--- linux-2.4.21-ebt/net/bridge/netfilter/Config.in	2003-08-07 20:51:03.000000000 +0200
+++ linux-2.4.21-ebt-with-reply/net/bridge/netfilter/Config.in	2003-08-07 20:54:29.000000000 +0200
@@ -17,3 +17,4 @@
 dep_tristate '    ebt: dnat target support' CONFIG_BRIDGE_EBT_DNAT $CONFIG_BRIDGE_NF_EBTABLES
 dep_tristate '    ebt: redirect target support' CONFIG_BRIDGE_EBT_REDIRECT $CONFIG_BRIDGE_NF_EBTABLES
 dep_tristate '    ebt: mark target support' CONFIG_BRIDGE_EBT_MARK_T $CONFIG_BRIDGE_NF_EBTABLES
+dep_tristate '    ebt: reply target support (EXPERIMENTAL)' CONFIG_BRIDGE_EBT_REPLY $CONFIG_BRIDGE_NF_EBTABLES
diff -Naur linux-2.4.21-ebt/net/bridge/netfilter/ebt_reply.c linux-2.4.21-ebt-with-reply/net/bridge/netfilter/ebt_reply.c
--- linux-2.4.21-ebt/net/bridge/netfilter/ebt_reply.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21-ebt-with-reply/net/bridge/netfilter/ebt_reply.c	2003-08-07 20:53:09.000000000 +0200
@@ -0,0 +1,95 @@
+/*
+ *  ebt_reply
+ *
+ *	Authors:
+ *	Grzegorz Borowiak <[email protected]>
+ *
+ *  August, 2003
+ *
+ */
+
+#include <linux/netfilter_bridge/ebtables.h>
+#include <linux/netfilter_bridge/ebt_reply.h>
+#include <linux/if_arp.h>
+#include <linux/module.h>
+
+static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr,
+   const struct net_device *in, const struct net_device *out,
+   const void *data, unsigned int datalen)
+{
+	struct ebt_reply_info *info = (struct ebt_reply_info *)data;
+	struct ethhdr *e = (**pskb).mac.ethernet;
+
+	if (e->h_proto != __constant_htons(ETH_P_ARP))
+		return EBT_CONTINUE;
+	else {
+		struct arphdr *ah;
+		unsigned char *sha, *tha, *arp_ptr;
+		u32 sip, tip;
+		struct net_device *dev;
+		
+		ah = (**pskb).nh.arph;
+		if (ah->ar_op != __constant_htons(ARPOP_REQUEST)) {
+			printk(KERN_WARNING "%d\n", ah->ar_op);
+			return EBT_CONTINUE;
+		}
+		
+		dev = (**pskb).real_dev;
+		if (!dev) {
+			dev = (**pskb).dev;
+		}
+		if (!dev) {
+			printk(KERN_WARNING "ebt_reply: real_dev == NULL && dev == NULL\n");
+			return EBT_CONTINUE;
+		}
+		
+		arp_ptr=(unsigned char *)(ah+1);
+	
+		sha=arp_ptr;
+		arp_ptr += dev->addr_len;
+		memcpy(&sip, arp_ptr, 4);
+		arp_ptr += 4;
+		tha=arp_ptr;
+		arp_ptr += dev->addr_len;
+		memcpy(&tip, arp_ptr, 4);
+
+		arp_send(ARPOP_REPLY, ETH_P_ARP, sip, dev, tip, sha, info->mac, sha);
+		
+		return EBT_DROP;
+	}
+}
+
+static int ebt_target_reply_check(const char *tablename, unsigned int hookmask,
+   const struct ebt_entry *e, void *data, unsigned int datalen)
+{
+	struct ebt_reply_info *info = (struct ebt_reply_info *)data;
+	CLEAR_BASE_CHAIN_BIT;
+	if ( (strcmp(tablename, "nat") ||
+	   (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) &&
+	   (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) )
+		return -EINVAL;
+	if (datalen != sizeof(struct ebt_reply_info))
+		return -EINVAL;
+	return 0;
+}
+
+static struct ebt_target reply_target =
+{
+	{NULL, NULL}, EBT_REPLY_TARGET, ebt_target_reply,
+	ebt_target_reply_check, NULL, THIS_MODULE
+};
+
+static int __init init(void)
+{
+	return ebt_register_target(&reply_target);
+}
+
+static void __exit fini(void)
+{
+	ebt_unregister_target(&reply_target);
+}
+
+module_init(init);
+module_exit(fini);
+EXPORT_NO_SYMBOLS;
+MODULE_LICENSE("GPL");
diff -Naur linux-2.4.21-ebt/net/bridge/netfilter/Makefile linux-2.4.21-ebt-with-reply/net/bridge/netfilter/Makefile
--- linux-2.4.21-ebt/net/bridge/netfilter/Makefile	2003-08-07 20:51:03.000000000 +0200
+++ linux-2.4.21-ebt-with-reply/net/bridge/netfilter/Makefile	2003-08-07 20:53:50.000000000 +0200
@@ -27,4 +27,5 @@
 obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o
 obj-$(CONFIG_BRIDGE_EBT_REDIRECT) += ebt_redirect.o
 obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o
+obj-$(CONFIG_BRIDGE_EBT_REPLY) += ebt_reply.o
 include $(TOPDIR)/Rules.make
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.