xref: /aosp_15_r20/external/iptables/extensions/libxt_LED.c (revision a71a954618bbadd4a345637e5edcf36eec826889)
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