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