* 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-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: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
* 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
* 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
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).