aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Nielsen <a.nielsen@shikadi.net>2009-02-20 04:55:14 -0500
committerPatrick McHardy <kaber@trash.net>2009-02-20 04:55:14 -0500
commit268cb38e1802db560c73167e643f14a3dcb4b07c (patch)
tree3bc3b7954795722bd09b760ba540a3f7f429dae0
parentaf07d241dc76f0a52c7ff04df3a3970020fe6157 (diff)
netfilter: x_tables: add LED trigger target
Kernel module providing implementation of LED netfilter target. Each instance of the target appears as a led-trigger device, which can be associated with one or more LEDs in /sys/class/leds/ Signed-off-by: Adam Nielsen <a.nielsen@shikadi.net> Acked-by: Richard Purdie <rpurdie@linux.intel.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--drivers/leds/Kconfig3
-rw-r--r--include/linux/netfilter/Kbuild1
-rw-r--r--include/linux/netfilter/xt_LED.h13
-rw-r--r--net/netfilter/Kconfig24
-rw-r--r--net/netfilter/Makefile1
-rw-r--r--net/netfilter/xt_LED.c161
6 files changed, 203 insertions, 0 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 742713611bc..556aeca0d86 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -223,4 +223,7 @@ config LEDS_TRIGGER_DEFAULT_ON
223 This allows LEDs to be initialised in the ON state. 223 This allows LEDs to be initialised in the ON state.
224 If unsure, say Y. 224 If unsure, say Y.
225 225
226comment "iptables trigger is under Netfilter config (LED target)"
227 depends on LEDS_TRIGGERS
228
226endif # NEW_LEDS 229endif # NEW_LEDS
diff --git a/include/linux/netfilter/Kbuild b/include/linux/netfilter/Kbuild
index 5a8af875bce..deeaee5c83f 100644
--- a/include/linux/netfilter/Kbuild
+++ b/include/linux/netfilter/Kbuild
@@ -7,6 +7,7 @@ header-y += xt_CLASSIFY.h
7header-y += xt_CONNMARK.h 7header-y += xt_CONNMARK.h
8header-y += xt_CONNSECMARK.h 8header-y += xt_CONNSECMARK.h
9header-y += xt_DSCP.h 9header-y += xt_DSCP.h
10header-y += xt_LED.h
10header-y += xt_MARK.h 11header-y += xt_MARK.h
11header-y += xt_NFLOG.h 12header-y += xt_NFLOG.h
12header-y += xt_NFQUEUE.h 13header-y += xt_NFQUEUE.h
diff --git a/include/linux/netfilter/xt_LED.h b/include/linux/netfilter/xt_LED.h
new file mode 100644
index 00000000000..4c91a0d770d
--- /dev/null
+++ b/include/linux/netfilter/xt_LED.h
@@ -0,0 +1,13 @@
1#ifndef _XT_LED_H
2#define _XT_LED_H
3
4struct xt_led_info {
5 char id[27]; /* Unique ID for this trigger in the LED class */
6 __u8 always_blink; /* Blink even if the LED is already on */
7 __u32 delay; /* Delay until LED is switched off after trigger */
8
9 /* Kernel data used in the module */
10 void *internal_data __attribute__((aligned(8)));
11};
12
13#endif /* _XT_LED_H */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 0eb98b4fbf4..cdbaaff6d0d 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -372,6 +372,30 @@ config NETFILTER_XT_TARGET_HL
372 since you can easily create immortal packets that loop 372 since you can easily create immortal packets that loop
373 forever on the network. 373 forever on the network.
374 374
375config NETFILTER_XT_TARGET_LED
376 tristate '"LED" target support'
377 depends on LEDS_CLASS
378 depends on NETFILTER_ADVANCED
379 help
380 This option adds a `LED' target, which allows you to blink LEDs in
381 response to particular packets passing through your machine.
382
383 This can be used to turn a spare LED into a network activity LED,
384 which only flashes in response to FTP transfers, for example. Or
385 you could have an LED which lights up for a minute or two every time
386 somebody connects to your machine via SSH.
387
388 You will need support for the "led" class to make this work.
389
390 To create an LED trigger for incoming SSH traffic:
391 iptables -A INPUT -p tcp --dport 22 -j LED --led-trigger-id ssh --led-delay 1000
392
393 Then attach the new trigger to an LED on your system:
394 echo netfilter-ssh > /sys/class/leds/<ledname>/trigger
395
396 For more information on the LEDs available on your system, see
397 Documentation/leds-class.txt
398
375config NETFILTER_XT_TARGET_MARK 399config NETFILTER_XT_TARGET_MARK
376 tristate '"MARK" target support' 400 tristate '"MARK" target support'
377 default m if NETFILTER_ADVANCED=n 401 default m if NETFILTER_ADVANCED=n
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index da73ed25701..7a9b8397573 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
46obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o 46obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
47obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o 47obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
48obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o 48obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
49obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
49obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o 50obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
50obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o 51obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
51obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 52obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
diff --git a/net/netfilter/xt_LED.c b/net/netfilter/xt_LED.c
new file mode 100644
index 00000000000..8ff7843bb92
--- /dev/null
+++ b/net/netfilter/xt_LED.c
@@ -0,0 +1,161 @@
1/*
2 * xt_LED.c - netfilter target to make LEDs blink upon packet matches
3 *
4 * Copyright (C) 2008 Adam Nielsen <a.nielsen@shikadi.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA.
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/skbuff.h>
24#include <linux/netfilter/x_tables.h>
25#include <linux/leds.h>
26#include <linux/mutex.h>
27
28#include <linux/netfilter/xt_LED.h>
29
30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Adam Nielsen <a.nielsen@shikadi.net>");
32MODULE_DESCRIPTION("Xtables: trigger LED devices on packet match");
33
34/*
35 * This is declared in here (the kernel module) only, to avoid having these
36 * dependencies in userspace code. This is what xt_led_info.internal_data
37 * points to.
38 */
39struct xt_led_info_internal {
40 struct led_trigger netfilter_led_trigger;
41 struct timer_list timer;
42};
43
44static unsigned int
45led_tg(struct sk_buff *skb, const struct xt_target_param *par)
46{
47 const struct xt_led_info *ledinfo = par->targinfo;
48 struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
49
50 /*
51 * If "always blink" is enabled, and there's still some time until the
52 * LED will switch off, briefly switch it off now.
53 */
54 if ((ledinfo->delay > 0) && ledinfo->always_blink &&
55 timer_pending(&ledinternal->timer))
56 led_trigger_event(&ledinternal->netfilter_led_trigger,LED_OFF);
57
58 led_trigger_event(&ledinternal->netfilter_led_trigger, LED_FULL);
59
60 /* If there's a positive delay, start/update the timer */
61 if (ledinfo->delay > 0) {
62 mod_timer(&ledinternal->timer,
63 jiffies + msecs_to_jiffies(ledinfo->delay));
64
65 /* Otherwise if there was no delay given, blink as fast as possible */
66 } else if (ledinfo->delay == 0) {
67 led_trigger_event(&ledinternal->netfilter_led_trigger, LED_OFF);
68 }
69
70 /* else the delay is negative, which means switch on and stay on */
71
72 return XT_CONTINUE;
73}
74
75static void led_timeout_callback(unsigned long data)
76{
77 struct xt_led_info *ledinfo = (struct xt_led_info *)data;
78 struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
79
80 led_trigger_event(&ledinternal->netfilter_led_trigger, LED_OFF);
81}
82
83static bool led_tg_check(const struct xt_tgchk_param *par)
84{
85 struct xt_led_info *ledinfo = par->targinfo;
86 struct xt_led_info_internal *ledinternal;
87 int err;
88
89 if (ledinfo->id[0] == '\0') {
90 printk(KERN_ERR KBUILD_MODNAME ": No 'id' parameter given.\n");
91 return false;
92 }
93
94 ledinternal = kzalloc(sizeof(struct xt_led_info_internal), GFP_KERNEL);
95 if (!ledinternal) {
96 printk(KERN_CRIT KBUILD_MODNAME ": out of memory\n");
97 return false;
98 }
99
100 ledinternal->netfilter_led_trigger.name = ledinfo->id;
101
102 err = led_trigger_register(&ledinternal->netfilter_led_trigger);
103 if (err) {
104 printk(KERN_CRIT KBUILD_MODNAME
105 ": led_trigger_register() failed\n");
106 if (err == -EEXIST)
107 printk(KERN_ERR KBUILD_MODNAME
108 ": Trigger name is already in use.\n");
109 goto exit_alloc;
110 }
111
112 /* See if we need to set up a timer */
113 if (ledinfo->delay > 0)
114 setup_timer(&ledinternal->timer, led_timeout_callback,
115 (unsigned long)ledinfo);
116
117 ledinfo->internal_data = ledinternal;
118
119 return true;
120
121exit_alloc:
122 kfree(ledinternal);
123
124 return false;
125}
126
127static void led_tg_destroy(const struct xt_tgdtor_param *par)
128{
129 const struct xt_led_info *ledinfo = par->targinfo;
130 struct xt_led_info_internal *ledinternal = ledinfo->internal_data;
131
132 if (ledinfo->delay > 0)
133 del_timer_sync(&ledinternal->timer);
134
135 led_trigger_unregister(&ledinternal->netfilter_led_trigger);
136 kfree(ledinternal);
137}
138
139static struct xt_target led_tg_reg __read_mostly = {
140 .name = "LED",
141 .revision = 0,
142 .family = NFPROTO_UNSPEC,
143 .target = led_tg,
144 .targetsize = XT_ALIGN(sizeof(struct xt_led_info)),
145 .checkentry = led_tg_check,
146 .destroy = led_tg_destroy,
147 .me = THIS_MODULE,
148};
149
150static int __init led_tg_init(void)
151{
152 return xt_register_target(&led_tg_reg);
153}
154
155static void __exit led_tg_exit(void)
156{
157 xt_unregister_target(&led_tg_reg);
158}
159
160module_init(led_tg_init);
161module_exit(led_tg_exit);