1*a71a9546SAutomerger Merge Worker /*
2*a71a9546SAutomerger Merge Worker * libxt_LED.c - shared library add-on to iptables to add customized LED
3*a71a9546SAutomerger Merge Worker * trigger support.
4*a71a9546SAutomerger Merge Worker *
5*a71a9546SAutomerger Merge Worker * (C) 2008 Adam Nielsen <[email protected]>
6*a71a9546SAutomerger Merge Worker *
7*a71a9546SAutomerger Merge Worker * This program is free software; you can redistribute it and/or modify
8*a71a9546SAutomerger Merge Worker * it under the terms of the GNU General Public License version 2 as
9*a71a9546SAutomerger Merge Worker * published by the Free Software Foundation.
10*a71a9546SAutomerger Merge Worker *
11*a71a9546SAutomerger Merge Worker */
12*a71a9546SAutomerger Merge Worker #include <stdio.h>
13*a71a9546SAutomerger Merge Worker #include <string.h>
14*a71a9546SAutomerger Merge Worker #include <stdlib.h>
15*a71a9546SAutomerger Merge Worker #include <xtables.h>
16*a71a9546SAutomerger Merge Worker #include <linux/netfilter/xt_LED.h>
17*a71a9546SAutomerger Merge Worker
18*a71a9546SAutomerger Merge Worker enum {
19*a71a9546SAutomerger Merge Worker O_LED_TRIGGER_ID = 0,
20*a71a9546SAutomerger Merge Worker O_LED_DELAY,
21*a71a9546SAutomerger Merge Worker O_LED_ALWAYS_BLINK,
22*a71a9546SAutomerger Merge Worker };
23*a71a9546SAutomerger Merge Worker
24*a71a9546SAutomerger Merge Worker #define s struct xt_led_info
25*a71a9546SAutomerger Merge Worker static const struct xt_option_entry LED_opts[] = {
26*a71a9546SAutomerger Merge Worker {.name = "led-trigger-id", .id = O_LED_TRIGGER_ID,
27*a71a9546SAutomerger Merge Worker .flags = XTOPT_MAND, .type = XTTYPE_STRING, .min = 0,
28*a71a9546SAutomerger Merge Worker .max = sizeof(((struct xt_led_info *)NULL)->id) -
29*a71a9546SAutomerger Merge Worker sizeof("netfilter-")},
30*a71a9546SAutomerger Merge Worker {.name = "led-delay", .id = O_LED_DELAY, .type = XTTYPE_STRING},
31*a71a9546SAutomerger Merge Worker {.name = "led-always-blink", .id = O_LED_ALWAYS_BLINK,
32*a71a9546SAutomerger Merge Worker .type = XTTYPE_NONE},
33*a71a9546SAutomerger Merge Worker XTOPT_TABLEEND,
34*a71a9546SAutomerger Merge Worker };
35*a71a9546SAutomerger Merge Worker #undef s
36*a71a9546SAutomerger Merge Worker
LED_help(void)37*a71a9546SAutomerger Merge Worker static void LED_help(void)
38*a71a9546SAutomerger Merge Worker {
39*a71a9546SAutomerger Merge Worker printf(
40*a71a9546SAutomerger Merge Worker "LED target options:\n"
41*a71a9546SAutomerger Merge Worker "--led-trigger-id name suffix for led trigger name\n"
42*a71a9546SAutomerger Merge Worker "--led-delay ms leave the LED on for this number of\n"
43*a71a9546SAutomerger Merge Worker " milliseconds after triggering.\n"
44*a71a9546SAutomerger Merge Worker "--led-always-blink blink on arriving packets, even if\n"
45*a71a9546SAutomerger Merge Worker " the LED is already on.\n"
46*a71a9546SAutomerger Merge Worker );
47*a71a9546SAutomerger Merge Worker }
48*a71a9546SAutomerger Merge Worker
LED_parse(struct xt_option_call * cb)49*a71a9546SAutomerger Merge Worker static void LED_parse(struct xt_option_call *cb)
50*a71a9546SAutomerger Merge Worker {
51*a71a9546SAutomerger Merge Worker struct xt_led_info *led = cb->data;
52*a71a9546SAutomerger Merge Worker
53*a71a9546SAutomerger Merge Worker xtables_option_parse(cb);
54*a71a9546SAutomerger Merge Worker switch (cb->entry->id) {
55*a71a9546SAutomerger Merge Worker case O_LED_TRIGGER_ID:
56*a71a9546SAutomerger Merge Worker snprintf(led->id, sizeof(led->id), "netfilter-%s", cb->arg);
57*a71a9546SAutomerger Merge Worker break;
58*a71a9546SAutomerger Merge Worker case O_LED_DELAY:
59*a71a9546SAutomerger Merge Worker if (strncasecmp(cb->arg, "inf", 3) == 0)
60*a71a9546SAutomerger Merge Worker led->delay = -1;
61*a71a9546SAutomerger Merge Worker else if (!xtables_strtoui(cb->arg, NULL, &led->delay, 0, UINT32_MAX))
62*a71a9546SAutomerger Merge Worker xtables_error(PARAMETER_PROBLEM,
63*a71a9546SAutomerger Merge Worker "Delay value must be within range 0..%u",
64*a71a9546SAutomerger Merge Worker UINT32_MAX);
65*a71a9546SAutomerger Merge Worker break;
66*a71a9546SAutomerger Merge Worker case O_LED_ALWAYS_BLINK:
67*a71a9546SAutomerger Merge Worker led->always_blink = 1;
68*a71a9546SAutomerger Merge Worker break;
69*a71a9546SAutomerger Merge Worker }
70*a71a9546SAutomerger Merge Worker }
71*a71a9546SAutomerger Merge Worker
LED_print(const void * ip,const struct xt_entry_target * target,int numeric)72*a71a9546SAutomerger Merge Worker static void LED_print(const void *ip, const struct xt_entry_target *target,
73*a71a9546SAutomerger Merge Worker int numeric)
74*a71a9546SAutomerger Merge Worker {
75*a71a9546SAutomerger Merge Worker const struct xt_led_info *led = (void *)target->data;
76*a71a9546SAutomerger Merge Worker const char *id = led->id + strlen("netfilter-"); /* trim off prefix */
77*a71a9546SAutomerger Merge Worker
78*a71a9546SAutomerger Merge Worker printf(" led-trigger-id:\"");
79*a71a9546SAutomerger Merge Worker /* Escape double quotes and backslashes in the ID */
80*a71a9546SAutomerger Merge Worker while (*id != '\0') {
81*a71a9546SAutomerger Merge Worker if (*id == '"' || *id == '\\')
82*a71a9546SAutomerger Merge Worker printf("\\");
83*a71a9546SAutomerger Merge Worker printf("%c", *id++);
84*a71a9546SAutomerger Merge Worker }
85*a71a9546SAutomerger Merge Worker printf("\"");
86*a71a9546SAutomerger Merge Worker
87*a71a9546SAutomerger Merge Worker if (led->delay == -1)
88*a71a9546SAutomerger Merge Worker printf(" led-delay:inf");
89*a71a9546SAutomerger Merge Worker else
90*a71a9546SAutomerger Merge Worker printf(" led-delay:%dms", led->delay);
91*a71a9546SAutomerger Merge Worker
92*a71a9546SAutomerger Merge Worker if (led->always_blink)
93*a71a9546SAutomerger Merge Worker printf(" led-always-blink");
94*a71a9546SAutomerger Merge Worker }
95*a71a9546SAutomerger Merge Worker
LED_save(const void * ip,const struct xt_entry_target * target)96*a71a9546SAutomerger Merge Worker static void LED_save(const void *ip, const struct xt_entry_target *target)
97*a71a9546SAutomerger Merge Worker {
98*a71a9546SAutomerger Merge Worker const struct xt_led_info *led = (void *)target->data;
99*a71a9546SAutomerger Merge Worker const char *id = led->id + strlen("netfilter-"); /* trim off prefix */
100*a71a9546SAutomerger Merge Worker
101*a71a9546SAutomerger Merge Worker printf(" --led-trigger-id \"");
102*a71a9546SAutomerger Merge Worker /* Escape double quotes and backslashes in the ID */
103*a71a9546SAutomerger Merge Worker while (*id != '\0') {
104*a71a9546SAutomerger Merge Worker if (*id == '"' || *id == '\\')
105*a71a9546SAutomerger Merge Worker printf("\\");
106*a71a9546SAutomerger Merge Worker printf("%c", *id++);
107*a71a9546SAutomerger Merge Worker }
108*a71a9546SAutomerger Merge Worker printf("\"");
109*a71a9546SAutomerger Merge Worker
110*a71a9546SAutomerger Merge Worker /* Only print the delay if it's not zero (the default) */
111*a71a9546SAutomerger Merge Worker if (led->delay > 0)
112*a71a9546SAutomerger Merge Worker printf(" --led-delay %d", led->delay);
113*a71a9546SAutomerger Merge Worker else if (led->delay == -1)
114*a71a9546SAutomerger Merge Worker printf(" --led-delay inf");
115*a71a9546SAutomerger Merge Worker
116*a71a9546SAutomerger Merge Worker /* Only print always_blink if it's not set to the default */
117*a71a9546SAutomerger Merge Worker if (led->always_blink)
118*a71a9546SAutomerger Merge Worker printf(" --led-always-blink");
119*a71a9546SAutomerger Merge Worker }
120*a71a9546SAutomerger Merge Worker
121*a71a9546SAutomerger Merge Worker static struct xtables_target led_tg_reg = {
122*a71a9546SAutomerger Merge Worker .version = XTABLES_VERSION,
123*a71a9546SAutomerger Merge Worker .name = "LED",
124*a71a9546SAutomerger Merge Worker .family = PF_UNSPEC,
125*a71a9546SAutomerger Merge Worker .revision = 0,
126*a71a9546SAutomerger Merge Worker .size = XT_ALIGN(sizeof(struct xt_led_info)),
127*a71a9546SAutomerger Merge Worker .userspacesize = offsetof(struct xt_led_info, internal_data),
128*a71a9546SAutomerger Merge Worker .help = LED_help,
129*a71a9546SAutomerger Merge Worker .print = LED_print,
130*a71a9546SAutomerger Merge Worker .save = LED_save,
131*a71a9546SAutomerger Merge Worker .x6_parse = LED_parse,
132*a71a9546SAutomerger Merge Worker .x6_options = LED_opts,
133*a71a9546SAutomerger Merge Worker };
134*a71a9546SAutomerger Merge Worker
_init(void)135*a71a9546SAutomerger Merge Worker void _init(void)
136*a71a9546SAutomerger Merge Worker {
137*a71a9546SAutomerger Merge Worker xtables_register_target(&led_tg_reg);
138*a71a9546SAutomerger Merge Worker }
139