libipt_REJECT.c revision a1ce9f9b8265a8c28facd52f4e3c0465dce2b9f0
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-port-unreachable", "port-unreach", 26 IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"}, 27 {"icmp-proto-unreachable", "proto-unreach", 28 IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"}, 29 {"echo-reply", "echoreply", 30 IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"} 31}; 32 33static void 34print_reject_types() 35{ 36 unsigned int i; 37 38 printf("Valid reject types:\n"); 39 40 for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) { 41 printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc); 42 printf(" %-25s\talias\n", reject_table[i].alias); 43 } 44 printf("\n"); 45} 46 47/* Saves the union ipt_targinfo in parsable form to stdout. */ 48 49/* Function which prints out usage message. */ 50static void 51help(void) 52{ 53 printf( 54"REJECT options:\n" 55"--reject-with type drop input packet and send back\n" 56" a reply packet according to type:\n"); 57 58 print_reject_types(); 59} 60 61static struct option opts[] = { 62 { "reject-with", 1, 0, '1' }, 63 { 0 } 64}; 65 66/* Allocate and initialize the target. */ 67static void 68init(struct ipt_entry_target *t, unsigned int *nfcache) 69{ 70 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data; 71 72 /* default */ 73 reject->with = IPT_ICMP_PORT_UNREACHABLE; 74 75 /* Can't cache this */ 76 *nfcache |= NFC_UNKNOWN; 77} 78 79/* Function which parses command options; returns true if it 80 ate an option */ 81static int 82parse(int c, char **argv, int invert, unsigned int *flags, 83 const struct ipt_entry *entry, 84 struct ipt_entry_target **target) 85{ 86 struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; 87 unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names); 88 unsigned int i; 89 90 switch(c) { 91 case '1': 92 if (check_inverse(optarg, &invert)) 93 exit_error(PARAMETER_PROBLEM, 94 "Unexpected `!' after --reject-with"); 95 for (i = 0; i < limit; i++) { 96 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) 97 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { 98 reject->with = reject_table[i].with; 99 return 1; 100 } 101 } 102 exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg); 103 default: 104 /* Fall through */ 105 } 106 return 0; 107} 108 109/* Final check; nothing. */ 110static void final_check(unsigned int flags) 111{ 112} 113 114/* Prints out ipt_reject_info. */ 115static void 116print(const struct ipt_ip *ip, 117 const struct ipt_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 < sizeof(reject_table)/sizeof(struct reject_names); i++) { 125 if (reject_table[i].with == reject->with) 126 break; 127 } 128 printf("reject-with %s ", reject_table[i].name); 129} 130 131/* Saves ipt_reject in parsable form to stdout. */ 132static void save(const struct ipt_ip *ip, const struct ipt_entry_target *target) 133{ 134 const struct ipt_reject_info *reject 135 = (const struct ipt_reject_info *)target->data; 136 137 printf("--reject-with %s ", reject_table[reject->with].name); 138} 139 140struct iptables_target reject 141= { NULL, 142 "REJECT", 143 NETFILTER_VERSION, 144 sizeof(struct ipt_reject_info), 145 &help, 146 &init, 147 &parse, 148 &final_check, 149 &print, 150 &save, 151 opts 152}; 153 154void _init(void) 155{ 156 register_target(&reject); 157} 158