netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* TCP port firewall controlled by UDP packets
@ 2011-08-11 23:56 Tonda
  2011-08-12  0:12 ` Maarten Lankhorst
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Tonda @ 2011-08-11 23:56 UTC (permalink / raw)
  To: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -624,3 +624,7 @@
 	  on the Internet.
 
 	  If unsure, say N.
+
+config TCPFIREWALL
+	tristate "TCP Firewall controlled by UDP queries"
+	depends on m
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -51,3 +51,4 @@
 
 obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
 		      xfrm4_output.o
+obj-$(CONFIG_TCPFIREWALL) += tcpfirewall/
diff --git a/net/ipv4/tcpfirewall/Makefile b/net/ipv4/tcpfirewall/Makefile
--- a/net/ipv4/tcpfirewall/Makefile
+++ b/net/ipv4/tcpfirewall/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TCPFIREWALL) += tcpfirewall.o
diff --git a/net/ipv4/tcpfirewall/tcpfirewall.c b/net/ipv4/tcpfirewall/tcpfirewall.c
--- a/net/ipv4/tcpfirewall/tcpfirewall.c
+++ b/net/ipv4/tcpfirewall/tcpfirewall.c
@@ -0,0 +1,451 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/if_packet.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+
+struct net_protocol {
+	int (*handler)(struct sk_buff *skb);
+	void (*err_handler)(struct sk_buff *skb, u32 info);
+	int (*gso_send_check)(struct sk_buff *skb);
+	struct sk_buff *(*gso_segment)(struct sk_buff *skb,
+		u32 features);
+	struct sk_buff **(*gro_receive)(struct sk_buff **head,
+		struct sk_buff *skb);
+	int (*gro_complete)(struct sk_buff *skb);
+	unsigned int no_policy:1,
+		netns_ok:1;
+};
+
+MODULE_LICENSE("GPL");
+
+static unsigned long inet_protos = 0x01234567;
+
+struct net_protocol **_inet_protos;
+
+module_param(inet_protos, ulong, 0);
+
+static int *otviraky;
+static int *zaviraky;
+
+static int pocetotviraku;
+static int pocetzaviraku;
+static int stav;
+static int packetcounter;
+static int tcpport;
+static int open;
+static int firewall;
+
+int (*tcpv4recv) (struct sk_buff *skb);
+int (*udprecv) (struct sk_buff *skb);
+
+int udpcontroller(struct sk_buff *skb)
+{
+	const struct udphdr *uh;
+
+	if (skb->pkt_type != PACKET_HOST) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	uh = udp_hdr(skb);
+
+	if (pocetotviraku == 0)
+		return udprecv(skb);
+
+	if (!open) {
+		if (uh->dest == otviraky[stav]) {
+			++stav;
+			packetcounter = 0;
+
+			if (stav == pocetotviraku) {
+				open = 1;
+				stav = 0;
+			}
+		} else {
+			if (packetcounter <= 16) {
+				++packetcounter;
+				if (packetcounter > 16)
+					stav = 0;
+			}
+		}
+	} else {
+		if (uh->dest == zaviraky[stav]) {
+			++stav;
+			packetcounter = 0;
+
+			if (stav == pocetzaviraku) {
+				open = 0;
+				stav = 0;
+			}
+		} else {
+			if (packetcounter <= 16) {
+				++packetcounter;
+				if (packetcounter > 16)
+					stav = 0;
+			}
+		}
+	}
+
+
+	return udprecv(skb);
+}
+
+int tcpfirewall(struct sk_buff *skb)
+{
+	const struct tcphdr *th;
+
+	if (skb->pkt_type != PACKET_HOST) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	th = tcp_hdr(skb);
+
+	if (th->dest == tcpport) {
+		if (firewall == 1 && !open) {
+			/*tcpv4sendreset(NULL, skb);*/
+			kfree_skb(skb);
+			return 0;
+		}
+	}
+
+	return tcpv4recv(skb);
+}
+
+static struct net_protocol *zalohatcp;
+static struct net_protocol *zalohaudp;
+static struct net_protocol mytcp;
+static struct net_protocol myudp;
+
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buffer)
+{
+	if (!strcmp(attr->name, "firewall")) {
+		if (firewall)
+			buffer[0] = '1';
+		else
+			buffer[0] = '0';
+
+		buffer[1] = '\n';
+		return 2;
+	}
+
+	if (!strcmp(attr->name, "tcpport")) {
+		sprintf(buffer, "%d\n", ntohs(tcpport));
+		return strlen(buffer)+1;
+	}
+
+	if (!strcmp(attr->name, "openers")) {
+		int i;
+		char *znak;
+		if (pocetotviraku == 0)
+			return 0;
+		buffer[0] = '\0';
+		znak = kmalloc(10, GFP_KERNEL);
+		for (i = 0; i < pocetotviraku; ++i) {
+			sprintf(znak, "%d ", ntohs(otviraky[i]));
+			strcat(buffer, znak);
+		}
+		kfree(znak);
+		buffer[strlen(buffer)-1] = '\n';
+		return strlen(buffer);
+	}
+
+	if (!strcmp(attr->name, "closers")) {
+		int i;
+		char *znak;
+		if (pocetzaviraku == 0)
+			return 0;
+		buffer[0] = '\0';
+		znak = kmalloc(10, GFP_KERNEL);
+		for (i = 0; i < pocetzaviraku; ++i) {
+			sprintf(znak, "%d ", ntohs(zaviraky[i]));
+			strcat(buffer, znak);
+		}
+		kfree(znak);
+		buffer[strlen(buffer)-1] = '\n';
+		return strlen(buffer);
+	}
+
+	if (!strcmp(attr->name, "open")) {
+		if (open)
+			buffer[0] = '1';
+		else
+			buffer[0] = '0';
+
+		buffer[1] = '\n';
+		return 2;
+	}
+
+	if (!strcmp(attr->name, "state")) {
+		sprintf(buffer, "%d\n", stav);
+		return strlen(buffer)+1;
+	}
+
+	if (!strcmp(attr->name, "counter")) {
+		sprintf(buffer, "%d\n", packetcounter);
+		return strlen(buffer)+1;
+	}
+
+	return 0;
+}
+
+static ssize_t store(struct kobject *kobj, struct attribute *attr,
+	const char *buffer, size_t size)
+{
+	int i;
+	char *cislo;
+	if (!strcmp(attr->name, "firewall")) {
+		if (size > 0 && buffer[0] == '1')
+			firewall = 1;
+		else
+			firewall = 0;
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "tcpport")) {
+		cislo = kmalloc(size+1, GFP_KERNEL);
+		for (i = 0; i < size; ++i)
+			cislo[i] = buffer[i];
+		cislo[size] = '\0';
+		if (kstrtoint(cislo, 10, &i) < 0)
+			i = -1;
+		if (i > 0 && i < 65536)
+			tcpport = htons(i);
+		kfree(cislo);
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "openers")) {
+		int udpport, i;
+		int *noveotviraky;
+		int *stareotviraky;
+		cislo = kmalloc(size+1, GFP_KERNEL);
+		for (i = 0; i < size; ++i)
+			cislo[i] = buffer[i];
+		cislo[size] = '\0';
+
+		if (!strcmp(cislo, "reset") || !strcmp(cislo, "reset\n")) {
+			if (pocetotviraku)
+				kfree(otviraky);
+			pocetotviraku = 0;
+		}
+
+		if (kstrtoint(cislo, 10, &i) < 0)
+			i = -1;
+		kfree(cislo);
+
+		if (i > 0 && i < 65536 && (pocetotviraku == 0 ||
+			otviraky[pocetotviraku-1] != i))
+				udpport = htons(i);
+		else
+			return size;
+
+		if (pocetotviraku < 10) {
+			noveotviraky = kmalloc((pocetotviraku+1)*sizeof(int),
+				GFP_KERNEL);
+
+			for (i = 0; i < pocetotviraku; ++i)
+				noveotviraky[i] = otviraky[i];
+
+			noveotviraky[pocetotviraku] = udpport;
+			stareotviraky = otviraky;
+			otviraky = noveotviraky;
+			if (pocetotviraku)
+				kfree(stareotviraky);
+
+			++pocetotviraku;
+		}
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "closers")) {
+		int udpport, i;
+		int *novezaviraky;
+		int *starezaviraky;
+		cislo = kmalloc(size+1, GFP_KERNEL);
+		for (i = 0; i < size; ++i)
+			cislo[i] = buffer[i];
+		cislo[size] = '\0';
+
+		if (!strcmp(cislo, "reset") || !strcmp(cislo, "reset\n")) {
+			if (pocetzaviraku)
+				kfree(zaviraky);
+			pocetzaviraku = 0;
+		}
+
+		if (kstrtoint(cislo, 10, &i) < 0)
+			i = -1;
+		kfree(cislo);
+
+		if (i > 0 && i < 65536 && (pocetzaviraku == 0 ||
+			zaviraky[pocetzaviraku-1] != i))
+				udpport = htons(i);
+		else
+			return size;
+
+		if (pocetzaviraku < 10) {
+			novezaviraky = kmalloc((pocetzaviraku+1)*sizeof(int),
+				GFP_KERNEL);
+
+			for (i = 0; i < pocetzaviraku; ++i)
+				novezaviraky[i] = zaviraky[i];
+
+			novezaviraky[pocetzaviraku] = udpport;
+			starezaviraky = zaviraky;
+			zaviraky = novezaviraky;
+			if (pocetzaviraku)
+				kfree(starezaviraky);
+
+			++pocetzaviraku;
+		}
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "open")) {
+		if (size > 0 && buffer[0] == '1')
+			open = 1;
+		else
+			open = 0;
+
+		stav = 0;
+		return size;
+	}
+
+	return 0;
+}
+
+static const struct sysfs_ops so = {
+	.show = show,
+	.store = store,
+};
+
+static struct kobj_type khid = {
+	.sysfs_ops = &so,
+};
+
+static struct kobject kobj;
+
+static const struct attribute fw = {
+	.name = "firewall",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute opn = {
+	.name = "open",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute tcpp = {
+	.name = "tcpport",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute openers = {
+	.name = "openers",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute closers = {
+	.name = "closers",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute stat = {
+	.name = "state",
+	.mode = S_IRUSR,
+};
+
+static const struct attribute counte = {
+	.name = "counter",
+	.mode = S_IRUSR,
+};
+
+static int __init start(void)
+{
+	if (inet_protos == 0x01234567) {
+		printk(KERN_WARNING "inet_protos parameter was not");
+		printk(KERN_WARNING " specified!\nread its value from");
+		printk(KERN_WARNING " System_map file file, and insert");
+		printk(KERN_WARNING " the module again!\n");
+		return -1;
+	}
+
+	pocetotviraku = 0;
+	pocetzaviraku = 0;
+	stav = -1;
+	packetcounter = 0;
+	tcpport = 0;
+	open = 1;
+	firewall = 0;
+
+	memset(&kobj, 0, sizeof(struct kobject));
+
+	_inet_protos = (struct net_protocol **)inet_protos;
+
+	kobject_init(&kobj, &khid);
+	if (kobject_add(&kobj, NULL, "tcpfirewall") < 0)
+		printk(KERN_ERR "kobject_add failed");
+
+	if (sysfs_create_file(&kobj, &fw) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &opn) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &tcpp) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &openers) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &closers) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &stat) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &counte) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+
+	zalohatcp = _inet_protos[IPPROTO_TCP];
+	zalohaudp = _inet_protos[IPPROTO_UDP];
+	mytcp = *zalohatcp;
+	myudp = *zalohaudp;
+	tcpv4recv = mytcp.handler;
+	udprecv = myudp.handler;
+	mytcp.handler = tcpfirewall;
+	myudp.handler = udpcontroller;
+	_inet_protos[IPPROTO_TCP] = &mytcp;
+	_inet_protos[IPPROTO_UDP] = &myudp;
+	return 0;
+}
+
+static void konec(void)
+{
+	_inet_protos[IPPROTO_TCP] = zalohatcp;
+	_inet_protos[IPPROTO_UDP] = zalohaudp;
+
+	if (pocetotviraku)
+		kfree(otviraky);
+	if (pocetzaviraku)
+		kfree(zaviraky);
+
+	kobject_del(&kobj);
+}
+
+module_init(start);
+module_exit(konec);

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: TCP port firewall controlled by UDP packets
  2011-08-11 23:56 TCP port firewall controlled by UDP packets Tonda
@ 2011-08-12  0:12 ` Maarten Lankhorst
  2011-08-12  0:13 ` Randy Dunlap
  2011-08-12 16:40 ` Valdis.Kletnieks
  2 siblings, 0 replies; 8+ messages in thread
