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