1/* ebt_redirect
2 *
3 * Authors:
4 * Bart De Schuymer <bdschuym@pandora.be>
5 *
6 * April, 2002
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <getopt.h>
13#include "../include/ebtables_u.h"
14#include <linux/netfilter_bridge/ebt_redirect.h>
15
16#define REDIRECT_TARGET '1'
17static struct option opts[] =
18{
19	{ "redirect-target", required_argument, 0, REDIRECT_TARGET },
20	{ 0 }
21};
22
23static void print_help()
24{
25	printf(
26	"redirect option:\n"
27	" --redirect-target target   : ACCEPT, DROP, RETURN or CONTINUE\n");
28}
29
30static void init(struct ebt_entry_target *target)
31{
32	struct ebt_redirect_info *redirectinfo =
33	   (struct ebt_redirect_info *)target->data;
34
35	redirectinfo->target = EBT_ACCEPT;
36	return;
37}
38
39#define OPT_REDIRECT_TARGET  0x01
40static int parse(int c, char **argv, int argc,
41   const struct ebt_u_entry *entry, unsigned int *flags,
42   struct ebt_entry_target **target)
43{
44	struct ebt_redirect_info *redirectinfo =
45	   (struct ebt_redirect_info *)(*target)->data;
46
47	switch (c) {
48	case REDIRECT_TARGET:
49		ebt_check_option2(flags, OPT_REDIRECT_TARGET);
50		if (FILL_TARGET(optarg, redirectinfo->target))
51			ebt_print_error2("Illegal --redirect-target target");
52		break;
53	default:
54		return 0;
55	}
56	return 1;
57}
58
59static void final_check(const struct ebt_u_entry *entry,
60   const struct ebt_entry_target *target, const char *name,
61   unsigned int hookmask, unsigned int time)
62{
63	struct ebt_redirect_info *redirectinfo =
64	   (struct ebt_redirect_info *)target->data;
65
66	if (BASE_CHAIN && redirectinfo->target == EBT_RETURN) {
67		ebt_print_error("--redirect-target RETURN not allowed on base chain");
68		return;
69	}
70	CLEAR_BASE_CHAIN_BIT;
71	if ( ((hookmask & ~(1 << NF_BR_PRE_ROUTING)) || strcmp(name, "nat")) &&
72	   ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")) )
73		ebt_print_error("Wrong chain for redirect");
74}
75
76static void print(const struct ebt_u_entry *entry,
77   const struct ebt_entry_target *target)
78{
79	struct ebt_redirect_info *redirectinfo =
80	   (struct ebt_redirect_info *)target->data;
81
82	if (redirectinfo->target == EBT_ACCEPT)
83		return;
84	printf(" --redirect-target %s", TARGET_NAME(redirectinfo->target));
85}
86
87static int compare(const struct ebt_entry_target *t1,
88   const struct ebt_entry_target *t2)
89{
90	struct ebt_redirect_info *redirectinfo1 =
91	   (struct ebt_redirect_info *)t1->data;
92	struct ebt_redirect_info *redirectinfo2 =
93	   (struct ebt_redirect_info *)t2->data;
94
95	return redirectinfo1->target == redirectinfo2->target;
96}
97
98static struct ebt_u_target redirect_target =
99{
100	.name		= "redirect",
101	.size		= sizeof(struct ebt_redirect_info),
102	.help		= print_help,
103	.init		= init,
104	.parse		= parse,
105	.final_check	= final_check,
106	.print		= print,
107	.compare	= compare,
108	.extra_ops	= opts,
109};
110
111void _init(void)
112{
113	ebt_register_target(&redirect_target);
114}
115