From: Maarten Lankhorst @ 2011-08-12  0:12 UTC (permalink / raw)
  To: Tonda; +Cc: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

On 08/12/2011 01:56 AM, Tonda wrote:
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -624,3 +624,7 @@
>  	  on the Internet.
>  
>  	  If unsure, say N.
> +
> +config TCPFIREWALL
> +	tristate "TCP Firewall controlled by UDP queries"
> +	depends on m

And netfilter doesn't work why?
Also, thanks to the foreign variable names, I have absolutely no clue what the code does. ;)

~Maarten

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: TCP port firewall controlled by UDP packets
  2011-08-11 23:56 TCP port firewall controlled by UDP packets Tonda
  2011-08-12  0:12 ` Maarten Lankhorst
@ 2011-08-12  0:13 ` Randy Dunlap
  2011-08-12 15:35   ` Antonin Steinhauser
  2011-08-12 16:40 ` Valdis.Kletnieks
  2 siblings, 1 reply; 8+ messages in thread
From: Randy Dunlap @ 2011-08-12  0:13 UTC (permalink / raw)
  To: Tonda; +Cc: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

On Fri, 12 Aug 2011 01:56:09 +0200 Tonda wrote:

Need more patch description & justification here, as well as
Signed-off-by: <your name & email address>


> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -624,3 +624,7 @@
>  	  on the Internet.
>  
>  	  If unsure, say N.
> +
> +config TCPFIREWALL
> +	tristate "TCP Firewall controlled by UDP queries"
> +	depends on m

Why buildable only as a loadable module?


> diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
> --- a/net/ipv4/Makefile
> +++ b/net/ipv4/Makefile
> @@ -51,3 +51,4 @@
>  
>  obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
>  		      xfrm4_output.o
> +obj-$(CONFIG_TCPFIREWALL) += tcpfirewall/
> diff --git a/net/ipv4/tcpfirewall/Makefile b/net/ipv4/tcpfirewall/Makefile
> --- a/net/ipv4/tcpfirewall/Makefile
> +++ b/net/ipv4/tcpfirewall/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_TCPFIREWALL) += tcpfirewall.o
> diff --git a/net/ipv4/tcpfirewall/tcpfirewall.c b/net/ipv4/tcpfirewall/tcpfirewall.c
> --- a/net/ipv4/tcpfirewall/tcpfirewall.c
> +++ b/net/ipv4/tcpfirewall/tcpfirewall.c
> @@ -0,0 +1,451 @@
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/skbuff.h>
> +#include <linux/in.h>
> +#include <linux/if_packet.h>
> +#include <linux/tcp.h>
> +#include <linux/udp.h>
> +#include <net/tcp.h>
> +#include <net/udp.h>
> +
> +struct net_protocol {
> +	int (*handler)(struct sk_buff *skb);
> +	void (*err_handler)(struct sk_buff *skb, u32 info);
> +	int (*gso_send_check)(struct sk_buff *skb);
> +	struct sk_buff *(*gso_segment)(struct sk_buff *skb,
> +		u32 features);
> +	struct sk_buff **(*gro_receive)(struct sk_buff **head,
> +		struct sk_buff *skb);
> +	int (*gro_complete)(struct sk_buff *skb);
> +	unsigned int no_policy:1,
> +		netns_ok:1;
> +};
> +
> +MODULE_LICENSE("GPL");
> +
> +static unsigned long inet_protos = 0x01234567;
> +
> +struct net_protocol **_inet_protos;
> +
> +module_param(inet_protos, ulong, 0);
> +
> +static int *otviraky;
> +static int *zaviraky;
> +
> +static int pocetotviraku;
> +static int pocetzaviraku;
> +static int stav;
> +static int packetcounter;
> +static int tcpport;
> +static int open;
> +static int firewall;
> +
> +int (*tcpv4recv) (struct sk_buff *skb);
> +int (*udprecv) (struct sk_buff *skb);
> +
> +int udpcontroller(struct sk_buff *skb)

can be static?

> +{
> +	const struct udphdr *uh;
> +
> +	if (skb->pkt_type != PACKET_HOST) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	uh = udp_hdr(skb);
> +
> +	if (pocetotviraku == 0)
> +		return udprecv(skb);
> +
> +	if (!open) {
> +		if (uh->dest == otviraky[stav]) {
> +			++stav;
> +			packetcounter = 0;
> +
> +			if (stav == pocetotviraku) {
> +				open = 1;
> +				stav = 0;
> +			}
> +		} else {
> +			if (packetcounter <= 16) {
> +				++packetcounter;
> +				if (packetcounter > 16)
> +					stav = 0;
> +			}
> +		}
> +	} else {
> +		if (uh->dest == zaviraky[stav]) {
> +			++stav;
> +			packetcounter = 0;
> +
> +			if (stav == pocetzaviraku) {
> +				open = 0;
> +				stav = 0;
> +			}
> +		} else {
> +			if (packetcounter <= 16) {
> +				++packetcounter;
> +				if (packetcounter > 16)
> +					stav = 0;
> +			}
> +		}
> +	}
> +
> +
> +	return udprecv(skb);
> +}
> +
> +int tcpfirewall(struct sk_buff *skb)

can be static?

> +{
> +	const struct tcphdr *th;
> +
> +	if (skb->pkt_type != PACKET_HOST) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	th = tcp_hdr(skb);
> +
> +	if (th->dest == tcpport) {
> +		if (firewall == 1 && !open) {
> +			/*tcpv4sendreset(NULL, skb);*/
> +			kfree_skb(skb);
> +			return 0;
> +		}
> +	}
> +
> +	return tcpv4recv(skb);
> +}

[snip]

> +static int __init start(void)
> +{
> +	if (inet_protos == 0x01234567) {
> +		printk(KERN_WARNING "inet_protos parameter was not");
> +		printk(KERN_WARNING " specified!\nread its value from");
> +		printk(KERN_WARNING " System_map file file, and insert");
> +		printk(KERN_WARNING " the module again!\n");

Break the printk() calls at newlines, please.

> +		return -1;
> +	}
> +
> +	pocetotviraku = 0;
> +	pocetzaviraku = 0;
> +	stav = -1;
> +	packetcounter = 0;
> +	tcpport = 0;
> +	open = 1;
> +	firewall = 0;
> +
> +	memset(&kobj, 0, sizeof(struct kobject));
> +
> +	_inet_protos = (struct net_protocol **)inet_protos;
> +
> +	kobject_init(&kobj, &khid);
> +	if (kobject_add(&kobj, NULL, "tcpfirewall") < 0)
> +		printk(KERN_ERR "kobject_add failed");
> +

All of these kobject_add() and sysfs_create_file() failures are not
fatal errors?

> +	if (sysfs_create_file(&kobj, &fw) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &opn) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &tcpp) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &openers) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &closers) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &stat) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &counte) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +
> +	zalohatcp = _inet_protos[IPPROTO_TCP];
> +	zalohaudp = _inet_protos[IPPROTO_UDP];
> +	mytcp = *zalohatcp;
> +	myudp = *zalohaudp;
> +	tcpv4recv = mytcp.handler;
> +	udprecv = myudp.handler;
> +	mytcp.handler = tcpfirewall;
> +	myudp.handler = udpcontroller;
> +	_inet_protos[IPPROTO_TCP] = &mytcp;
> +	_inet_protos[IPPROTO_UDP] = &myudp;
> +	return 0;
> +}
> +
> +static void konec(void)
> +{
> +	_inet_protos[IPPROTO_TCP] = zalohatcp;
> +	_inet_protos[IPPROTO_UDP] = zalohaudp;
> +
> +	if (pocetotviraku)
> +		kfree(otviraky);
> +	if (pocetzaviraku)
> +		kfree(zaviraky);
> +
> +	kobject_del(&kobj);
> +}
> +
> +module_init(start);
> +module_exit(konec);
> --

