libipt_REJECT.c revision bf97128c7262f17a02fec41cdae75b472ba77f88
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Shared library add-on to iptables to add customized REJECT support. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stdio.h> 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string.h> 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <stdlib.h> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <getopt.h> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <xtables.h> 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <linux/netfilter_ipv4/ipt_REJECT.h> 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <linux/version.h> 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)/* If we are compiling against a kernel that does not support 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) * IPT_ICMP_ADMIN_PROHIBITED, we are emulating it. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The result will be a plain DROP of the packet instead of 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reject. -- Maciej Soltysiak <solt@dns.toxicfilms.tv> 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef IPT_ICMP_ADMIN_PROHIBITED 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#define IPT_ICMP_ADMIN_PROHIBITED IPT_TCP_RESET + 1 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)struct reject_names { 2390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char *name; 2490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char *alias; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) enum ipt_reject_with with; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char *desc; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct reject_names reject_table[] = { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"icmp-net-unreachable", "net-unreach", 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"}, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"icmp-host-unreachable", "host-unreach", 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"}, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"icmp-proto-unreachable", "proto-unreach", 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"}, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"icmp-port-unreachable", "port-unreach", 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"}, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"echo-reply", "echoreply", 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"}, 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {"icmp-net-prohibited", "net-prohib", 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"}, 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"icmp-host-prohibited", "host-prohib", 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"}, 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"tcp-reset", "tcp-rst", 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPT_TCP_RESET, "TCP RST packet"}, 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) {"icmp-admin-prohibited", "admin-prohib", 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"} 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}; 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)static void 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)print_reject_types(void) 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unsigned int i; 5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf("Valid reject types:\n"); 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (i = 0; i < ARRAY_SIZE(reject_table); ++i) { 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc); 6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) printf(" %-25s\talias\n", reject_table[i].alias); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("\n"); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void REJECT_help(void) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf( 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"REJECT target options:\n" 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"--reject-with type drop input packet and send back\n" 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" a reply packet according to type:\n"); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) print_reject_types(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("(*) See man page or read the INCOMPATIBILITES file for compatibility issues.\n"); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const struct option REJECT_opts[] = { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "reject-with", 1, NULL, '1' }, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { .name = NULL } 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void REJECT_init(struct xt_entry_target *t) 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* default */ 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reject->with = IPT_ICMP_PORT_UNREACHABLE; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int REJECT_parse(int c, char **argv, int invert, unsigned int *flags, 9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const void *entry, struct xt_entry_target **target) 9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles){ 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const unsigned int limit = ARRAY_SIZE(reject_table); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(c) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case '1': 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xtables_check_inverse(optarg, &invert, NULL, 0, argv)) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unexpected `!' after --reject-with"); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < limit; i++) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reject->with = reject_table[i].with; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* This due to be dropped late in 2.4 pre-release cycle --RR */ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) || strncasecmp("echoreply", optarg, strlen(optarg)) == 0) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "--reject-with echo-reply no longer" 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) " supported\n"); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtables_error(PARAMETER_PROBLEM, "unknown reject type \"%s\"", optarg); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Fall through */ 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void REJECT_print(const void *ip, const struct xt_entry_target *target, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int numeric) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct ipt_reject_info *reject 12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) = (const struct ipt_reject_info *)target->data; 12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) unsigned int i; 13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < ARRAY_SIZE(reject_table); ++i) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reject_table[i].with == reject->with) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("reject-with %s ", reject_table[i].name); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void REJECT_save(const void *ip, const struct xt_entry_target *target) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const struct ipt_reject_info *reject 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) = (const struct ipt_reject_info *)target->data; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int i; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0; i < ARRAY_SIZE(reject_table); ++i) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (reject_table[i].with == reject->with) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("--reject-with %s ", reject_table[i].name); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct xtables_target reject_tg_reg = { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .name = "REJECT", 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .version = XTABLES_VERSION, 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .family = NFPROTO_IPV4, 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .size = XT_ALIGN(sizeof(struct ipt_reject_info)), 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .userspacesize = XT_ALIGN(sizeof(struct ipt_reject_info)), 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .help = REJECT_help, 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .init = REJECT_init, 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .parse = REJECT_parse, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .print = REJECT_print, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .save = REJECT_save, 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .extra_opts = REJECT_opts, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void _init(void) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xtables_register_target(&reject_tg_reg); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)