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