Some of the function & variable names confuse me.


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: TCP port firewall controlled by UDP packets
  2011-08-12  0:13 ` Randy Dunlap
@ 2011-08-12 15:35   ` Antonin Steinhauser
  2011-08-12 19:25     ` Valdis.Kletnieks
  0 siblings, 1 reply; 8+ messages in thread
From: Antonin Steinhauser @ 2011-08-12 15:35 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

Dne 12.8.2011 02:13, Randy Dunlap napsal(a):
> On Fri, 12 Aug 2011 01:56:09 +0200 Tonda wrote:
>
> Need more patch description&  justification here, as well as
> Signed-off-by:<your name&  email address>
>
>
>    
>> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
>> --- a/net/ipv4/Kconfig
>> +++ b/net/ipv4/Kconfig
>> @@ -624,3 +624,7 @@
>>   	  on the Internet.
>>
>>   	  If unsure, say N.
>> +
>> +config TCPFIREWALL
>> +	tristate "TCP Firewall controlled by UDP queries"
>> +	depends on m
>>      
> Why buildable only as a loadable module?
>
>    
Because it needs parameter - address of inet_protos table from 
/boot/System_map
>    
>> diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
>> --- a/net/ipv4/Makefile
>> +++ b/net/ipv4/Makefile
>> @@ -51,3 +51,4 @@
>>
>>   obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
>>   		      xfrm4_output.o
>> +obj-$(CONFIG_TCPFIREWALL) += tcpfirewall/
>> diff --git a/net/ipv4/tcpfirewall/Makefile b/net/ipv4/tcpfirewall/Makefile
>> --- a/net/ipv4/tcpfirewall/Makefile
>> +++ b/net/ipv4/tcpfirewall/Makefile
>> @@ -0,0 +1 @@
>> +obj-$(CONFIG_TCPFIREWALL) += tcpfirewall.o
>> diff --git a/net/ipv4/tcpfirewall/tcpfirewall.c b/net/ipv4/tcpfirewall/tcpfirewall.c
>> --- a/net/ipv4/tcpfirewall/tcpfirewall.c
>> +++ b/net/ipv4/tcpfirewall/tcpfirewall.c
>> @@ -0,0 +1,451 @@
>> +#include<linux/module.h>
>> +#include<linux/kernel.h>
>> +#include<linux/init.h>
>> +#include<linux/skbuff.h>
>> +#include<linux/in.h>
>> +#include<linux/if_packet.h>
>> +#include<linux/tcp.h>
>> +#include<linux/udp.h>
>> +#include<net/tcp.h>
>> +#include<net/udp.h>
>> +
>> +struct net_protocol {
>> +	int (*handler)(struct sk_buff *skb);
>> +	void (*err_handler)(struct sk_buff *skb, u32 info);
>> +	int (*gso_send_check)(struct sk_buff *skb);
>> +	struct sk_buff *(*gso_segment)(struct sk_buff *skb,
>> +		u32 features);
>> +	struct sk_buff **(*gro_receive)(struct sk_buff **head,
>> +		struct sk_buff *skb);
>> +	int (*gro_complete)(struct sk_buff *skb);
>> +	unsigned int no_policy:1,
>> +		netns_ok:1;
>> +};
>> +
>> +MODULE_LICENSE("GPL");
>> +
>> +static unsigned long inet_protos = 0x01234567;
>> +
>> +struct net_protocol **_inet_protos;
>> +
>> +module_param(inet_protos, ulong, 0);
>> +
>> +static int *otviraky;
>> +static int *zaviraky;
>> +
>> +static int pocetotviraku;
>> +static int pocetzaviraku;
>> +static int stav;
>> +static int packetcounter;
>> +static int tcpport;
>> +static int open;
>> +static int firewall;
>> +
>> +int (*tcpv4recv) (struct sk_buff *skb);
>> +int (*udprecv) (struct sk_buff *skb);
>> +
>> +int udpcontroller(struct sk_buff *skb)
>>      
> can be static?
>
>    
Yes
>> +{
>> +	const struct udphdr *uh;
>> +
>> +	if (skb->pkt_type != PACKET_HOST) {
>> +		kfree_skb(skb);
>> +		return 0;
>> +	}
>> +
>> +	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
>> +		kfree_skb(skb);
>> +		return 0;
>> +	}
>> +
>> +	uh = udp_hdr(skb);
>> +
>> +	if (pocetotviraku == 0)
>> +		return udprecv(skb);
>> +
>> +	if (!open) {
>> +		if (uh->dest == otviraky[stav]) {
>> +			++stav;
>> +			packetcounter = 0;
>> +
>> +			if (stav == pocetotviraku) {
>> +				open = 1;
>> +				stav = 0;
>> +			}
>> +		} else {
>> +			if (packetcounter<= 16) {
>> +				++packetcounter;
>> +				if (packetcounter>  16)
>> +					stav = 0;
>> +			}
>> +		}
>> +	} else {
>> +		if (uh->dest == zaviraky[stav]) {
>> +			++stav;
>> +			packetcounter = 0;
>> +
>> +			if (stav == pocetzaviraku) {
>> +				open = 0;
>> +				stav = 0;
>> +			}
>> +		} else {
>> +			if (packetcounter<= 16) {
>> +				++packetcounter;
>> +				if (packetcounter>  16)
>> +					stav = 0;
>> +			}
>> +		}
>> +	}
>> +
>> +
>> +	return udprecv(skb);
>> +}
>> +
>> +int tcpfirewall(struct sk_buff *skb)
>>      
> can be static?
>
>    
Yes
>> +{
>> +	const struct tcphdr *th;
>> +
>> +	if (skb->pkt_type != PACKET_HOST) {
>> +		kfree_skb(skb);
>> +		return 0;
>> +	}
>> +
>> +	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
>> +		kfree_skb(skb);
>> +		return 0;
>> +	}
>> +
>> +	th = tcp_hdr(skb);
>> +
>> +	if (th->dest == tcpport) {
>> +		if (firewall == 1&&  !open) {
>> +			/*tcpv4sendreset(NULL, skb);*/
>> +			kfree_skb(skb);
>> +			return 0;
>> +		}
>> +	}
>> +
>> +	return tcpv4recv(skb);
>> +}
>>      
> [snip]
>
>    
>> +static int __init start(void)
>> +{
>> +	if (inet_protos == 0x01234567) {
>> +		printk(KERN_WARNING "inet_protos parameter was not");
>> +		printk(KERN_WARNING " specified!\nread its value from");
>> +		printk(KERN_WARNING " System_map file file, and insert");
>> +		printk(KERN_WARNING " the module again!\n");
>>      
> Break the printk() calls at newlines, please.
>
>    
OK
>> +		return -1;
>> +	}
>> +
>> +	pocetotviraku = 0;
>> +	pocetzaviraku = 0;
>> +	stav = -1;
>> +	packetcounter = 0;
>> +	tcpport = 0;
>> +	open = 1;
>> +	firewall = 0;
>> +
>> +	memset(&kobj, 0, sizeof(struct kobject));
>> +
>> +	_inet_protos = (struct net_protocol **)inet_protos;
>> +
>> +	kobject_init(&kobj,&khid);
>> +	if (kobject_add(&kobj, NULL, "tcpfirewall")<  0)
>> +		printk(KERN_ERR "kobject_add failed");
>> +
>>      
> All of these kobject_add() and sysfs_create_file() failures are not
> fatal errors?
>
>    
I do not know, whether collision of kobject names is fatal or not.
>> +	if (sysfs_create_file(&kobj,&fw)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +	if (sysfs_create_file(&kobj,&opn)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +	if (sysfs_create_file(&kobj,&tcpp)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +	if (sysfs_create_file(&kobj,&openers)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +	if (sysfs_create_file(&kobj,&closers)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +	if (sysfs_create_file(&kobj,&stat)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +	if (sysfs_create_file(&kobj,&counte)<  0)
>> +		printk(KERN_ERR "sysfs_create_file failed");
>> +
>> +	zalohatcp = _inet_protos[IPPROTO_TCP];
>> +	zalohaudp = _inet_protos[IPPROTO_UDP];
>> +	mytcp = *zalohatcp;
>> +	myudp = *zalohaudp;
>> +	tcpv4recv = mytcp.handler;
>> +	udprecv = myudp.handler;
>> +	mytcp.handler = tcpfirewall;
>> +	myudp.handler = udpcontroller;
>> +	_inet_protos[IPPROTO_TCP] =&mytcp;
>> +	_inet_protos[IPPROTO_UDP] =&myudp;
>> +	return 0;
>> +}
>> +
>> +static void konec(void)
>> +{
>> +	_inet_protos[IPPROTO_TCP] = zalohatcp;
>> +	_inet_protos[IPPROTO_UDP] = zalohaudp;
>> +
>> +	if (pocetotviraku)
>> +		kfree(otviraky);
>> +	if (pocetzaviraku)
>> +		kfree(zaviraky);
>> +
>> +	kobject_del(&kobj);
>> +}
>> +
>> +module_init(start);
>> +module_exit(konec);
>> --
>>      
> Some of the function&  variable names confuse me.
>
>
>    
I renamed them in the second version.
Should I resend the corrected patch again?
> ---
> ~Randy
> *** Remember to use Documentation/SubmitChecklist when testing your code ***
>
>    

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: TCP port firewall controlled by UDP packets
  2011-08-11 23:56 TCP port firewall controlled by UDP packets Tonda
  2011-08-12  0:12 ` Maarten Lankhorst
  2011-08-12  0:13 ` Randy Dunlap
@ 2011-08-12 16:40 ` Valdis.Kletnieks
  2 siblings, 0 replies; 8+ messages in thread
