libipt_REJECT.c revision 2c69b55e55f2efc5a334b87ccdceaa9de0ecb658
1/* Shared library add-on to iptables to add customized REJECT support. 2 * 3 * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 */ 5#include <stdio.h> 6#include <string.h> 7#include <stdlib.h> 8#include <getopt.h> 9#include <xtables.h> 10#include <linux/netfilter_ipv4/ipt_REJECT.h> 11#include <linux/version.h> 12 13/* If we are compiling against a kernel that does not support 14 * IPT_ICMP_ADMIN_PROHIBITED, we are emulating it. 15 * The result will be a plain DROP of the packet instead of 16 * reject. -- Maciej Soltysiak <solt@dns.toxicfilms.tv> 17 */ 18#ifndef IPT_ICMP_ADMIN_PROHIBITED 19#define IPT_ICMP_ADMIN_PROHIBITED IPT_TCP_RESET + 1 20#endif 21 22struct reject_names { 23 const char *name; 24 const char *alias; 25 enum ipt_reject_with with; 26 const char *desc; 27}; 28 29static const struct reject_names reject_table[] = { 30 {"icmp-net-unreachable", "net-unreach", 31 IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"}, 32 {"icmp-host-unreachable", "host-unreach", 33 IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"}, 34 {"icmp-proto-unreachable", "proto-unreach", 35 IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"}, 36 {"icmp-port-unreachable", "port-unreach", 37 IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"}, 38#if 0 39 {"echo-reply", "echoreply", 40 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"}, 41#endif 42 {"icmp-net-prohibited", "net-prohib", 43 IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"}, 44 {"icmp-host-prohibited", "host-prohib", 45 IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"}, 46 {"tcp-reset", "tcp-rst", 47 IPT_TCP_RESET, "TCP RST packet"}, 48 {"icmp-admin-prohibited", "admin-prohib", 49 IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"} 50}; 51 52static void 53print_reject_types(void) 54{ 55 unsigned int i; 56 57 printf("Valid reject types:\n"); 58 59 for (i = 0; i < ARRAY_SIZE(reject_table); ++i) { 60 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc); 61 printf(" %-25s\talias\n", reject_table[i].alias); 62 } 63 printf("\n"); 64} 65 66static void REJECT_help(void) 67{ 68 printf( 69"REJECT target options:\n" 70"--reject-with type drop input packet and send back\n" 71" a reply packet according to type:\n"); 72 73 print_reject_types(); 74 75 printf("(*) See man page or read the INCOMPATIBILITES file for compatibility issues.\n"); 76} 77 78static const struct option REJECT_opts[] = { 79 { "reject-with", 1, NULL, '1' }, 80 { .name = NULL } 81}; 82 83static void REJECT_init(struct xt_entry_target *t) 84{ 85 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data; 86 87 /* default */ 88 reject->with = IPT_ICMP_PORT_UNREACHABLE; 89 90} 91 92static int REJECT_parse(int c, char **argv, int invert, unsigned int *flags, 93 const void *entry, struct xt_entry_target **target) 94{ 95 struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; 96 static const unsigned int limit = ARRAY_SIZE(reject_table); 97 unsigned int i; 98 99 switch(c) { 100 case '1': 101 if (xtables_check_inverse(optarg, &invert, NULL, 0)) 102 xtables_error(PARAMETER_PROBLEM, 103 "Unexpected `!' after --reject-with"); 104 for (i = 0; i < limit; i++) { 105 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) 106 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { 107 reject->with = reject_table[i].with; 108 return 1; 109 } 110 } 111 /* This due to be dropped late in 2.4 pre-release cycle --RR */ 112 if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0 113 || strncasecmp("echoreply", optarg, strlen(optarg)) == 0) 114 fprintf(stderr, "--reject-with echo-reply no longer" 115 " supported\n"); 116 xtables_error(PARAMETER_PROBLEM, "unknown reject type \"%s\"", optarg); 117 default: 118 /* Fall through */ 119 break; 120 } 121 return 0; 122} 123 124static void REJECT_print(const void *ip, const struct xt_entry_target *target, 125 int numeric) 126{ 127 const struct ipt_reject_info *reject 128 = (const struct ipt_reject_info *)target->data; 129 unsigned int i; 130 131 for (i = 0; i < ARRAY_SIZE(reject_table); ++i) 132 if (reject_table[i].with == reject->with) 133 break; 134 printf("reject-with %s ", reject_table[i].name); 135} 136 137static void REJECT_save(const void *ip, const struct xt_entry_target *target) 138{ 139 const struct ipt_reject_info *reject 140 = (const struct ipt_reject_info *)target->data; 141 unsigned int i; 142 143 for (i = 0; i < ARRAY_SIZE(reject_table); ++i) 144 if (reject_table[i].with == reject->with) 145 break; 146 147 printf("--reject-with %s ", reject_table[i].name); 148} 149 150static struct xtables_target reject_tg_reg = { 151 .name = "REJECT", 152 .version = XTABLES_VERSION, 153 .family = NFPROTO_IPV4, 154 .size = XT_ALIGN(sizeof(struct ipt_reject_info)), 155 .userspacesize = XT_ALIGN(sizeof(struct ipt_reject_info)), 156 .help = REJECT_help, 157 .init = REJECT_init, 158 .parse = REJECT_parse, 159 .print = REJECT_print, 160 .save = REJECT_save, 161 .extra_opts = REJECT_opts, 162}; 163 164void _init(void) 165{ 166 xtables_register_target(&reject_tg_reg); 167} 168