Skip to content

Commit 268cb38

Browse files
Malvineouskaber
authored andcommitted
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 <[email protected]> Acked-by: Richard Purdie <[email protected]> Signed-off-by: Patrick McHardy <[email protected]>
1 parent af07d24 commit 268cb38

File tree

6 files changed

+203
-0
lines changed

6 files changed

+203
-0
lines changed

drivers/leds/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,7 @@ config LEDS_TRIGGER_DEFAULT_ON
223223
This allows LEDs to be initialised in the ON state.
224224
If unsure, say Y.
225225

226+
comment "iptables trigger is under Netfilter config (LED target)"
227+
depends on LEDS_TRIGGERS
228+
226229
endif # NEW_LEDS

include/linux/netfilter/Kbuild

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ header-y += xt_CLASSIFY.h
77
header-y += xt_CONNMARK.h
88
header-y += xt_CONNSECMARK.h
99
header-y += xt_DSCP.h
10+
header-y += xt_LED.h
1011
header-y += xt_MARK.h
1112
header-y += xt_NFLOG.h
1213
header-y += xt_NFQUEUE.h

include/linux/netfilter/xt_LED.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#ifndef _XT_LED_H
2+
#define _XT_LED_H
3+
4+
struct 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 */

net/netfilter/Kconfig

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,30 @@ config NETFILTER_XT_TARGET_HL
372372
since you can easily create immortal packets that loop
373373
forever on the network.
374374

375+
config 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+
375399
config NETFILTER_XT_TARGET_MARK
376400
tristate '"MARK" target support'
377401
default m if NETFILTER_ADVANCED=n

net/netfilter/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
4646
obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
4747
obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
4848
obj-$(CONFIG_NETFILTER_XT_TARGET_HL) += xt_HL.o
49+
obj-$(CONFIG_NETFILTER_XT_TARGET_LED) += xt_LED.o
4950
obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
5051
obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
5152
obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o

net/netfilter/xt_LED.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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 <[email protected]>
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+
30+
MODULE_LICENSE("GPL");
31+
MODULE_AUTHOR("Adam Nielsen <[email protected]>");
32+
MODULE_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+
*/
39+
struct xt_led_info_internal {
40+
struct led_trigger netfilter_led_trigger;
41+
struct timer_list timer;
42+
};
43+
44+
static unsigned int
45+
led_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+
75+
static 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+
83+
static 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+
121+
exit_alloc:
122+
kfree(ledinternal);
123+
124+
return false;
125+
}
126+
127+
static 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+
139+
static 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+
150+
static int __init led_tg_init(void)
151+
{
152+
return xt_register_target(&led_tg_reg);
153+
}
154+
155+
static void __exit led_tg_exit(void)
156+
{
157+
xt_unregister_target(&led_tg_reg);
158+
}
159+
160+
module_init(led_tg_init);
161+
module_exit(led_tg_exit);

0 commit comments

Comments
 (0)