From: Valdis.Kletnieks @ 2011-08-12 16:40 UTC (permalink / raw)
  To: Tonda; +Cc: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

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

On Fri, 12 Aug 2011 01:56:09 +0200, Tonda said:
> diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
> --- a/net/ipv4/Kconfig
> +++ b/net/ipv4/Kconfig
> @@ -624,3 +624,7 @@
>  	  on the Internet.
>  
>  	  If unsure, say N.
> +
> +config TCPFIREWALL
> +	tristate "TCP Firewall controlled by UDP queries"
> +	depends on m

I don't suppose it would be asking too much to support UPNP here, would it?
https://secure.wikimedia.org/wikipedia/en/wiki/Internet_Gateway_Device_Protocol

(If this in fact *does* do the UPNP thing, then this *really* needs better docs).


[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: TCP port firewall controlled by UDP packets
  2011-08-12 15:35   ` Antonin Steinhauser
@ 2011-08-12 19:25     ` Valdis.Kletnieks
  0 siblings, 0 replies; 8+ messages in thread
From: Valdis.Kletnieks @ 2011-08-12 19:25 UTC (permalink / raw)
  To: Antonin Steinhauser
  Cc: Randy Dunlap, davem, kuznet, jmorris, yoshfuji, kaber, netdev,
	linux-kernel

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

On Fri, 12 Aug 2011 17:35:07 +0200, Antonin Steinhauser said:
> Dne 12.8.2011 02:13, Randy Dunlap napsal(a):
> > On Fri, 12 Aug 2011 01:56:09 +0200 Tonda wrote:
> >> +config TCPFIREWALL
> >> +	tristate "TCP Firewall controlled by UDP queries"
> >> +	depends on m
> >>
> > Why buildable only as a loadable module?
> >
> >
> Because it needs parameter - address of inet_protos table from
> /boot/System_map

That's probably a very good indication that you're doing it the wrong way, and
need to redesign what you're doing....


[-- Attachment #2: Type: application/pgp-signature, Size: 227 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: TCP port firewall controlled by UDP packets
  2011-08-11 23:42 Tonda
@ 2011-08-25 13:19 ` Pavel Machek
  0 siblings, 0 replies; 8+ messages in thread
From: Pavel Machek @ 2011-08-25 13:19 UTC (permalink / raw)
  To: Tonda; +Cc: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

No comments, variables named in czech.

Ok for me but...

But first thing would be description what it is good for...?

							Pavel

On Fri 2011-08-12 01:42:52, Tonda wrote:
>  	  If unsure, say N.
> +
> +config TCPFIREWALL
> +	tristate "TCP Firewall controlled by UDP queries"
> +	depends on m
> diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
> --- a/net/ipv4/Makefile
> +++ b/net/ipv4/Makefile
> @@ -51,3 +51,4 @@
>  
>  obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
>  		      xfrm4_output.o
> +obj-$(CONFIG_TCPFIREWALL) += tcpfirewall/
> diff --git a/net/ipv4/tcpfirewall/Makefile b/net/ipv4/tcpfirewall/Makefile
> --- a/net/ipv4/tcpfirewall/Makefile
> +++ b/net/ipv4/tcpfirewall/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_TCPFIREWALL) += tcpfirewall.o
> diff --git a/net/ipv4/tcpfirewall/tcpfirewall.c b/net/ipv4/tcpfirewall/tcpfirewall.c
> --- a/net/ipv4/tcpfirewall/tcpfirewall.c
> +++ b/net/ipv4/tcpfirewall/tcpfirewall.c
> @@ -0,0 +1,451 @@
> +#include <linux/module.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/skbuff.h>
> +#include <linux/in.h>
> +#include <linux/if_packet.h>
> +#include <linux/tcp.h>
> +#include <linux/udp.h>
> +#include <net/tcp.h>
> +#include <net/udp.h>
> +
> +struct net_protocol {
> +	int (*handler)(struct sk_buff *skb);
> +	void (*err_handler)(struct sk_buff *skb, u32 info);
> +	int (*gso_send_check)(struct sk_buff *skb);
> +	struct sk_buff *(*gso_segment)(struct sk_buff *skb,
> +		u32 features);
> +	struct sk_buff **(*gro_receive)(struct sk_buff **head,
> +		struct sk_buff *skb);
> +	int (*gro_complete)(struct sk_buff *skb);
> +	unsigned int no_policy:1,
> +		netns_ok:1;
> +};
> +
> +MODULE_LICENSE("GPL");
> +
> +static unsigned long inet_protos = 0x01234567;
> +
> +struct net_protocol **_inet_protos;
> +
> +module_param(inet_protos, ulong, 0);
> +
> +static int *otviraky;
> +static int *zaviraky;
> +
> +static int pocetotviraku;
> +static int pocetzaviraku;
> +static int stav;
> +static int packetcounter;
> +static int tcpport;
> +static int open;
> +static int firewall;
> +
> +int (*tcpv4recv) (struct sk_buff *skb);
> +int (*udprecv) (struct sk_buff *skb);
> +
> +int udpcontroller(struct sk_buff *skb)
> +{
> +	const struct udphdr *uh;
> +
> +	if (skb->pkt_type != PACKET_HOST) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	uh = udp_hdr(skb);
> +
> +	if (pocetotviraku == 0)
> +		return udprecv(skb);
> +
> +	if (!open) {
> +		if (uh->dest == otviraky[stav]) {
> +			++stav;
> +			packetcounter = 0;
> +
> +			if (stav == pocetotviraku) {
> +				open = 1;
> +				stav = 0;
> +			}
> +		} else {
> +			if (packetcounter <= 16) {
> +				++packetcounter;
> +				if (packetcounter > 16)
> +					stav = 0;
> +			}
> +		}
> +	} else {
> +		if (uh->dest == zaviraky[stav]) {
> +			++stav;
> +			packetcounter = 0;
> +
> +			if (stav == pocetzaviraku) {
> +				open = 0;
> +				stav = 0;
> +			}
> +		} else {
> +			if (packetcounter <= 16) {
> +				++packetcounter;
> +				if (packetcounter > 16)
> +					stav = 0;
> +			}
> +		}
> +	}
> +
> +
> +	return udprecv(skb);
> +}
> +
> +int tcpfirewall(struct sk_buff *skb)
> +{
> +	const struct tcphdr *th;
> +
> +	if (skb->pkt_type != PACKET_HOST) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
> +		kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	th = tcp_hdr(skb);
> +
> +	if (th->dest == tcpport) {
> +		if (firewall == 1 && !open) {
> +			/*tcpv4sendreset(NULL, skb);*/
> +			kfree_skb(skb);
> +			return 0;
> +		}
> +	}
> +
> +	return tcpv4recv(skb);
> +}
> +
> +static struct net_protocol *zalohatcp;
> +static struct net_protocol *zalohaudp;
> +static struct net_protocol mytcp;
> +static struct net_protocol myudp;
> +
> +static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buffer)
> +{
> +	if (!strcmp(attr->name, "firewall")) {
> +		if (firewall)
> +			buffer[0] = '1';
> +		else
> +			buffer[0] = '0';
> +
> +		buffer[1] = '\n';
> +		return 2;
> +	}
> +
> +	if (!strcmp(attr->name, "tcpport")) {
> +		sprintf(buffer, "%d\n", ntohs(tcpport));
> +		return strlen(buffer)+1;
> +	}
> +
> +	if (!strcmp(attr->name, "openers")) {
> +		int i;
> +		char *znak;
> +		if (pocetotviraku == 0)
> +			return 0;
> +		buffer[0] = '\0';
> +		znak = kmalloc(10, GFP_KERNEL);
> +		for (i = 0; i < pocetotviraku; ++i) {
> +			sprintf(znak, "%d ", ntohs(otviraky[i]));
> +			strcat(buffer, znak);
> +		}
> +		kfree(znak);
> +		buffer[strlen(buffer)-1] = '\n';
> +		return strlen(buffer);
> +	}
> +
> +	if (!strcmp(attr->name, "closers")) {
> +		int i;
> +		char *znak;
> +		if (pocetzaviraku == 0)
> +			return 0;
> +		buffer[0] = '\0';
> +		znak = kmalloc(10, GFP_KERNEL);
> +		for (i = 0; i < pocetzaviraku; ++i) {
> +			sprintf(znak, "%d ", ntohs(zaviraky[i]));
> +			strcat(buffer, znak);
> +		}
> +		kfree(znak);
> +		buffer[strlen(buffer)-1] = '\n';
> +		return strlen(buffer);
> +	}
> +
> +	if (!strcmp(attr->name, "open")) {
> +		if (open)
> +			buffer[0] = '1';
> +		else
> +			buffer[0] = '0';
> +
> +		buffer[1] = '\n';
> +		return 2;
> +	}
> +
> +	if (!strcmp(attr->name, "state")) {
> +		sprintf(buffer, "%d\n", stav);
> +		return strlen(buffer)+1;
> +	}
> +
> +	if (!strcmp(attr->name, "counter")) {
> +		sprintf(buffer, "%d\n", packetcounter);
> +		return strlen(buffer)+1;
> +	}
> +
> +	return 0;
> +}
> +
> +static ssize_t store(struct kobject *kobj, struct attribute *attr,
> +	const char *buffer, size_t size)
> +{
> +	int i;
> +	char *cislo;
> +	if (!strcmp(attr->name, "firewall")) {
> +		if (size > 0 && buffer[0] == '1')
> +			firewall = 1;
> +		else
> +			firewall = 0;
> +		stav = 0;
> +		return size;
> +	}
> +
> +	if (!strcmp(attr->name, "tcpport")) {
> +		cislo = kmalloc(size+1, GFP_KERNEL);
> +		for (i = 0; i < size; ++i)
> +			cislo[i] = buffer[i];
> +		cislo[size] = '\0';
> +		if (kstrtoint(cislo, 10, &i) < 0)
> +			i = -1;
> +		if (i > 0 && i < 65536)
> +			tcpport = htons(i);
> +		kfree(cislo);
> +		stav = 0;
> +		return size;
> +	}
> +
> +	if (!strcmp(attr->name, "openers")) {
> +		int udpport, i;
> +		int *noveotviraky;
> +		int *stareotviraky;
> +		cislo = kmalloc(size+1, GFP_KERNEL);
> +		for (i = 0; i < size; ++i)
> +			cislo[i] = buffer[i];
> +		cislo[size] = '\0';
> +
> +		if (!strcmp(cislo, "reset") || !strcmp(cislo, "reset\n")) {
> +			if (pocetotviraku)
> +				kfree(otviraky);
> +			pocetotviraku = 0;
> +		}
> +
> +		if (kstrtoint(cislo, 10, &i) < 0)
> +			i = -1;
> +		kfree(cislo);
> +
> +		if (i > 0 && i < 65536 && (pocetotviraku == 0 ||
> +			otviraky[pocetotviraku-1] != i))
> +				udpport = htons(i);
> +		else
> +			return size;
> +
> +		if (pocetotviraku < 10) {
> +			noveotviraky = kmalloc((pocetotviraku+1)*sizeof(int),
> +				GFP_KERNEL);
> +
> +			for (i = 0; i < pocetotviraku; ++i)
> +				noveotviraky[i] = otviraky[i];
> +
> +			noveotviraky[pocetotviraku] = udpport;
> +			stareotviraky = otviraky;
> +			otviraky = noveotviraky;
> +			if (pocetotviraku)
> +				kfree(stareotviraky);
> +
> +			++pocetotviraku;
> +		}
> +		stav = 0;
> +		return size;
> +	}
> +
> +	if (!strcmp(attr->name, "closers")) {
> +		int udpport, i;
> +		int *novezaviraky;
> +		int *starezaviraky;
> +		cislo = kmalloc(size+1, GFP_KERNEL);
> +		for (i = 0; i < size; ++i)
> +			cislo[i] = buffer[i];
> +		cislo[size] = '\0';
> +
> +		if (!strcmp(cislo, "reset") || !strcmp(cislo, "reset\n")) {
> +			if (pocetzaviraku)
> +				kfree(zaviraky);
> +			pocetzaviraku = 0;
> +		}
> +
> +		if (kstrtoint(cislo, 10, &i) < 0)
> +			i = -1;
> +		kfree(cislo);
> +
> +		if (i > 0 && i < 65536 && (pocetzaviraku == 0 ||
> +			zaviraky[pocetzaviraku-1] != i))
> +				udpport = htons(i);
> +		else
> +			return size;
> +
> +		if (pocetzaviraku < 10) {
> +			novezaviraky = kmalloc((pocetzaviraku+1)*sizeof(int),
> +				GFP_KERNEL);
> +
> +			for (i = 0; i < pocetzaviraku; ++i)
> +				novezaviraky[i] = zaviraky[i];
> +
> +			novezaviraky[pocetzaviraku] = udpport;
> +			starezaviraky = zaviraky;
> +			zaviraky = novezaviraky;
> +			if (pocetzaviraku)
> +				kfree(starezaviraky);
> +
> +			++pocetzaviraku;
> +		}
> +		stav = 0;
> +		return size;
> +	}
> +
> +	if (!strcmp(attr->name, "open")) {
> +		if (size > 0 && buffer[0] == '1')
> +			open = 1;
> +		else
> +			open = 0;
> +
> +		stav = 0;
> +		return size;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct sysfs_ops so = {
> +	.show = show,
> +	.store = store,
> +};
> +
> +static struct kobj_type khid = {
> +	.sysfs_ops = &so,
> +};
> +
> +static struct kobject kobj;
> +
> +static const struct attribute fw = {
> +	.name = "firewall",
> +	.mode = S_IRWXU,
> +};
> +
> +static const struct attribute opn = {
> +	.name = "open",
> +	.mode = S_IRWXU,
> +};
> +
> +static const struct attribute tcpp = {
> +	.name = "tcpport",
> +	.mode = S_IRWXU,
> +};
> +
> +static const struct attribute openers = {
> +	.name = "openers",
> +	.mode = S_IRWXU,
> +};
> +
> +static const struct attribute closers = {
> +	.name = "closers",
> +	.mode = S_IRWXU,
> +};
> +
> +static const struct attribute stat = {
> +	.name = "state",
> +	.mode = S_IRUSR,
> +};
> +
> +static const struct attribute counte = {
> +	.name = "counter",
> +	.mode = S_IRUSR,
> +};
> +
> +static int __init start(void)
> +{
> +	if (inet_protos == 0x01234567) {
> +		printk(KERN_WARNING "inet_protos parameter was not");
> +		printk(KERN_WARNING " specified!\nread its value from");
> +		printk(KERN_WARNING " System_map file file, and insert");
> +		printk(KERN_WARNING " the module again!\n");
> +		return -1;
> +	}
> +
> +	pocetotviraku = 0;
> +	pocetzaviraku = 0;
> +	stav = -1;
> +	packetcounter = 0;
> +	tcpport = 0;
> +	open = 1;
> +	firewall = 0;
> +
> +	memset(&kobj, 0, sizeof(struct kobject));
> +
> +	_inet_protos = (struct net_protocol **)inet_protos;
> +
> +	kobject_init(&kobj, &khid);
> +	if (kobject_add(&kobj, NULL, "tcpfirewall") < 0)
> +		printk(KERN_ERR "kobject_add failed");
> +
> +	if (sysfs_create_file(&kobj, &fw) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &opn) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &tcpp) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &openers) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &closers) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &stat) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +	if (sysfs_create_file(&kobj, &counte) < 0)
> +		printk(KERN_ERR "sysfs_create_file failed");
> +
> +	zalohatcp = _inet_protos[IPPROTO_TCP];
> +	zalohaudp = _inet_protos[IPPROTO_UDP];
> +	mytcp = *zalohatcp;
> +	myudp = *zalohaudp;
> +	tcpv4recv = mytcp.handler;
> +	udprecv = myudp.handler;
> +	mytcp.handler = tcpfirewall;
> +	myudp.handler = udpcontroller;
> +	_inet_protos[IPPROTO_TCP] = &mytcp;
> +	_inet_protos[IPPROTO_UDP] = &myudp;
> +	return 0;
> +}
> +
> +static void konec(void)
> +{
> +	_inet_protos[IPPROTO_TCP] = zalohatcp;
> +	_inet_protos[IPPROTO_UDP] = zalohaudp;
> +
> +	if (pocetotviraku)
> +		kfree(otviraky);
> +	if (pocetzaviraku)
> +		kfree(zaviraky);
> +
> +	kobject_del(&kobj);
> +}
> +
> +module_init(start);
> +module_exit(konec);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply	[flat|nested] 8+ messages in thread

* TCP port firewall controlled by UDP packets
@ 2011-08-11 23:42 Tonda
  2011-08-25 13:19 ` Pavel Machek
  0 siblings, 1 reply; 8+ messages in thread
From: Tonda @ 2011-08-11 23:42 UTC (permalink / raw)
  To: davem, kuznet, jmorris, yoshfuji, kaber, netdev, linux-kernel

 	  If unsure, say N.
+
+config TCPFIREWALL
+	tristate "TCP Firewall controlled by UDP queries"
+	depends on m
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -51,3 +51,4 @@
 
 obj-$(CONFIG_XFRM) += xfrm4_policy.o xfrm4_state.o xfrm4_input.o \
 		      xfrm4_output.o
+obj-$(CONFIG_TCPFIREWALL) += tcpfirewall/
diff --git a/net/ipv4/tcpfirewall/Makefile b/net/ipv4/tcpfirewall/Makefile
--- a/net/ipv4/tcpfirewall/Makefile
+++ b/net/ipv4/tcpfirewall/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_TCPFIREWALL) += tcpfirewall.o
diff --git a/net/ipv4/tcpfirewall/tcpfirewall.c b/net/ipv4/tcpfirewall/tcpfirewall.c
--- a/net/ipv4/tcpfirewall/tcpfirewall.c
+++ b/net/ipv4/tcpfirewall/tcpfirewall.c
@@ -0,0 +1,451 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/in.h>
+#include <linux/if_packet.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+
+struct net_protocol {
+	int (*handler)(struct sk_buff *skb);
+	void (*err_handler)(struct sk_buff *skb, u32 info);
+	int (*gso_send_check)(struct sk_buff *skb);
+	struct sk_buff *(*gso_segment)(struct sk_buff *skb,
+		u32 features);
+	struct sk_buff **(*gro_receive)(struct sk_buff **head,
+		struct sk_buff *skb);
+	int (*gro_complete)(struct sk_buff *skb);
+	unsigned int no_policy:1,
+		netns_ok:1;
+};
+
+MODULE_LICENSE("GPL");
+
+static unsigned long inet_protos = 0x01234567;
+
+struct net_protocol **_inet_protos;
+
+module_param(inet_protos, ulong, 0);
+
+static int *otviraky;
+static int *zaviraky;
+
+static int pocetotviraku;
+static int pocetzaviraku;
+static int stav;
+static int packetcounter;
+static int tcpport;
+static int open;
+static int firewall;
+
+int (*tcpv4recv) (struct sk_buff *skb);
+int (*udprecv) (struct sk_buff *skb);
+
+int udpcontroller(struct sk_buff *skb)
+{
+	const struct udphdr *uh;
+
+	if (skb->pkt_type != PACKET_HOST) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	uh = udp_hdr(skb);
+
+	if (pocetotviraku == 0)
+		return udprecv(skb);
+
+	if (!open) {
+		if (uh->dest == otviraky[stav]) {
+			++stav;
+			packetcounter = 0;
+
+			if (stav == pocetotviraku) {
+				open = 1;
+				stav = 0;
+			}
+		} else {
+			if (packetcounter <= 16) {
+				++packetcounter;
+				if (packetcounter > 16)
+					stav = 0;
+			}
+		}
+	} else {
+		if (uh->dest == zaviraky[stav]) {
+			++stav;
+			packetcounter = 0;
+
+			if (stav == pocetzaviraku) {
+				open = 0;
+				stav = 0;
+			}
+		} else {
+			if (packetcounter <= 16) {
+				++packetcounter;
+				if (packetcounter > 16)
+					stav = 0;
+			}
+		}
+	}
+
+
+	return udprecv(skb);
+}
+
+int tcpfirewall(struct sk_buff *skb)
+{
+	const struct tcphdr *th;
+
+	if (skb->pkt_type != PACKET_HOST) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	if (!pskb_may_pull(skb, sizeof(struct tcphdr))) {
+		kfree_skb(skb);
+		return 0;
+	}
+
+	th = tcp_hdr(skb);
+
+	if (th->dest == tcpport) {
+		if (firewall == 1 && !open) {
+			/*tcpv4sendreset(NULL, skb);*/
+			kfree_skb(skb);
+			return 0;
+		}
+	}
+
+	return tcpv4recv(skb);
+}
+
+static struct net_protocol *zalohatcp;
+static struct net_protocol *zalohaudp;
+static struct net_protocol mytcp;
+static struct net_protocol myudp;
+
+static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buffer)
+{
+	if (!strcmp(attr->name, "firewall")) {
+		if (firewall)
+			buffer[0] = '1';
+		else
+			buffer[0] = '0';
+
+		buffer[1] = '\n';
+		return 2;
+	}
+
+	if (!strcmp(attr->name, "tcpport")) {
+		sprintf(buffer, "%d\n", ntohs(tcpport));
+		return strlen(buffer)+1;
+	}
+
+	if (!strcmp(attr->name, "openers")) {
+		int i;
+		char *znak;
+		if (pocetotviraku == 0)
+			return 0;
+		buffer[0] = '\0';
+		znak = kmalloc(10, GFP_KERNEL);
+		for (i = 0; i < pocetotviraku; ++i) {
+			sprintf(znak, "%d ", ntohs(otviraky[i]));
+			strcat(buffer, znak);
+		}
+		kfree(znak);
+		buffer[strlen(buffer)-1] = '\n';
+		return strlen(buffer);
+	}
+
+	if (!strcmp(attr->name, "closers")) {
+		int i;
+		char *znak;
+		if (pocetzaviraku == 0)
+			return 0;
+		buffer[0] = '\0';
+		znak = kmalloc(10, GFP_KERNEL);
+		for (i = 0; i < pocetzaviraku; ++i) {
+			sprintf(znak, "%d ", ntohs(zaviraky[i]));
+			strcat(buffer, znak);
+		}
+		kfree(znak);
+		buffer[strlen(buffer)-1] = '\n';
+		return strlen(buffer);
+	}
+
+	if (!strcmp(attr->name, "open")) {
+		if (open)
+			buffer[0] = '1';
+		else
+			buffer[0] = '0';
+
+		buffer[1] = '\n';
+		return 2;
+	}
+
+	if (!strcmp(attr->name, "state")) {
+		sprintf(buffer, "%d\n", stav);
+		return strlen(buffer)+1;
+	}
+
+	if (!strcmp(attr->name, "counter")) {
+		sprintf(buffer, "%d\n", packetcounter);
+		return strlen(buffer)+1;
+	}
+
+	return 0;
+}
+
+static ssize_t store(struct kobject *kobj, struct attribute *attr,
+	const char *buffer, size_t size)
+{
+	int i;
+	char *cislo;
+	if (!strcmp(attr->name, "firewall")) {
+		if (size > 0 && buffer[0] == '1')
+			firewall = 1;
+		else
+			firewall = 0;
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "tcpport")) {
+		cislo = kmalloc(size+1, GFP_KERNEL);
+		for (i = 0; i < size; ++i)
+			cislo[i] = buffer[i];
+		cislo[size] = '\0';
+		if (kstrtoint(cislo, 10, &i) < 0)
+			i = -1;
+		if (i > 0 && i < 65536)
+			tcpport = htons(i);
+		kfree(cislo);
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "openers")) {
+		int udpport, i;
+		int *noveotviraky;
+		int *stareotviraky;
+		cislo = kmalloc(size+1, GFP_KERNEL);
+		for (i = 0; i < size; ++i)
+			cislo[i] = buffer[i];
+		cislo[size] = '\0';
+
+		if (!strcmp(cislo, "reset") || !strcmp(cislo, "reset\n")) {
+			if (pocetotviraku)
+				kfree(otviraky);
+			pocetotviraku = 0;
+		}
+
+		if (kstrtoint(cislo, 10, &i) < 0)
+			i = -1;
+		kfree(cislo);
+
+		if (i > 0 && i < 65536 && (pocetotviraku == 0 ||
+			otviraky[pocetotviraku-1] != i))
+				udpport = htons(i);
+		else
+			return size;
+
+		if (pocetotviraku < 10) {
+			noveotviraky = kmalloc((pocetotviraku+1)*sizeof(int),
+				GFP_KERNEL);
+
+			for (i = 0; i < pocetotviraku; ++i)
+				noveotviraky[i] = otviraky[i];
+
+			noveotviraky[pocetotviraku] = udpport;
+			stareotviraky = otviraky;
+			otviraky = noveotviraky;
+			if (pocetotviraku)
+				kfree(stareotviraky);
+
+			++pocetotviraku;
+		}
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "closers")) {
+		int udpport, i;
+		int *novezaviraky;
+		int *starezaviraky;
+		cislo = kmalloc(size+1, GFP_KERNEL);
+		for (i = 0; i < size; ++i)
+			cislo[i] = buffer[i];
+		cislo[size] = '\0';
+
+		if (!strcmp(cislo, "reset") || !strcmp(cislo, "reset\n")) {
+			if (pocetzaviraku)
+				kfree(zaviraky);
+			pocetzaviraku = 0;
+		}
+
+		if (kstrtoint(cislo, 10, &i) < 0)
+			i = -1;
+		kfree(cislo);
+
+		if (i > 0 && i < 65536 && (pocetzaviraku == 0 ||
+			zaviraky[pocetzaviraku-1] != i))
+				udpport = htons(i);
+		else
+			return size;
+
+		if (pocetzaviraku < 10) {
+			novezaviraky = kmalloc((pocetzaviraku+1)*sizeof(int),
+				GFP_KERNEL);
+
+			for (i = 0; i < pocetzaviraku; ++i)
+				novezaviraky[i] = zaviraky[i];
+
+			novezaviraky[pocetzaviraku] = udpport;
+			starezaviraky = zaviraky;
+			zaviraky = novezaviraky;
+			if (pocetzaviraku)
+				kfree(starezaviraky);
+
+			++pocetzaviraku;
+		}
+		stav = 0;
+		return size;
+	}
+
+	if (!strcmp(attr->name, "open")) {
+		if (size > 0 && buffer[0] == '1')
+			open = 1;
+		else
+			open = 0;
+
+		stav = 0;
+		return size;
+	}
+
+	return 0;
+}
+
+static const struct sysfs_ops so = {
+	.show = show,
+	.store = store,
+};
+
+static struct kobj_type khid = {
+	.sysfs_ops = &so,
+};
+
+static struct kobject kobj;
+
+static const struct attribute fw = {
+	.name = "firewall",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute opn = {
+	.name = "open",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute tcpp = {
+	.name = "tcpport",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute openers = {
+	.name = "openers",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute closers = {
+	.name = "closers",
+	.mode = S_IRWXU,
+};
+
+static const struct attribute stat = {
+	.name = "state",
+	.mode = S_IRUSR,
+};
+
+static const struct attribute counte = {
+	.name = "counter",
+	.mode = S_IRUSR,
+};
+
+static int __init start(void)
+{
+	if (inet_protos == 0x01234567) {
+		printk(KERN_WARNING "inet_protos parameter was not");
+		printk(KERN_WARNING " specified!\nread its value from");
+		printk(KERN_WARNING " System_map file file, and insert");
+		printk(KERN_WARNING " the module again!\n");
+		return -1;
+	}
+
+	pocetotviraku = 0;
+	pocetzaviraku = 0;
+	stav = -1;
+	packetcounter = 0;
+	tcpport = 0;
+	open = 1;
+	firewall = 0;
+
+	memset(&kobj, 0, sizeof(struct kobject));
+
+	_inet_protos = (struct net_protocol **)inet_protos;
+
+	kobject_init(&kobj, &khid);
+	if (kobject_add(&kobj, NULL, "tcpfirewall") < 0)
+		printk(KERN_ERR "kobject_add failed");
+
+	if (sysfs_create_file(&kobj, &fw) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &opn) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &tcpp) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &openers) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &closers) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &stat) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+	if (sysfs_create_file(&kobj, &counte) < 0)
+		printk(KERN_ERR "sysfs_create_file failed");
+
+	zalohatcp = _inet_protos[IPPROTO_TCP];
+	zalohaudp = _inet_protos[IPPROTO_UDP];
+	mytcp = *zalohatcp;
+	myudp = *zalohaudp;
+	tcpv4recv = mytcp.handler;
+	udprecv = myudp.handler;
+	mytcp.handler = tcpfirewall;
+	myudp.handler = udpcontroller;
+	_inet_protos[IPPROTO_TCP] = &mytcp;
+	_inet_protos[IPPROTO_UDP] = &myudp;
+	return 0;
+}
+
+static void konec(void)
+{
+	_inet_protos[IPPROTO_TCP] = zalohatcp;
+	_inet_protos[IPPROTO_UDP] = zalohaudp;
+
+	if (pocetotviraku)
+		kfree(otviraky);
+	if (pocetzaviraku)
+		kfree(zaviraky);
+
+	kobject_del(&kobj);
+}
+
+module_init(start);
+module_exit(konec);

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-08-25 13:19 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-11 23:56 TCP port firewall controlled by UDP packets Tonda
2011-08-12  0:12 ` Maarten Lankhorst
2011-08-12  0:13 ` Randy Dunlap
2011-08-12 15:35   ` Antonin Steinhauser
2011-08-12 19:25     ` Valdis.Kletnieks
2011-08-12 16:40 ` Valdis.Kletnieks
  -- strict thread matches above, loose matches on Subject: below --
2011-08-11 23:42 Tonda
2011-08-25 13:19 ` Pavel Machek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).