libipt_REJECT.c revision b77f1dafb9f35752bb9685323bcacb32a0e6ddc5
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 <iptables.h> 10#include <linux/netfilter_ipv4/ip_tables.h> 11#include <linux/netfilter_ipv4/ipt_REJECT.h> 12 13struct reject_names { 14 const char *name; 15 const char *alias; 16 enum ipt_reject_with with; 17 const char *desc; 18}; 19 20static const struct reject_names reject_table[] = { 21 {"icmp-net-unreachable", "net-unreach", 22 IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"}, 23 {"icmp-host-unreachable", "host-unreach", 24 IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"}, 25 {"icmp-proto-unreachable", "proto-unreach", 26 IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"}, 27 {"icmp-port-unreachable", "port-unreach", 28 IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"}, 29#if 0 30 {"echo-reply", "echoreply", 31 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"}, 32#endif 33 {"icmp-net-prohibited", "net-prohib", 34 IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"}, 35 {"icmp-host-prohibited", "host-prohib", 36 IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"}, 37 {"tcp-reset", "tcp-reset", 38 IPT_TCP_RESET, "TCP RST packet"} 39}; 40 41static void 42print_reject_types() 43{ 44 unsigned int i; 45 46 printf("Valid reject types:\n"); 47 48 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) { 49 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc); 50 printf(" %-25s\talias\n", reject_table[i].alias); 51 } 52 printf("\n"); 53} 54 55/* Saves the union ipt_targinfo in parsable form to stdout. */ 56 57/* Function which prints out usage message. */ 58static void 59help(void) 60{ 61 printf( 62"REJECT options:\n" 63"--reject-with type drop input packet and send back\n" 64" a reply packet according to type:\n"); 65 66 print_reject_types(); 67} 68 69static struct option opts[] = { 70 { "reject-with", 1, 0, '1' }, 71 { 0 } 72}; 73 74/* Allocate and initialize the target. */ 75static void 76init(struct ipt_entry_target *t, unsigned int *nfcache) 77{ 78 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data; 79 80 /* default */ 81 reject->with = IPT_ICMP_PORT_UNREACHABLE; 82 83 /* Can't cache this */ 84 *nfcache |= NFC_UNKNOWN; 85} 86 87/* Function which parses command options; returns true if it 88 ate an option */ 89static int 90parse(int c, char **argv, int invert, unsigned int *flags, 91 const struct ipt_entry *entry, 92 struct ipt_entry_target **target) 93{ 94 struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; 95 unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names); 96 unsigned int i; 97 98 switch(c) { 99 case '1': 100 if (check_inverse(optarg, &invert, NULL, 0)) 101 exit_error(PARAMETER_PROBLEM, 102 "Unexpected `!' after --reject-with"); 103 for (i = 0; i < limit; i++) { 104 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) 105 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { 106 reject->with = reject_table[i].with; 107 return 1; 108 } 109 } 110 /* This due to be dropped late in 2.4 pre-release cycle --RR */ 111 if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0 112 || strncasecmp("echoreply", optarg, strlen(optarg)) == 0) 113 fprintf(stderr, "--reject-with echo-reply no longer" 114 " supported\n"); 115 exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg); 116 default: 117 /* Fall through */ 118 break; 119 } 120 return 0; 121} 122 123/* Final check; nothing. */ 124static void final_check(unsigned int flags) 125{ 126} 127 128/* Prints out ipt_reject_info. */ 129static void 130print(const struct ipt_ip *ip, 131 const struct ipt_entry_target *target, 132 int numeric) 133{ 134 const struct ipt_reject_info *reject 135 = (const struct ipt_reject_info *)target->data; 136 unsigned int i; 137 138 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) { 139 if (reject_table[i].with == reject->with) 140 break; 141 } 142 printf("reject-with %s ", reject_table[i].name); 143} 144 145/* Saves ipt_reject in parsable form to stdout. */ 146static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 147{ 148 const struct ipt_reject_info *reject 149 = (const struct ipt_reject_info *)target->data; 150 unsigned int i; 151 152 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) 153 if (reject_table[i].with == reject->with) 154 break; 155 156 printf("--reject-with %s ", reject_table[i].name); 157} 158 159static 160struct iptables_target reject 161= { NULL, 162 "REJECT", 163 NETFILTER_VERSION, 164 IPT_ALIGN(sizeof(struct ipt_reject_info)), 165 IPT_ALIGN(sizeof(struct ipt_reject_info)), 166 &help, 167 &init, 168 &parse, 169 &final_check, 170 &print, 171 &save, 172 opts 173}; 174 175void _init(void) 176{ 177 register_target(&reject); 178} 179