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