xtables.c revision 7e4db2f50133007f549f222468bde4f3adcf41ac
15208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI/* 25208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * (C) 2000-2006 by the netfilter coreteam <coreteam@netfilter.org>: 35208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * 45208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * This program is free software; you can redistribute it and/or modify 55208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * it under the terms of the GNU General Public License as published by 65208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * the Free Software Foundation; either version 2 of the License, or 75208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * (at your option) any later version. 85208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * 95208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * This program is distributed in the hope that it will be useful, 105208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * but WITHOUT ANY WARRANTY; without even the implied warranty of 115208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 125208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * GNU General Public License for more details. 135208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * 145208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * You should have received a copy of the GNU General Public License 155208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * along with this program; if not, write to the Free Software 165208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 175208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI */ 185208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI 193dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <errno.h> 200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <fcntl.h> 2104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI#include <netdb.h> 22aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt#include <stdarg.h> 23cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt#include <stdbool.h> 243dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdio.h> 253dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdlib.h> 260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <string.h> 270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <unistd.h> 280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#include <sys/socket.h> 290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/stat.h> 300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/types.h> 310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/wait.h> 3208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#include <arpa/inet.h> 333dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 345208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#include <xtables.h> 3577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt#include <linux/netfilter_ipv4/ip_tables.h> 3677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt#include <linux/netfilter_ipv6/ip6_tables.h> 37ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt#include <libiptc/libxtc.h> 383dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 395a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#ifndef NO_SHARED_LIBS 405a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#include <dlfcn.h> 415a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#endif 42c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#ifndef IPT_SO_GET_REVISION_MATCH /* Old kernel source. */ 43c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) 44c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) 45c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#endif 46c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#ifndef IP6T_SO_GET_REVISION_MATCH /* Old kernel source. */ 47c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IP6T_SO_GET_REVISION_MATCH 68 48c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IP6T_SO_GET_REVISION_TARGET 69 49c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#endif 5070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim#include <getopt.h> 51c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt 525a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger 530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#define NPROTO 255 540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 550b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#ifndef PROC_SYS_MODPROBE 560b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" 570b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#endif 580b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 598b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salimvoid basic_exit_err(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); 608b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim 6140a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salimstruct xtables_globals *xt_params = NULL; 6240a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 638b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salimvoid basic_exit_err(enum xtables_exittype status, const char *msg, ...) 6440a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim{ 6540a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim va_list args; 6640a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 6740a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim va_start(args, msg); 6840a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim fprintf(stderr, "%s v%s: ", xt_params->program_name, xt_params->program_version); 6940a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim vfprintf(stderr, msg, args); 7040a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim va_end(args); 7140a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim fprintf(stderr, "\n"); 7240a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim exit(status); 7340a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim} 7440a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 758b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim 76139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salimvoid xtables_free_opts(int reset_offset) 7784c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim{ 78139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim if (xt_params->opts != xt_params->orig_opts) { 79139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim free(xt_params->opts); 80139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim xt_params->opts = xt_params->orig_opts; 8184c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim if (reset_offset) 8284c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim xt_params->option_offset = 0; 8384c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim } 8484c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim} 8584c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim 8670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salimstruct option *xtables_merge_options(struct option *oldopts, 8770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim const struct option *newopts, 8870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim unsigned int *option_offset) 8970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim{ 9070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim unsigned int num_old, num_new, i; 9170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim struct option *merge; 9270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 9370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim if (newopts == NULL) 9470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return oldopts; 9570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 9670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (num_old = 0; oldopts[num_old].name; num_old++) ; 9770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (num_new = 0; newopts[num_new].name; num_new++) ; 9870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 9970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim xt_params->option_offset += OPTION_OFFSET; 10070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim *option_offset = xt_params->option_offset; 10170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 10270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim merge = malloc(sizeof(struct option) * (num_new + num_old + 1)); 10370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim if (merge == NULL) 10470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return NULL; 10570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim memcpy(merge, oldopts, num_old * sizeof(struct option)); 10670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim xtables_free_opts(0); /* Release any old options merged */ 10770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (i = 0; i < num_new; i++) { 10870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim merge[num_old + i] = newopts[i]; 10970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim merge[num_old + i].val += *option_offset; 11070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim } 11170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim memset(merge + num_old + num_new, 0, sizeof(struct option)); 11270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 11370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return merge; 11470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim} 11570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 116853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salimvoid xtables_set_revision(char *name, u_int8_t revision) 117853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim{ 118853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim /* Old kernel sources don't have ".revision" field, 119853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim * but we stole a byte from name. */ 120853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim name[XT_FUNCTION_MAXNAMELEN - 2] = '\0'; 121853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim name[XT_FUNCTION_MAXNAMELEN - 1] = revision; 122853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim} 123853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim 124dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt/** 12577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * xtables_afinfo - protocol family dependent information 12677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @kmod: kernel module basename (e.g. "ip_tables") 12777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @libprefix: prefix of .so library name (e.g. "libipt_") 12877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @family: nfproto family 12977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @ipproto: used by setsockopt (e.g. IPPROTO_IP) 13077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @so_rev_match: optname to check revision support of match 13177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @so_rev_target: optname to check revision support of target 13277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt */ 13377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstruct xtables_afinfo { 13477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt const char *kmod; 13577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt const char *libprefix; 13677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt uint8_t family; 13777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt uint8_t ipproto; 13877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt int so_rev_match; 13977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt int so_rev_target; 14077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 14177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 14277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv4 = { 14377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip_tables", 14477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libipt_", 14577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV4, 14677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IP, 14777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IPT_SO_GET_REVISION_MATCH, 14877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IPT_SO_GET_REVISION_TARGET, 14977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 15077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 15177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv6 = { 15277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip6_tables", 15377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libip6t_", 15477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV6, 15577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IPV6, 15677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IP6T_SO_GET_REVISION_MATCH, 15777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IP6T_SO_GET_REVISION_TARGET, 15877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 15977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 16077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo *afinfo; 16177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 16277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt/** 163dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt * Program will set this to its own name. 164dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt */ 165dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardtconst char *xtables_program_name; 166dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt 16739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt/* Search path for Xtables .so files */ 16839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtstatic const char *xtables_libdir; 1690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1700b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI/* the path to command to load kernel module */ 171c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtconst char *xtables_modprobe_program; 1720b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI/* Keeping track of external matches and targets: linked lists. */ 1740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_match *xtables_matches; 1750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_target *xtables_targets; 1760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 17739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtvoid xtables_init(void) 17839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt{ 17939bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("XTABLES_LIBDIR"); 18039bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) 18139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 18239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("IPTABLES_LIB_DIR"); 18339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) { 18439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt fprintf(stderr, "IPTABLES_LIB_DIR is deprecated, " 18539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt "use XTABLES_LIBDIR.\n"); 18639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 18739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt } 188ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt /* 189ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * Well yes, IP6TABLES_LIB_DIR is of lower priority over 190ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * IPTABLES_LIB_DIR since this moved to libxtables; I think that is ok 191ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * for these env vars are deprecated anyhow, and in light of the 192ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * (shared) libxt_*.so files, makes less sense to have 193ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * IPTABLES_LIB_DIR != IP6TABLES_LIB_DIR. 194ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt */ 195ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt xtables_libdir = getenv("IP6TABLES_LIB_DIR"); 196ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt if (xtables_libdir != NULL) { 197ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt fprintf(stderr, "IP6TABLES_LIB_DIR is deprecated, " 198ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt "use XTABLES_LIBDIR.\n"); 199ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt return; 200ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt } 20139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = XTABLES_LIBDIR; 20239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt} 20339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt 20477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtvoid xtables_set_nfproto(uint8_t nfproto) 20577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt{ 20677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt switch (nfproto) { 20777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV4: 20877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv4; 20977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 21077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV6: 21177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv6; 21277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 21377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt default: 21477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt fprintf(stderr, "libxtables: unhandled NFPROTO in %s\n", 21577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt __func__); 21677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt } 21777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt} 21877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 219630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt/** 2207e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * xtables_set_params - set the global parameters used by xtables 2217e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * @xtp: input xtables_globals structure 2227e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * 2237e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * The app is expected to pass a valid xtables_globals data-filled 2247e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * with proper values 2257e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * @xtp cannot be NULL 2267e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * 2277e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * Returns -1 on failure to set and 0 on success 2287e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim */ 2297e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salimint xtables_set_params(struct xtables_globals *xtp) 2307e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim{ 2317e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim if (!xtp) { 2327e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim fprintf(stderr, "%s: Illegal global params\n",__func__); 2337e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim return -1; 2347e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim } 2357e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2367e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xt_params = xtp; 2377e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2387e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim if (!xt_params->exit_err) 2397e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xt_params->exit_err = basic_exit_err; 2407e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2417e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim return 0; 2427e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim} 2437e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2447e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salimint xtables_init_all(struct xtables_globals *xtp, uint8_t nfproto) 2457e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim{ 2467e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xtables_init(); 2477e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xtables_set_nfproto(nfproto); 2487e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim return xtables_set_params(xtp); 2497e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim} 2507e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2517e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim/** 252630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt * xtables_*alloc - wrappers that exit on failure 253630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt */ 254630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_calloc(size_t count, size_t size) 2553dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 2563dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 2573dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2583dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = calloc(count, size)) == NULL) { 2593dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: calloc failed"); 2603dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 2613dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 2623dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2633dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 2643dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 2653dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 266630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_malloc(size_t size) 2673dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 2683dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 2693dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2703dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = malloc(size)) == NULL) { 2713dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: malloc failed"); 2723dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 2733dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 2743dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2753dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 2763dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 2770b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2780b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIstatic char *get_modprobe(void) 2790b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 2800b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int procfile; 2810b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *ret; 2820b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2830b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROCFILE_BUFSIZ 1024 2840b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI procfile = open(PROC_SYS_MODPROBE, O_RDONLY); 2850b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (procfile < 0) 2860b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 2870b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2880b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret = (char *) malloc(PROCFILE_BUFSIZ); 2890b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret) { 2900b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI memset(ret, 0, PROCFILE_BUFSIZ); 2910b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (read(procfile, ret, PROCFILE_BUFSIZ)) { 2920b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: goto fail; 2930b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */ 2940b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 2950b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret[strlen(ret)-1]=='\n') 2960b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret[strlen(ret)-1]=0; 2970b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 2980b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return ret; 2990b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3000b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI fail: 3010b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(ret); 3020b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 3030b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 3040b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 3050b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 306c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_insmod(const char *modname, const char *modprobe, bool quiet) 3070b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 3080b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *buf = NULL; 3090b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *argv[4]; 3100b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int status; 3110b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3120b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* If they don't explicitly set it, read out of kernel */ 3130b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!modprobe) { 3140b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI buf = get_modprobe(); 3150b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!buf) 3160b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3170b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI modprobe = buf; 3180b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3190b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 320c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt /* 321c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt * Need to flush the buffer, or the child may output it again 322c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt * when switching the program thru execv. 323c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt */ 324c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt fflush(stdout); 325c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt 3260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (fork()) { 3270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case 0: 3280b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[0] = (char *)modprobe; 3290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[1] = (char *)modname; 3300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (quiet) { 3310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = "-q"; 3320b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 3330b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } else { 3340b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = NULL; 3350b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 3360b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3370b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI execv(argv[0], argv); 3380b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3390b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* not usually reached */ 3400b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI exit(1); 3410b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: 3420b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3430b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3440b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI default: /* parent */ 3450b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI wait(&status); 3460b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3470b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3480b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(buf); 3490b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 3500b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return 0; 3510b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3520b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 3530b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 354c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_load_ko(const char *modprobe, bool quiet) 3550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 356c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt static bool loaded = false; 3570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI static int ret = -1; 3580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!loaded) { 36077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ret = xtables_insmod(afinfo->kmod, modprobe, quiet); 3610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI loaded = (ret == 0); 3620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ret; 3650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 3660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3675f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt/** 3685f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * xtables_strtou{i,l} - string to number conversion 3695f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @s: input string 3705f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @end: like strtoul's "end" pointer 3715f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @value: pointer for result 3725f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @min: minimum accepted value 3735f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @max: maximum accepted value 3745f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * 3755f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * If @end is NULL, we assume the caller wants a "strict strtoul", and hence 3765f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * "15a" is rejected. 3775f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * In either case, the value obtained is compared for min-max compliance. 3785f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Base is always 0, i.e. autodetect depending on @s. 379cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt * 3805f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Returns true/false whether number was accepted. On failure, *value has 3815f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * undefined contents. 382cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt */ 3835f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoul(const char *s, char **end, unsigned long *value, 3845f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned long min, unsigned long max) 385cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 386cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt unsigned long v; 387cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt char *my_end; 388cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 389cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt errno = 0; 390cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt v = strtoul(s, &my_end, 0); 391cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 392cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (my_end == s) 393cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 394cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end != NULL) 395cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *end = my_end; 396cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 397cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (errno != ERANGE && min <= v && (max == 0 || v <= max)) { 398cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 399cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 400cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end == NULL) 401cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return *my_end == '\0'; 402cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return true; 403cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt } 404cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 405cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 406cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 407cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 4085f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoui(const char *s, char **end, unsigned int *value, 4095f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned int min, unsigned int max) 410cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 411cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt unsigned long v; 412cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt bool ret; 413cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 4145f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt ret = xtables_strtoul(s, end, &v, min, max); 415cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 416cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 417cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return ret; 418cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 419cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 420aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtint xtables_service_to_port(const char *name, const char *proto) 42104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 42204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI struct servent *service; 42304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 42404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((service = getservbyname(name, proto)) != NULL) 42504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return ntohs((unsigned short) service->s_port); 42604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 42704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return -1; 42804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 42904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 430aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtu_int16_t xtables_parse_port(const char *port, const char *proto) 43104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 4327a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt unsigned int portnum; 43304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4345f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (xtables_strtoui(port, NULL, &portnum, 0, UINT16_MAX) || 435aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt (portnum = xtables_service_to_port(port, proto)) != (unsigned)-1) 436213e185afbb298e6708881e4c2adffdc47a8b6daJan Engelhardt return portnum; 43704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4388b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 43904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "invalid port/service `%s' specified", port); 44004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 44104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 442aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtvoid xtables_parse_interface(const char *arg, char *vianame, 443aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt unsigned char *mask) 44404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 44504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI int vialen = strlen(arg); 44604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int i; 44704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 44804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 44904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(vianame, 0, IFNAMSIZ); 45004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 45104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vialen + 1 > IFNAMSIZ) 4528b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 45304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "interface name `%s' must be shorter than IFNAMSIZ" 45404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI " (%i)", arg, IFNAMSIZ-1); 45504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 45604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI strcpy(vianame, arg); 45704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((vialen == 0) || (vialen == 1 && vianame[0] == '+')) 45804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 45904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI else if (vianame[vialen - 1] == '+') { 46004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen - 1); 46104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1); 46204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Don't remove `+' here! -HW */ 46304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } else { 46404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Include nul-terminator in match */ 46504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen + 1); 46604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1); 46704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI for (i = 0; vianame[i]; i++) { 46804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vianame[i] == ':' || 46904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '!' || 47004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '*') { 471aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann fprintf(stderr, 472aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann "Warning: weird character in interface" 473aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann " `%s' (No aliases, :, ! or *).\n", 474aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann vianame); 47504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI break; 47604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 47704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 47804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 47904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 48004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 481cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#ifndef NO_SHARED_LIBS 48221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardtstatic void *load_extension(const char *search_path, const char *prefix, 48321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *name, bool is_target) 48421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt{ 48521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *dir = search_path, *next; 48621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt void *ptr = NULL; 48721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt struct stat sb; 48821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt char path[256]; 48921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 49021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt do { 49121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = strchr(dir, ':'); 49221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (next == NULL) 49321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = dir + strlen(dir); 49421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt snprintf(path, sizeof(path), "%.*s/libxt_%s.so", 4952c0a0c9eba1d1ab39dcde54bc822d4788f9531fcJan Engelhardt (unsigned int)(next - dir), dir, name); 49621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 49721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (dlopen(path, RTLD_NOW) != NULL) { 49821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt /* Found library. If it didn't register itself, 49921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt maybe they specified target as match. */ 50021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 5012338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 50221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 5032338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 5042338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 50521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } else if (stat(path, &sb) == 0) { 50621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 50721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } 50821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 50921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (ptr != NULL) 51021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return ptr; 51121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 51221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt snprintf(path, sizeof(path), "%.*s/%s%s.so", 5132c0a0c9eba1d1ab39dcde54bc822d4788f9531fcJan Engelhardt (unsigned int)(next - dir), dir, prefix, name); 51421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (dlopen(path, RTLD_NOW) != NULL) { 51521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 5162338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 51721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 5182338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 5192338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 52021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } else if (stat(path, &sb) == 0) { 52121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 52221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } 52321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 52421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (ptr != NULL) 52521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return ptr; 52621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 52721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt dir = next + 1; 52821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } while (*next != '\0'); 52921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 53021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return NULL; 53121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt} 532cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#endif 53321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 5342338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_match * 5352338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_match(const char *name, enum xtables_tryload tryload, 5362338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt struct xtables_rule_match **matches) 5370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 5380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *ptr; 5390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI const char *icmp6 = "icmp6"; 5400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is ugly as hell. Nonetheless, there is no way of changing 5420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI * this without hurting backwards compatibility */ 5430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if ( (strcmp(name,"icmpv6") == 0) || 5440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"ipv6-icmp") == 0) || 5450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"icmp6") == 0) ) 5460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = icmp6; 5470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_matches; ptr; ptr = ptr->next) { 5490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) { 5500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *clone; 5510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* First match of this type: */ 5530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr->m == NULL) 5540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 5550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Second and subsequent clones */ 557630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt clone = xtables_malloc(sizeof(struct xtables_match)); 5580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI memcpy(clone, ptr, sizeof(struct xtables_match)); 5590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->mflags = 0; 5600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is a clone: */ 5610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->next = clone; 5620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = clone; 5640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 5650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 5692338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 57077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 57139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, false); 572170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 5732338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 5748b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 5750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load match `%s':%s\n", 5760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 5770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 5790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 5802338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 5810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 5820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 5830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 5840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5852338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if(!ptr && (tryload == XTF_LOAD_MUST_SUCCEED)) { 5868b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 5870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find match `%s'\n", name); 5880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 5900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && matches) { 5920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match **i; 5930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match *newentry; 5940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 595630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt newentry = xtables_malloc(sizeof(struct xtables_rule_match)); 5960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = matches; *i; i = &(*i)->next) { 5980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, (*i)->match->name) == 0) 5992338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt (*i)->completed = true; 6000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->match = ptr; 6022338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt newentry->completed = false; 6030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->next = NULL; 6040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = newentry; 6050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 6080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6102338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_target * 6112338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_target(const char *name, enum xtables_tryload tryload) 6120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 6130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *ptr; 6140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Standard target? */ 6160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, "") == 0 6170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_ACCEPT) == 0 6180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_DROP) == 0 6190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_QUEUE) == 0 6200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_RETURN) == 0) 6210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = "standard"; 6220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_targets; ptr; ptr = ptr->next) { 6240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) 6250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 6260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 6292338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 63077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 63139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, true); 632170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 6332338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 6348b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 6350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load target `%s':%s\n", 6360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 6370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 6390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 6402338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 6410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 6420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 6430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 6440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if(!ptr && (tryload == LOAD_MUST_SUCCEED)) { 6468b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 6470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find target `%s'\n", name); 6480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 6500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr) 6520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->used = 1; 6530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 6550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_revision(const char *name, u_int8_t revision, int opt) 6580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 6590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xt_get_revision rev; 6600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI socklen_t s = sizeof(rev); 6610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI int max_rev, sockfd; 6620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 66377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt sockfd = socket(afinfo->family, SOCK_RAW, IPPROTO_RAW); 6640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (sockfd < 0) { 665df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (errno == EPERM) { 666df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy /* revision 0 is always supported. */ 667df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (revision != 0) 668df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy fprintf(stderr, "Could not determine whether " 669df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "revision %u is supported, " 670df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "assuming it is.\n", 671df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy revision); 672df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy return 1; 673df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy } 6740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "Could not open socket to kernel: %s\n", 6750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 6760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 679c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt xtables_load_ko(xtables_modprobe_program, true); 6800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strcpy(rev.name, name); 6820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI rev.revision = revision; 6830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 68477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); 6850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (max_rev < 0) { 6860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Definitely don't support this? */ 6870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (errno == ENOENT || errno == EPROTONOSUPPORT) { 6880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 6890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 0; 6900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else if (errno == ENOPROTOOPT) { 6910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 6920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Assume only revision 0 support (old kernel) */ 6930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return (revision == 0); 6940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else { 6950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "getsockopt failed strangely: %s\n", 6960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 6970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 7010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 1; 7020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_match_revision(const char *name, u_int8_t revision) 7060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 70777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_match); 7080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_target_revision(const char *name, u_int8_t revision) 7110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 71277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_target); 7130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_match(struct xtables_match *me) 7160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 7170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match **i, *old; 7180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 719dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 720dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: match \"%s\" has version \"%s\", " 721dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 722dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, 723dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 7240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 7280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 7290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 730dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 7350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 7360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: match %s has invalid protocol family\n", 737dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested match */ 74277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 7430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7452338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); 7460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 74723545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && 74823545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt old->family == me->family) { 7490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 7500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: match `%s' already registered.\n", 751dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 7560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_match_revision(old->name, old->revision) 7570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 7580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 76023545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new match can be used. */ 7610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_match_revision(me->name, me->revision)) 7620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 76423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */ 76523545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && me->family == AF_UNSPEC) 76623545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt return; 76723545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt 7680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 7690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i!=old; i = &(*i)->next); 7700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 7710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 7740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: match `%s' has invalid size %u.\n", 775dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, (unsigned int)me->size); 7760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Append to list. */ 7800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i; i = &(*i)->next); 7810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = NULL; 7820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = me; 7830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->m = NULL; 7850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->mflags = 0; 7860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_target(struct xtables_target *me) 7890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 7900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *old; 7910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 792dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 793dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: target \"%s\" has version \"%s\", " 794dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 795dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, 796dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 7970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 8010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 8020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 803dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 8040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 8080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 8090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: target %s has invalid protocol family\n", 810dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 8110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested target */ 81577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 8160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8182338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_target(me->name, XTF_DURING_LOAD); 8190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 8200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target **i; 8210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 82223545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && 82323545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt old->family == me->family) { 8240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 8250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: target `%s' already registered.\n", 826dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 8270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 8310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_target_revision(old->name, old->revision) 8320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 8330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 83523545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new target can be used. */ 8360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_target_revision(me->name, me->revision)) 8370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 83923545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */ 84023545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && me->family == AF_UNSPEC) 84123545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt return; 84223545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt 8430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 8440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_targets; *i!=old; i = &(*i)->next); 8450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 8460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 8490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid size %u.\n", 850dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, (unsigned int)me->size); 8510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Prepend to list. */ 8550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = xtables_targets; 8560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI xtables_targets = me; 8570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->t = NULL; 8580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->tflags = 0; 8590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 860aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 861a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt/** 862a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * xtables_param_act - act on condition 863a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @status: a constant from enum xtables_exittype 864a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 865a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONLY_ONCE: print error message that option may only be used once. 866a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name (e.g. "mark") 867a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2(...): option in conflict (e.g. "--mark") 868a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3(...): condition to match on (see extensions/ for examples) 869a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 870a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_NO_INVERT: option does not support inversion 871a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 872a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option in conflict 873a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: condition to match on 874a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 875a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_BAD_VALUE: bad value for option 876a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 877a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option with which the problem occured (e.g. "--mark") 878a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: string the user passed in (e.g. "99999999999999") 879a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 880a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONE_ACTION: two mutually exclusive actions have been specified 881a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 882a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 883a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * Displays an error message and exits the program. 884a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt */ 885a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardtvoid xtables_param_act(unsigned int status, const char *p1, ...) 886aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt{ 887aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt const char *p2, *p3; 888aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_list args; 889aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt bool b; 890aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 891aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_start(args, p1); 892aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 893aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt switch (status) { 894a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONLY_ONCE: 895aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 896aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 897aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 898aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 8998b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 900aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option may only be specified once", 901aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2); 902aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 903a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_NO_INVERT: 904aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 905aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 906aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 907aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 9088b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 909aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option cannot be inverted", p1, p2); 910aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 911a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_BAD_VALUE: 912aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 913aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p3 = va_arg(args, const char *); 9148b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 915aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: Bad value for \"%s\" option: \"%s\"", 916aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2, p3); 917aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 918a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONE_ACTION: 919aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 920aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 921aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 9228b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 923aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: At most one action is possible", p1); 924aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 925aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt default: 9268b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(status, p1, args); 927aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 928aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt } 929aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 930aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_end(args); 931aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt} 93208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 933e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_numeric(const struct in_addr *addrp) 93408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 93508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 93608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const unsigned char *bytep = (const void *)&addrp->s_addr; 93708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 93808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]); 93908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 94008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 94108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 94208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_host(const struct in_addr *addr) 94308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 94408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct hostent *host; 94508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 94608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt host = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET); 94708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (host == NULL) 94808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 94908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 95008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return host->h_name; 95108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 95208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 95308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_network(const struct in_addr *addr) 95408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 95508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct netent *net; 95608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 95708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((net = getnetbyaddr(ntohl(addr->s_addr), AF_INET)) != NULL) 95808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return net->n_name; 95908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 96008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 96108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 96208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 963e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_anyname(const struct in_addr *addr) 96408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 96508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 96608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 96708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ipaddr_to_host(addr)) != NULL || 96808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt (name = ipaddr_to_network(addr)) != NULL) 96908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 97008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 971e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ipaddr_to_numeric(addr); 97208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 97308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 974e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipmask_to_numeric(const struct in_addr *mask) 97508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 97608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 97708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t maskaddr, bits; 97808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int i; 97908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 98008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt maskaddr = ntohl(mask->s_addr); 98108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 98208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (maskaddr == 0xFFFFFFFFL) 98308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* we don't want to see "/32" */ 98408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return ""; 98508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 98608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt i = 32; 98708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits = 0xFFFFFFFEL; 98808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (--i >= 0 && maskaddr != bits) 98908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits <<= 1; 99008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (i >= 0) 99108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", i); 99208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt else 99308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* mask was not a decent combination of 1's and 0's */ 994e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); 99508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 99608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 99708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 99808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 999bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *__numeric_to_ipaddr(const char *dotted, bool is_mask) 1000bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1001bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 1002bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned char *addrp; 1003bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int onebyte; 1004bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[20], *p, *q; 1005bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int i; 1006bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1007bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* copy dotted string, because we need to modify it */ 1008bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, dotted, sizeof(buf) - 1); 1009bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1010bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = (void *)&addr.s_addr; 1011bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1012bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = buf; 1013bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < 3; ++i) { 1014bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((q = strchr(p, '.')) == NULL) { 1015bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (is_mask) 1016bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1017bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1018bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* autocomplete, this is a network address */ 10195f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1020bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1021bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1022bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 1023bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (i < 3) 1024bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[++i] = 0; 1025bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1026bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1027bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1028bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1029bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *q = '\0'; 10305f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1031bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1032bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1033bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 1034bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = q + 1; 1035bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1036bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1037bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* we have checked 3 bytes, now we check the last one */ 10385f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1039bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1040bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1041bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[3] = onebyte; 1042bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1043bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1044bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 10451e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipaddr(const char *dotted) 1046bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1047bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, false); 1048bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1049bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 10501e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipmask(const char *dotted) 1051bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1052bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, true); 1053bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1054bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1055bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *network_to_ipaddr(const char *name) 1056bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1057bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 1058bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct netent *net; 1059bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1060bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((net = getnetbyname(name)) != NULL) { 1061bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (net->n_addrtype != AF_INET) 1062bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1063bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addr.s_addr = htonl(net->n_net); 1064bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1065bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1066bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1067bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1068bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1069bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1070bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *host_to_ipaddr(const char *name, unsigned int *naddr) 1071bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1072bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct hostent *host; 1073bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addr; 1074bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i; 1075bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1076bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1077bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((host = gethostbyname(name)) != NULL) { 1078bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (host->h_addrtype != AF_INET || 1079bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt host->h_length != sizeof(struct in_addr)) 1080bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1081bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1082bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (host->h_addr_list[*naddr] != NULL) 1083bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++*naddr; 1084630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addr = xtables_calloc(*naddr, sizeof(struct in_addr) * *naddr); 1085bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < *naddr; i++) 1086bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(&addr[i], host->h_addr_list[i], 1087bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in_addr)); 1088bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1089bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1090bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1091bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1092bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1093bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1094bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr * 1095bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtipparse_hostnetwork(const char *name, unsigned int *naddrs) 1096bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1097bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrptmp, *addrp; 1098bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 10991e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ipaddr(name)) != NULL || 1100bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ipaddr(name)) != NULL) { 1101630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in_addr)); 1102bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1103bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1104bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1105bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1106bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrptmp = host_to_ipaddr(name, naddrs)) != NULL) 1107bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrptmp; 1108bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 11098b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1110bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1111bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1112bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *parse_ipmask(const char *mask) 1113bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1114bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr maskaddr; 1115bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1116bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1117bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1118bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1119bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 32 bits */ 1120bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0xFFFFFFFF; 1121bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1122bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 11231e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ipmask(mask)) != NULL) 1124bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* dotted_to_addr already returns a network byte order addr */ 1125bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 11265f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 32)) 11278b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1128bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1129bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1130bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); 1131bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1132bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1133bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1134bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0U; 1135bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1136bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1137bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1138a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt/** 1139a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * xtables_ipparse_any - transform arbitrary name to in_addr 1140a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * 1141a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * Possible inputs (pseudo regex): 1142a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * m{^($hostname|$networkname|$ipaddr)(/$mask)?} 1143a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * "1.2.3.4/5", "1.2.3.4", "hostname", "networkname" 1144a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt */ 1145a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ipparse_any(const char *name, struct in_addr **addrpp, 1146a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in_addr *maskp, unsigned int *naddrs) 1147bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1148bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1149bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1150bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1151bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1152bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1153bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1154bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1155bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1156bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(p + 1); 1157bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1158bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(NULL); 1159bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1160bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1161bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1162bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1163bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (maskp->s_addr == 0U) 1164bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "0.0.0.0"); 1165bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1166bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ipparse_hostnetwork(buf, naddrs); 1167bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1168bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1169bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[j++].s_addr &= maskp->s_addr; 1170bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1171bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (addrp[k].s_addr == addrp[j-1].s_addr) { 1172bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --*naddrs; 1173bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --j; 1174bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1175bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1176bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1177bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1178bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1179e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_numeric(const struct in6_addr *addrp) 118008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 118108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* 0000:0000:0000:0000:0000:000.000.000.000 118208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt * 0000:0000:0000:0000:0000:0000:0000:0000 */ 118308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+1]; 118408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); 118508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 118608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 118708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ip6addr_to_host(const struct in6_addr *addr) 118808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 118908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char hostname[NI_MAXHOST]; 119008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct sockaddr_in6 saddr; 119108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int err; 119208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 119308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memset(&saddr, 0, sizeof(struct sockaddr_in6)); 119408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memcpy(&saddr.sin6_addr, addr, sizeof(*addr)); 119508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt saddr.sin6_family = AF_INET6; 119608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 119708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt err = getnameinfo((const void *)&saddr, sizeof(struct sockaddr_in6), 119808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt hostname, sizeof(hostname) - 1, NULL, 0, 0); 119908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (err != 0) { 120008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 120108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf(stderr,"IP2Name: %s\n",gai_strerror(err)); 120208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 120308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 120408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 120508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 120608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 120708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf (stderr, "\naddr2host: %s\n", hostname); 120808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 120908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return hostname; 121008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 121108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1212e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_anyname(const struct in6_addr *addr) 121308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 121408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 121508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 121608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ip6addr_to_host(addr)) != NULL) 121708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 121808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1219e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ip6addr_to_numeric(addr); 122008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 122108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 122208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic int ip6addr_prefix_length(const struct in6_addr *k) 122308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 122408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt unsigned int bits = 0; 122508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t a, b, c, d; 122608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 122748607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt a = ntohl(k->s6_addr32[0]); 122848607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt b = ntohl(k->s6_addr32[1]); 122948607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt c = ntohl(k->s6_addr32[2]); 123048607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt d = ntohl(k->s6_addr32[3]); 123108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (a & 0x80000000U) { 123208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt ++bits; 123308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a <<= 1; 123408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a |= (b >> 31) & 1; 123508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b <<= 1; 123608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b |= (c >> 31) & 1; 123708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c <<= 1; 123808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c |= (d >> 31) & 1; 123908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt d <<= 1; 124008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 124108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (a != 0 || b != 0 || c != 0 || d != 0) 124208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return -1; 124308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return bits; 124408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 124508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1246e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6mask_to_numeric(const struct in6_addr *addrp) 124708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 124808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+2]; 124908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int l = ip6addr_prefix_length(addrp); 125008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 125108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (l == -1) { 125208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt strcpy(buf, "/"); 1253e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt strcat(buf, xtables_ip6addr_to_numeric(addrp)); 125408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 125508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 125608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", l); 125708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 125808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 1259bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 12601e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in6_addr *xtables_numeric_to_ip6addr(const char *num) 1261bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1262bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr ap; 1263bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1264bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1265bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = inet_pton(AF_INET6, num, &ap)) == 1) 1266bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return ≈ 1267bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1268bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "\nnumeric2addr: %d\n", err); 1269bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1270bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1271bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1272bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1273bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1274bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardthost_to_ip6addr(const char *name, unsigned int *naddr) 1275bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1276bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr *addr; 1277bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo hints; 1278bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo *res; 1279bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1280bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1281bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&hints, 0, sizeof(hints)); 1282bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_flags = AI_CANONNAME; 1283bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_family = AF_INET6; 1284bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_socktype = SOCK_RAW; 1285bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_protocol = IPPROTO_IPV6; 1286bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_next = NULL; 1287bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1288bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1289bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { 1290bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1291bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); 1292bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1293bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1294bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1295bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (res->ai_family != AF_INET6 || 1296bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt res->ai_addrlen != sizeof(struct sockaddr_in6)) 1297bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1298bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1299bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1300bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, 1301bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ip6addr_to_numeric(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)); 1302bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1303bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* Get the first element of the address-chain */ 1304630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addr = xtables_malloc(sizeof(struct in6_addr)); 1305bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addr, &((const struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 1306bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in6_addr)); 1307bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt freeaddrinfo(res); 1308bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 1; 1309bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1310bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1311bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1312bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1313bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1314bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1315bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *network_to_ip6addr(const char *name) 1316bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1317bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* abort();*/ 1318bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* TODO: not implemented yet, but the exception breaks the 1319bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt * name resolvation */ 1320bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1321bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1322bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1323bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1324bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtip6parse_hostnetwork(const char *name, unsigned int *naddrs) 1325bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1326bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp, *addrptmp; 1327bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 13281e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ip6addr(name)) != NULL || 1329bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ip6addr(name)) != NULL) { 1330630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in6_addr)); 1331bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1332bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1333bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1334bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1335bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrp = host_to_ip6addr(name, naddrs)) != NULL) 1336bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1337bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 13388b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1339bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1340bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1341bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *parse_ip6mask(char *mask) 1342bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1343bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr maskaddr; 1344bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1345bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1346bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1347bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1348bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 128 bits */ 1349bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0xff, sizeof maskaddr); 1350bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1351bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 13521e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ip6addr(mask)) != NULL) 1353bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 13545f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 128)) 13558b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1356bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1357bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1358bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char *p = (void *)&maskaddr; 1359bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p, 0xff, bits / 8); 1360bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p + (bits / 8) + 1, 0, (128 - bits) / 8); 1361bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p[bits/8] = 0xff << (8 - (bits & 7)); 1362bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1363bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1364bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1365bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0, sizeof(maskaddr)); 1366bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1367bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1368bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1369a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ip6parse_any(const char *name, struct in6_addr **addrpp, 1370a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in6_addr *maskp, unsigned int *naddrs) 1371bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1372bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1373bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1374bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1375bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1376bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1377bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf)-1] = '\0'; 1378bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1379bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1380bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(p + 1); 1381bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1382bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(NULL); 1383bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1384bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1385bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1386bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1387bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (memcmp(maskp, &in6addr_any, sizeof(in6addr_any)) == 0) 1388bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "::"); 1389bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1390bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ip6parse_hostnetwork(buf, naddrs); 1391bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1392bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1393bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < 4; ++k) 13945a2208c3e62a150e6f6297abbfa63056ab4a8066Yasuyuki Kozakai addrp[j].s6_addr32[k] &= maskp->s6_addr32[k]; 1395bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++j; 1396bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1397bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (IN6_ARE_ADDR_EQUAL(&addrp[k], &addrp[j - 1])) { 1398bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --*naddrs; 1399bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --j; 1400bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1401bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1402bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1403bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1404a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1405a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_save_string(const char *value) 1406a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann{ 1407a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char no_quote_chars[] = "_-0123456789" 1408a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "abcdefghijklmnopqrstuvwxyz" 1409a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 1410a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char escape_chars[] = "\"\\'"; 1411a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann size_t length; 1412a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann const char *p; 1413a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1414a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann length = strcspn(value, no_quote_chars); 1415a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (length > 0 && value[length] == 0) { 1416a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* no quoting required */ 1417a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 1418a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(' '); 1419a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } else { 1420a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* there is at least one dangerous character in the 1421a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value, which we have to quote. Write double quotes 1422a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann around the value and escape special characters with 1423a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann a backslash */ 1424a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('"'); 1425a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1426a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann for (p = strpbrk(value, escape_chars); p != NULL; 1427a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann p = strpbrk(value, escape_chars)) { 1428a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (p > value) 1429a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fwrite(value, 1, p - value, stdout); 1430a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('\\'); 1431a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(*p); 1432a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value = p + 1; 1433a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1434a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1435a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* print the rest and finish the double quoted 1436a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann string */ 1437a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 1438a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann printf("\" "); 1439a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1440a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann} 14410f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 14420f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt/** 14430f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt * Check for option-intrapositional negation. 14440f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt * Do not use in new code. 14450f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt */ 14460f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardtint xtables_check_inverse(const char option[], int *invert, 14470f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt int *my_optind, int argc) 14480f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt{ 14490f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (option && strcmp(option, "!") == 0) { 14500f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt fprintf(stderr, "Using intrapositioned negation " 14510f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "(`--option ! this`) is deprecated in favor of " 14520f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "extrapositioned (`! --option this`).\n"); 14530f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 14540f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (*invert) 14558b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 14560f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "Multiple `!' flags not allowed"); 14570f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt *invert = true; 14580f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (my_optind != NULL) { 14590f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt ++*my_optind; 14600f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (argc && *my_optind > argc) 14618b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 14620f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "no argument following `!'"); 14630f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt } 14640f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 14650f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt return true; 14660f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt } 14670f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt return false; 14680f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt} 14691de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14701de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtconst struct xtables_pprot xtables_chain_protos[] = { 14711de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"tcp", IPPROTO_TCP}, 14721de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"sctp", IPPROTO_SCTP}, 14731de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udp", IPPROTO_UDP}, 14741de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udplite", IPPROTO_UDPLITE}, 14751de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmp", IPPROTO_ICMP}, 14761de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmpv6", IPPROTO_ICMPV6}, 14771de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-icmp", IPPROTO_ICMPV6}, 14781de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"esp", IPPROTO_ESP}, 14791de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ah", IPPROTO_AH}, 14801de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-mh", IPPROTO_MH}, 14811de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"mh", IPPROTO_MH}, 14821de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"all", 0}, 14831de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {NULL}, 14841de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt}; 14851de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14861de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtu_int16_t 14871de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtxtables_parse_protocol(const char *s) 14881de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt{ 14891de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt unsigned int proto; 14901de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14911de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (!xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX)) { 14921de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt struct protoent *pent; 14931de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14941de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt /* first deal with the special case of 'all' to prevent 14951de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * people from being able to redefine 'all' in nsswitch 14961de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * and/or provoke expensive [not working] ldap/nis/... 14971de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * lookups */ 14981de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (!strcmp(s, "all")) 14991de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt return 0; 15001de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 15011de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if ((pent = getprotobyname(s))) 15021de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt proto = pent->p_proto; 15031de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt else { 15041de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt unsigned int i; 15051de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) { 15061de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (strcmp(s, xtables_chain_protos[i].name) == 0) { 15071de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt proto = xtables_chain_protos[i].num; 15081de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt break; 15091de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15101de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15111de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (i == ARRAY_SIZE(xtables_chain_protos)) 15128b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 15131de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt "unknown protocol `%s' specified", 15141de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt s); 15151de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15161de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15171de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 15181de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt return proto; 15191de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt} 1520