libipt_REJECT.c revision 193df8ee3507f0c02762c88a16916c4ea950bd99
121e463b2bf864671a87ebe386cb100ef9349a540Nate Begeman/* Shared library add-on to iptables to add customized REJECT support. 27c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner * 37c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner * (C) 2000 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 47c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner */ 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner#include <stdio.h> 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner#include <string.h> 77c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <stdlib.h> 87c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <getopt.h> 97c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <iptables.h> 107c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <linux/netfilter_ipv4/ip_tables.h> 117c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <linux/netfilter_ipv4/ipt_REJECT.h> 127c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner#include <linux/version.h> 137c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 147c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner/* If we are compiling against a kernel that does not support 157c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner * IPT_ICMP_ADMIN_PROHIBITED, we are emulating it. 167c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner * The result will be a plain DROP of the packet instead of 177c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner * reject. -- Maciej Soltysiak <solt@dns.toxicfilms.tv> 182668959b8879097db368aec7d76c455260abc75bChris Lattner */ 19331d1bc5dfe1be9090e29f9af9579888a63a9a79Chris Lattner#ifndef IPT_ICMP_ADMIN_PROHIBITED 2079aa3417eb6f58d668aadfedf075240a41d35a26Craig Topper#define IPT_ICMP_ADMIN_PROHIBITED IPT_TCP_RESET + 1 21a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#endif 227c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattner 237c5a3d390a463fb50a6eee7ae3174817925e6d28Chris Lattnerstruct reject_names { 240bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner const char *name; 250bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner const char *alias; 263c983c3dc19bb83807f978c04737b4572be90a93Nate Begeman enum ipt_reject_with with; 270ba2bcfcc3149a25d08aa8aa00fb6c34a4e25bddDan Gohman const char *desc; 280bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner}; 290bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner 300bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattnerstatic const struct reject_names reject_table[] = { 310bbea954331b8f08afa5b094dfb0841829c70eaaChris Lattner {"icmp-net-unreachable", "net-unreach", 3295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson IPT_ICMP_NET_UNREACHABLE, "ICMP network unreachable"}, 33c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman {"icmp-host-unreachable", "host-unreach", 34c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman IPT_ICMP_HOST_UNREACHABLE, "ICMP host unreachable"}, 35c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman {"icmp-proto-unreachable", "proto-unreach", 36c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman IPT_ICMP_PROT_UNREACHABLE, "ICMP protocol unreachable"}, 3795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson {"icmp-port-unreachable", "port-unreach", 3895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson IPT_ICMP_PORT_UNREACHABLE, "ICMP port unreachable (default)"}, 39c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman#if 0 40c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman {"echo-reply", "echoreply", 41c09eeec0ebc378644bafd04916e5efafa7d98152Nate Begeman IPT_ICMP_ECHOREPLY, "for ICMP echo only: faked ICMP echo reply"}, 4295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson#endif 435126984b1da4bda0e93961da07e883699f1f2d57Chris Lattner {"icmp-net-prohibited", "net-prohib", 44c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman IPT_ICMP_NET_PROHIBITED, "ICMP network prohibited"}, 455126984b1da4bda0e93961da07e883699f1f2d57Chris Lattner {"icmp-host-prohibited", "host-prohib", 4695771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson IPT_ICMP_HOST_PROHIBITED, "ICMP host prohibited"}, 47993aeb2ed93f99faf1438f1b67cd922989306828Nate Begeman {"tcp-reset", "tcp-rst", 48993aeb2ed93f99faf1438f1b67cd922989306828Nate Begeman IPT_TCP_RESET, "TCP RST packet"}, 49993aeb2ed93f99faf1438f1b67cd922989306828Nate Begeman {"icmp-admin-prohibited", "admin-prohib", 5095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson IPT_ICMP_ADMIN_PROHIBITED, "ICMP administratively prohibited (*)"} 51f1d0b2bedaa065972a5ba17259055c1176cd1497Chris Lattner}; 52f1d0b2bedaa065972a5ba17259055c1176cd1497Chris Lattner 53f1d0b2bedaa065972a5ba17259055c1176cd1497Chris Lattnerstatic void 5495771afbfd604ad003fa3723cac66c9370fed55dOwen Andersonprint_reject_types() 55860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner{ 56860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner unsigned int i; 57860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner 58860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner printf("Valid reject types:\n"); 59860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner 60860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) { 6195771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson printf(" %-25s\t%s\n", reject_table[i].name, reject_table[i].desc); 626b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller printf(" %-25s\talias\n", reject_table[i].alias); 636b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller } 643a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller printf("\n"); 653a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller} 663a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller 673a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller/* Saves the union ipt_targinfo in parsable form to stdout. */ 683a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller 693a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller/* Function which prints out usage message. */ 703a84dae654630a89a91a73807201b6067c4774ecTilmann Schellerstatic void 713a84dae654630a89a91a73807201b6067c4774ecTilmann Schellerhelp(void) 723a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller{ 733a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller printf( 743a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller"REJECT options:\n" 753a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller"--reject-with type drop input packet and send back\n" 763a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller" a reply packet according to type:\n"); 773a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller 783a84dae654630a89a91a73807201b6067c4774ecTilmann Scheller print_reject_types(); 792f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey 802f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey printf("(*) See man page or read the INCOMPATIBILITES file for compatibility issues.\n"); 812f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey} 822f616bff7ef1e2e08d6d23c2a8b42ec2bfebb173Jim Laskey 8395771afbfd604ad003fa3723cac66c9370fed55dOwen Andersonstatic struct option opts[] = { 84860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner { "reject-with", 1, 0, '1' }, 85860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner { 0 } 86860e8862c1fbd3b261da4a64a8c0096f9f373681Chris Lattner}; 8795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson 884172b10ca1adfc1026428e5f522aaab98bd939adChris Lattner/* Allocate and initialize the target. */ 894172b10ca1adfc1026428e5f522aaab98bd939adChris Lattnerstatic void 904172b10ca1adfc1026428e5f522aaab98bd939adChris Lattnerinit(struct xt_entry_target *t, unsigned int *nfcache) 914172b10ca1adfc1026428e5f522aaab98bd939adChris Lattner{ 9295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson struct ipt_reject_info *reject = (struct ipt_reject_info *)t->data; 93ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner 94ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner /* default */ 95ecfe55e65b6a72fddd543c42f2e2df4c96c647baChris Lattner reject->with = IPT_ICMP_PORT_UNREACHABLE; 969e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1Nate Begeman 97c703a8fbf8653ac8302ae368391a4954c307ca2cChris Lattner} 985b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel 995b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel/* Function which parses command options; returns true if it 1005b00ceaeeabff8c25abb09926343c3fcb06053d8Hal Finkel ate an option */ 10195771afbfd604ad003fa3723cac66c9370fed55dOwen Andersonstatic int 1026b16eff207f99bbde3c0f7340452a5287218772cTilmann Schellerparse(int c, char **argv, int invert, unsigned int *flags, 1036b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller const struct ipt_entry *entry, 1046b16eff207f99bbde3c0f7340452a5287218772cTilmann Scheller struct xt_entry_target **target) 105c703a8fbf8653ac8302ae368391a4954c307ca2cChris Lattner{ 106c703a8fbf8653ac8302ae368391a4954c307ca2cChris Lattner struct ipt_reject_info *reject = (struct ipt_reject_info *)(*target)->data; 107c703a8fbf8653ac8302ae368391a4954c307ca2cChris Lattner unsigned int limit = sizeof(reject_table)/sizeof(struct reject_names); 10895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson unsigned int i; 109c703a8fbf8653ac8302ae368391a4954c307ca2cChris Lattner 110c703a8fbf8653ac8302ae368391a4954c307ca2cChris Lattner switch(c) { 1112a9ddfb903ae3baede7282348afae1f750905248Tilmann Scheller case '1': 11295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson if (check_inverse(optarg, &invert, NULL, 0)) 1139e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1Nate Begeman exit_error(PARAMETER_PROBLEM, 1149e4dd9dfc97f3930f58ca6e47bebbd8eb5cdd8a1Nate Begeman "Unexpected `!' after --reject-with"); 11595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson for (i = 0; i < limit; i++) { 1165f07d5224ddc32f405d7e19de8e58e91ab2816bcDale Johannesen if ((strncasecmp(reject_table[i].name, optarg, strlen(optarg)) == 0) 1175f07d5224ddc32f405d7e19de8e58e91ab2816bcDale Johannesen || (strncasecmp(reject_table[i].alias, optarg, strlen(optarg)) == 0)) { 1185f07d5224ddc32f405d7e19de8e58e91ab2816bcDale Johannesen reject->with = reject_table[i].with; 1195f07d5224ddc32f405d7e19de8e58e91ab2816bcDale Johannesen return 1; 1206d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner } 121a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner } 122a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner /* This due to be dropped late in 2.4 pre-release cycle --RR */ 123a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner if (strncasecmp("echo-reply", optarg, strlen(optarg)) == 0 124a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner || strncasecmp("echoreply", optarg, strlen(optarg)) == 0) 125a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner fprintf(stderr, "--reject-with echo-reply no longer" 126a17b1557ad705c56c41624e6841e19093ed31f21Chris Lattner " supported\n"); 12795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson exit_error(PARAMETER_PROBLEM, "unknown reject type `%s'",optarg); 1286d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner default: 12995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson /* Fall through */ 1306d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner break; 1316d92caddc4aa5fc946b294259e00cc35536e61e8Chris Lattner } 13290564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner return 0; 13395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson} 13490564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner 13590564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner/* Final check; nothing. */ 13690564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattnerstatic void final_check(unsigned int flags) 13790564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner{ 13890564f26d17701e11effa2f4e0fb9a18d8a91274Chris Lattner} 139d9989384592a3bd9dd374470a723ca8303071a2dChris Lattner 14095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson/* Prints out ipt_reject_info. */ 1416eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesenstatic void 1426eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesenprint(const struct ipt_ip *ip, 1436eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen const struct xt_entry_target *target, 1446eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen int numeric) 1456eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen{ 1466eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen const struct ipt_reject_info *reject 1476eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen = (const struct ipt_reject_info *)target->data; 1486eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen unsigned int i; 1496eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen 1506eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) { 1516eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen if (reject_table[i].with == reject->with) 1526eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen break; 1536eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen } 1546eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen printf("reject-with %s ", reject_table[i].name); 15595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson} 1566eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen 1576eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen/* Saves ipt_reject in parsable form to stdout. */ 1586eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesenstatic void save(const struct ipt_ip *ip, const struct xt_entry_target *target) 1596eaeff29b8a6990107735f7e5f5e49da38f56223Dale Johannesen{ 16054fc97dcdc0ab747f49bd09c5a877bfd2a00e364Evan Cheng const struct ipt_reject_info *reject 16154fc97dcdc0ab747f49bd09c5a877bfd2a00e364Evan Cheng = (const struct ipt_reject_info *)target->data; 1628608f2eff2dab5345243c40d0bca9138f2dce6f1Evan Cheng unsigned int i; 16354fc97dcdc0ab747f49bd09c5a877bfd2a00e364Evan Cheng 1648608f2eff2dab5345243c40d0bca9138f2dce6f1Evan Cheng for (i = 0; i < sizeof(reject_table)/sizeof(struct reject_names); i++) 16554fc97dcdc0ab747f49bd09c5a877bfd2a00e364Evan Cheng if (reject_table[i].with == reject->with) 1668608f2eff2dab5345243c40d0bca9138f2dce6f1Evan Cheng break; 1678608f2eff2dab5345243c40d0bca9138f2dce6f1Evan Cheng 1688608f2eff2dab5345243c40d0bca9138f2dce6f1Evan Cheng printf("--reject-with %s ", reject_table[i].name); 16954fc97dcdc0ab747f49bd09c5a877bfd2a00e364Evan Cheng} 17030e62c098b5841259f8026df1c5c45c7c1182a38Arnold Schwaighofer 17130e62c098b5841259f8026df1c5c45c7c1182a38Arnold Schwaighoferstatic struct iptables_target reject = { 17230e62c098b5841259f8026df1c5c45c7c1182a38Arnold Schwaighofer .next = NULL, 17330e62c098b5841259f8026df1c5c45c7c1182a38Arnold Schwaighofer .name = "REJECT", 17430e62c098b5841259f8026df1c5c45c7c1182a38Arnold Schwaighofer .version = IPTABLES_VERSION, 175c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman .size = IPT_ALIGN(sizeof(struct ipt_reject_info)), 176c76909abfec876c6b751d693ebd3df07df686aa0Dan Gohman .userspacesize = IPT_ALIGN(sizeof(struct ipt_reject_info)), 17782b3821208286aeb43f603fdac98832bd662dad9Hal Finkel .help = &help, 17882b3821208286aeb43f603fdac98832bd662dad9Hal Finkel .init = &init, 17982b3821208286aeb43f603fdac98832bd662dad9Hal Finkel .parse = &parse, 18082b3821208286aeb43f603fdac98832bd662dad9Hal Finkel .final_check = &final_check, 181d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt .print = &print, 182d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt .save = &save, 183d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt .extra_opts = opts 184d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt}; 185d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt 186d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidtvoid _init(void) 187d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt{ 188d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt register_target(&reject); 189d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt} 190d7802bf0ddcac16ee910105922492aee86a53e1bBill Schmidt