libipt_REJECT.c revision d09b6d591ca7d7d7575cb6aa20384c9830f777ab
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* Shared library add-on to iptables to add customized REJECT support. 2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stdbool.h> 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stdio.h> 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <string.h> 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <stdlib.h> 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <getopt.h> 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <xtables.h> 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <linux/netfilter_ipv4/ipt_REJECT.h> 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <linux/version.h> 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* If we are compiling against a kernel that does not support 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IPT_ICMP_ADMIN_PROHIBITED, we are emulating it. 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The result will be a plain DROP of the packet instead of 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * reject. -- Maciej Soltysiak <solt@dns.toxicfilms.tv> 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef IPT_ICMP_ADMIN_PROHIBITED 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define IPT_ICMP_ADMIN_PROHIBITED IPT_TCP_RESET + 1 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 23926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)struct reject_names { 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char *name; 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char *alias; 2619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) enum ipt_reject_with with; 2719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) const char *desc; 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}; 29c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 3051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)static const struct reject_names reject_table[] = { 31e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch {"icmp-net-unreachable", "net-unreach", 32e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"}, 33e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch {"icmp-host-unreachable", "host-unreach", 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"}, 35c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) {"icmp-proto-unreachable", "proto-unreach", 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"}, 37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) {"icmp-port-unreachable", "port-unreach", 387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"}, 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if 0 40f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu {"echo-reply", "echoreply", 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"}, 42f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#endif 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) {"icmp-net-prohibited", "net-prohib", 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"}, 45926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) {"icmp-host-prohibited", "host-prohib", 46926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"}, 4719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) {"tcp-reset", "tcp-rst", 4819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) IPT_TCP_RESET, "TCP RST packet"}, 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) {"icmp-admin-prohibited", "admin-prohib", 50f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"} 5119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)}; 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 53f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liustatic void 54f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liuprint_reject_types(void) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 5619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles) unsigned int i; 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 58f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu printf("Valid reject types:\n"); 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (i = 0; i < ARRAY_SIZE(reject_table); ++i) { 61c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc); 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) printf(" %-25s\talias\n", reject_table[i].alias); 637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci } 64 printf("\n"); 65} 66 67static void REJECT_help(void) 68{ 69 printf( 70"REJECT target options:\n" 71"--reject-with type drop input packet and send back\n" 72" a reply packet according to type:\n"); 73 74 print_reject_types(); 75 76 printf("(*) See man page or read the INCOMPATIBILITES file for compatibility issues.\n"); 77} 78 79static const struct option REJECT_opts[] = { 80 {.name = "reject-with", .has_arg = true, .val = '1'}, 81 XT_GETOPT_TABLEEND, 82}; 83 84static void REJECT_init(struct xt_entry_target *t) 85{ 86 struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data; 87 88 /* default */ 89 reject->with = IPT_ICMP_PORT_UNREACHABLE; 90 91} 92 93static int REJECT_parse(int c, char **argv, int invert, unsigned int *flags, 94 const void *entry, struct xt_entry_target **target) 95{ 96 struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; 97 static const unsigned int limit = ARRAY_SIZE(reject_table); 98 unsigned int i; 99 100 switch(c) { 101 case '1': 102 if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 103 xtables_error(PARAMETER_PROBLEM, 104 "Unexpected `!' after --reject-with"); 105 for (i = 0; i < limit; i++) { 106 if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) 107 || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { 108 reject->with = reject_table[i].with; 109 return 1; 110 } 111 } 112 /* This due to be dropped late in 2.4 pre-release cycle --RR */ 113 if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0 114 || strncasecmp("echoreply", optarg, strlen(optarg)) == 0) 115 fprintf(stderr, "--reject-with echo-reply no longer" 116 " supported\n"); 117 xtables_error(PARAMETER_PROBLEM, "unknown reject type \"%s\"", optarg); 118 break; 119 } 120 return 0; 121} 122 123static void REJECT_print(const void *ip, const struct xt_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 < ARRAY_SIZE(reject_table); ++i) 131 if (reject_table[i].with == reject->with) 132 break; 133 printf("reject-with %s ", reject_table[i].name); 134} 135 136static void REJECT_save(const void *ip, const struct xt_entry_target *target) 137{ 138 const struct ipt_reject_info *reject 139 = (const struct ipt_reject_info *)target->data; 140 unsigned int i; 141 142 for (i = 0; i < ARRAY_SIZE(reject_table); ++i) 143 if (reject_table[i].with == reject->with) 144 break; 145 146 printf("--reject-with %s ", reject_table[i].name); 147} 148 149static struct xtables_target reject_tg_reg = { 150 .name = "REJECT", 151 .version = XTABLES_VERSION, 152 .family = NFPROTO_IPV4, 153 .size = XT_ALIGN(sizeof(struct ipt_reject_info)), 154 .userspacesize = XT_ALIGN(sizeof(struct ipt_reject_info)), 155 .help = REJECT_help, 156 .init = REJECT_init, 157 .parse = REJECT_parse, 158 .print = REJECT_print, 159 .save = REJECT_save, 160 .extra_opts = REJECT_opts, 161}; 162 163void _init(void) 164{ 165 xtables_register_target(&reject_tg_reg); 166} 167