xtables.c revision 70581922f873a88306dd5b1cb83c5081ee239eb8
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 768e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim/** 778e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * xtables_set_params - set the global parameters used by xtables 788e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * @xtp: input xtables_globals structure 798e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * 808e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * The app is expected to pass a valid xtables_globals data-filled 818e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * with proper values 828e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * @xtp cannot be NULL 838e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * 848e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim * Returns -1 on failure to set and 0 on success 858e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim */ 868e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salimint xtables_set_params(struct xtables_globals *xtp) 878e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim{ 888e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim if (!xtp) { 898e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim fprintf(stderr, "%s: Illegal global params\n",__func__); 908e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim return -1; 918e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim } 928e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim 938e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim xt_params = xtp; 9440a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 958b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim if (!xt_params->exit_err) 968b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err = basic_exit_err; 9740a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 988e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim return 0; 998e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim} 1008e90ce66a99e5dc9b055a9fd14e8e9216f90233cJamal Hadi Salim 101139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salimvoid xtables_free_opts(int reset_offset) 10284c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim{ 103139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim if (xt_params->opts != xt_params->orig_opts) { 104139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim free(xt_params->opts); 105139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim xt_params->opts = xt_params->orig_opts; 10684c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim if (reset_offset) 10784c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim xt_params->option_offset = 0; 10884c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim } 10984c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim} 11084c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim 11170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salimstruct option *xtables_merge_options(struct option *oldopts, 11270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim const struct option *newopts, 11370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim unsigned int *option_offset) 11470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim{ 11570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim unsigned int num_old, num_new, i; 11670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim struct option *merge; 11770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 11870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim if (newopts == NULL) 11970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return oldopts; 12070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 12170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (num_old = 0; oldopts[num_old].name; num_old++) ; 12270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (num_new = 0; newopts[num_new].name; num_new++) ; 12370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 12470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim xt_params->option_offset += OPTION_OFFSET; 12570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim *option_offset = xt_params->option_offset; 12670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 12770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim merge = malloc(sizeof(struct option) * (num_new + num_old + 1)); 12870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim if (merge == NULL) 12970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return NULL; 13070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim memcpy(merge, oldopts, num_old * sizeof(struct option)); 13170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim xtables_free_opts(0); /* Release any old options merged */ 13270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (i = 0; i < num_new; i++) { 13370581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim merge[num_old + i] = newopts[i]; 13470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim merge[num_old + i].val += *option_offset; 13570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim } 13670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim memset(merge + num_old + num_new, 0, sizeof(struct option)); 13770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 13870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return merge; 13970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim} 14070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 141853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salimvoid xtables_set_revision(char *name, u_int8_t revision) 142853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim{ 143853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim /* Old kernel sources don't have ".revision" field, 144853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim * but we stole a byte from name. */ 145853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim name[XT_FUNCTION_MAXNAMELEN - 2] = '\0'; 146853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim name[XT_FUNCTION_MAXNAMELEN - 1] = revision; 147853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim} 148853322131026d62df3f8d77d67e5c63be496303cJamal Hadi Salim 149dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt/** 15077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * xtables_afinfo - protocol family dependent information 15177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @kmod: kernel module basename (e.g. "ip_tables") 15277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @libprefix: prefix of .so library name (e.g. "libipt_") 15377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @family: nfproto family 15477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @ipproto: used by setsockopt (e.g. IPPROTO_IP) 15577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @so_rev_match: optname to check revision support of match 15677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @so_rev_target: optname to check revision support of target 15777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt */ 15877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstruct xtables_afinfo { 15977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt const char *kmod; 16077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt const char *libprefix; 16177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt uint8_t family; 16277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt uint8_t ipproto; 16377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt int so_rev_match; 16477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt int so_rev_target; 16577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 16677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 16777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv4 = { 16877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip_tables", 16977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libipt_", 17077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV4, 17177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IP, 17277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IPT_SO_GET_REVISION_MATCH, 17377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IPT_SO_GET_REVISION_TARGET, 17477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 17577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 17677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv6 = { 17777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip6_tables", 17877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libip6t_", 17977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV6, 18077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IPV6, 18177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IP6T_SO_GET_REVISION_MATCH, 18277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IP6T_SO_GET_REVISION_TARGET, 18377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 18477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 18577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo *afinfo; 18677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 18777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt/** 188dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt * Program will set this to its own name. 189dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt */ 190dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardtconst char *xtables_program_name; 191dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt 19239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt/* Search path for Xtables .so files */ 19339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtstatic const char *xtables_libdir; 1940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1950b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI/* the path to command to load kernel module */ 196c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtconst char *xtables_modprobe_program; 1970b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI/* Keeping track of external matches and targets: linked lists. */ 1990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_match *xtables_matches; 2000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_target *xtables_targets; 2010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 20239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtvoid xtables_init(void) 20339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt{ 20439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("XTABLES_LIBDIR"); 20539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) 20639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 20739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("IPTABLES_LIB_DIR"); 20839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) { 20939bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt fprintf(stderr, "IPTABLES_LIB_DIR is deprecated, " 21039bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt "use XTABLES_LIBDIR.\n"); 21139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 21239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt } 213ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt /* 214ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * Well yes, IP6TABLES_LIB_DIR is of lower priority over 215ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * IPTABLES_LIB_DIR since this moved to libxtables; I think that is ok 216ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * for these env vars are deprecated anyhow, and in light of the 217ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * (shared) libxt_*.so files, makes less sense to have 218ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * IPTABLES_LIB_DIR != IP6TABLES_LIB_DIR. 219ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt */ 220ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt xtables_libdir = getenv("IP6TABLES_LIB_DIR"); 221ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt if (xtables_libdir != NULL) { 222ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt fprintf(stderr, "IP6TABLES_LIB_DIR is deprecated, " 223ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt "use XTABLES_LIBDIR.\n"); 224ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt return; 225ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt } 22639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = XTABLES_LIBDIR; 22739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt} 22839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt 22977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtvoid xtables_set_nfproto(uint8_t nfproto) 23077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt{ 23177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt switch (nfproto) { 23277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV4: 23377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv4; 23477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 23577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV6: 23677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv6; 23777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 23877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt default: 23977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt fprintf(stderr, "libxtables: unhandled NFPROTO in %s\n", 24077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt __func__); 24177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt } 24277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt} 24377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 244630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt/** 245630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt * xtables_*alloc - wrappers that exit on failure 246630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt */ 247630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_calloc(size_t count, size_t size) 2483dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 2493dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 2503dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2513dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = calloc(count, size)) == NULL) { 2523dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: calloc failed"); 2533dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 2543dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 2553dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2563dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 2573dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 2583dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 259630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_malloc(size_t size) 2603dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 2613dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 2623dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2633dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = malloc(size)) == NULL) { 2643dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: malloc failed"); 2653dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 2663dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 2673dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2683dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 2693dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 2700b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2710b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIstatic char *get_modprobe(void) 2720b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 2730b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int procfile; 2740b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *ret; 2750b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2760b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROCFILE_BUFSIZ 1024 2770b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI procfile = open(PROC_SYS_MODPROBE, O_RDONLY); 2780b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (procfile < 0) 2790b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 2800b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2810b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret = (char *) malloc(PROCFILE_BUFSIZ); 2820b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret) { 2830b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI memset(ret, 0, PROCFILE_BUFSIZ); 2840b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (read(procfile, ret, PROCFILE_BUFSIZ)) { 2850b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: goto fail; 2860b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */ 2870b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 2880b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret[strlen(ret)-1]=='\n') 2890b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret[strlen(ret)-1]=0; 2900b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 2910b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return ret; 2920b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 2930b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI fail: 2940b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(ret); 2950b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 2960b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 2970b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 2980b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 299c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_insmod(const char *modname, const char *modprobe, bool quiet) 3000b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 3010b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *buf = NULL; 3020b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *argv[4]; 3030b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int status; 3040b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3050b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* If they don't explicitly set it, read out of kernel */ 3060b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!modprobe) { 3070b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI buf = get_modprobe(); 3080b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!buf) 3090b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3100b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI modprobe = buf; 3110b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3120b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 313c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt /* 314c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt * Need to flush the buffer, or the child may output it again 315c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt * when switching the program thru execv. 316c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt */ 317c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt fflush(stdout); 318c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt 3190b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (fork()) { 3200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case 0: 3210b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[0] = (char *)modprobe; 3220b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[1] = (char *)modname; 3230b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (quiet) { 3240b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = "-q"; 3250b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 3260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } else { 3270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = NULL; 3280b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 3290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI execv(argv[0], argv); 3310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3320b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* not usually reached */ 3330b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI exit(1); 3340b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: 3350b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3360b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3370b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI default: /* parent */ 3380b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI wait(&status); 3390b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3400b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3410b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(buf); 3420b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 3430b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return 0; 3440b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3450b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 3460b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 347c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_load_ko(const char *modprobe, bool quiet) 3480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 349c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt static bool loaded = false; 3500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI static int ret = -1; 3510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!loaded) { 35377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ret = xtables_insmod(afinfo->kmod, modprobe, quiet); 3540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI loaded = (ret == 0); 3550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ret; 3580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 3590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3605f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt/** 3615f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * xtables_strtou{i,l} - string to number conversion 3625f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @s: input string 3635f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @end: like strtoul's "end" pointer 3645f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @value: pointer for result 3655f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @min: minimum accepted value 3665f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @max: maximum accepted value 3675f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * 3685f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * If @end is NULL, we assume the caller wants a "strict strtoul", and hence 3695f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * "15a" is rejected. 3705f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * In either case, the value obtained is compared for min-max compliance. 3715f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Base is always 0, i.e. autodetect depending on @s. 372cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt * 3735f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Returns true/false whether number was accepted. On failure, *value has 3745f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * undefined contents. 375cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt */ 3765f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoul(const char *s, char **end, unsigned long *value, 3775f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned long min, unsigned long max) 378cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 379cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt unsigned long v; 380cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt char *my_end; 381cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 382cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt errno = 0; 383cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt v = strtoul(s, &my_end, 0); 384cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 385cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (my_end == s) 386cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 387cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end != NULL) 388cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *end = my_end; 389cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 390cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (errno != ERANGE && min <= v && (max == 0 || v <= max)) { 391cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 392cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 393cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end == NULL) 394cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return *my_end == '\0'; 395cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return true; 396cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt } 397cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 398cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 399cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 400cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 4015f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoui(const char *s, char **end, unsigned int *value, 4025f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned int min, unsigned int max) 403cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 404cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt unsigned long v; 405cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt bool ret; 406cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 4075f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt ret = xtables_strtoul(s, end, &v, min, max); 408cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 409cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 410cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return ret; 411cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 412cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 413aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtint xtables_service_to_port(const char *name, const char *proto) 41404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 41504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI struct servent *service; 41604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 41704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((service = getservbyname(name, proto)) != NULL) 41804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return ntohs((unsigned short) service->s_port); 41904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 42004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return -1; 42104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 42204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 423aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtu_int16_t xtables_parse_port(const char *port, const char *proto) 42404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 4257a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt unsigned int portnum; 42604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4275f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (xtables_strtoui(port, NULL, &portnum, 0, UINT16_MAX) || 428aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt (portnum = xtables_service_to_port(port, proto)) != (unsigned)-1) 429213e185afbb298e6708881e4c2adffdc47a8b6daJan Engelhardt return portnum; 43004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4318b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 43204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "invalid port/service `%s' specified", port); 43304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 43404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 435aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtvoid xtables_parse_interface(const char *arg, char *vianame, 436aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt unsigned char *mask) 43704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 43804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI int vialen = strlen(arg); 43904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int i; 44004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 44104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 44204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(vianame, 0, IFNAMSIZ); 44304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 44404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vialen + 1 > IFNAMSIZ) 4458b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 44604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "interface name `%s' must be shorter than IFNAMSIZ" 44704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI " (%i)", arg, IFNAMSIZ-1); 44804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 44904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI strcpy(vianame, arg); 45004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((vialen == 0) || (vialen == 1 && vianame[0] == '+')) 45104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 45204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI else if (vianame[vialen - 1] == '+') { 45304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen - 1); 45404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1); 45504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Don't remove `+' here! -HW */ 45604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } else { 45704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Include nul-terminator in match */ 45804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen + 1); 45904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1); 46004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI for (i = 0; vianame[i]; i++) { 46104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vianame[i] == ':' || 46204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '!' || 46304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '*') { 464aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann fprintf(stderr, 465aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann "Warning: weird character in interface" 466aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann " `%s' (No aliases, :, ! or *).\n", 467aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann vianame); 46804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI break; 46904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 47004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 47104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 47204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 47304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 474cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#ifndef NO_SHARED_LIBS 47521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardtstatic void *load_extension(const char *search_path, const char *prefix, 47621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *name, bool is_target) 47721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt{ 47821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *dir = search_path, *next; 47921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt void *ptr = NULL; 48021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt struct stat sb; 48121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt char path[256]; 48221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 48321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt do { 48421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = strchr(dir, ':'); 48521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (next == NULL) 48621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = dir + strlen(dir); 48721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt snprintf(path, sizeof(path), "%.*s/libxt_%s.so", 4882c0a0c9eba1d1ab39dcde54bc822d4788f9531fcJan Engelhardt (unsigned int)(next - dir), dir, name); 48921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 49021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (dlopen(path, RTLD_NOW) != NULL) { 49121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt /* Found library. If it didn't register itself, 49221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt maybe they specified target as match. */ 49321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 4942338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 49521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 4962338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 4972338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 49821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } else if (stat(path, &sb) == 0) { 49921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 50021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } 50121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 50221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (ptr != NULL) 50321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return ptr; 50421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 50521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt snprintf(path, sizeof(path), "%.*s/%s%s.so", 5062c0a0c9eba1d1ab39dcde54bc822d4788f9531fcJan Engelhardt (unsigned int)(next - dir), dir, prefix, name); 50721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (dlopen(path, RTLD_NOW) != NULL) { 50821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 5092338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 51021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 5112338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 5122338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 51321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } else if (stat(path, &sb) == 0) { 51421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 51521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } 51621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 51721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (ptr != NULL) 51821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return ptr; 51921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 52021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt dir = next + 1; 52121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } while (*next != '\0'); 52221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 52321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return NULL; 52421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt} 525cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#endif 52621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 5272338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_match * 5282338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_match(const char *name, enum xtables_tryload tryload, 5292338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt struct xtables_rule_match **matches) 5300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 5310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *ptr; 5320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI const char *icmp6 = "icmp6"; 5330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is ugly as hell. Nonetheless, there is no way of changing 5350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI * this without hurting backwards compatibility */ 5360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if ( (strcmp(name,"icmpv6") == 0) || 5370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"ipv6-icmp") == 0) || 5380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"icmp6") == 0) ) 5390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = icmp6; 5400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_matches; ptr; ptr = ptr->next) { 5420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) { 5430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *clone; 5440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* First match of this type: */ 5460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr->m == NULL) 5470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 5480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Second and subsequent clones */ 550630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt clone = xtables_malloc(sizeof(struct xtables_match)); 5510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI memcpy(clone, ptr, sizeof(struct xtables_match)); 5520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->mflags = 0; 5530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is a clone: */ 5540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->next = clone; 5550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = clone; 5570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 5580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 5622338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 56377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 56439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, false); 565170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 5662338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 5678b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 5680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load match `%s':%s\n", 5690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 5700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 5720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 5732338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 5740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 5750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 5760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 5770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5782338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if(!ptr && (tryload == XTF_LOAD_MUST_SUCCEED)) { 5798b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 5800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find match `%s'\n", name); 5810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 5830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && matches) { 5850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match **i; 5860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match *newentry; 5870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 588630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt newentry = xtables_malloc(sizeof(struct xtables_rule_match)); 5890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = matches; *i; i = &(*i)->next) { 5910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, (*i)->match->name) == 0) 5922338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt (*i)->completed = true; 5930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->match = ptr; 5952338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt newentry->completed = false; 5960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->next = NULL; 5970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = newentry; 5980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 6010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6032338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_target * 6042338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_target(const char *name, enum xtables_tryload tryload) 6050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 6060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *ptr; 6070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Standard target? */ 6090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, "") == 0 6100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_ACCEPT) == 0 6110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_DROP) == 0 6120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_QUEUE) == 0 6130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_RETURN) == 0) 6140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = "standard"; 6150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_targets; ptr; ptr = ptr->next) { 6170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) 6180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 6190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 6222338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 62377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 62439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, true); 625170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 6262338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 6278b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 6280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load target `%s':%s\n", 6290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 6300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 6320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 6332338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 6340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 6350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 6360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 6370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if(!ptr && (tryload == LOAD_MUST_SUCCEED)) { 6398b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 6400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find target `%s'\n", name); 6410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 6430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr) 6450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->used = 1; 6460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 6480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_revision(const char *name, u_int8_t revision, int opt) 6510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 6520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xt_get_revision rev; 6530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI socklen_t s = sizeof(rev); 6540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI int max_rev, sockfd; 6550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 65677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt sockfd = socket(afinfo->family, SOCK_RAW, IPPROTO_RAW); 6570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (sockfd < 0) { 658df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (errno == EPERM) { 659df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy /* revision 0 is always supported. */ 660df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (revision != 0) 661df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy fprintf(stderr, "Could not determine whether " 662df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "revision %u is supported, " 663df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "assuming it is.\n", 664df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy revision); 665df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy return 1; 666df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy } 6670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "Could not open socket to kernel: %s\n", 6680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 6690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 672c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt xtables_load_ko(xtables_modprobe_program, true); 6730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strcpy(rev.name, name); 6750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI rev.revision = revision; 6760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 67777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); 6780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (max_rev < 0) { 6790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Definitely don't support this? */ 6800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (errno == ENOENT || errno == EPROTONOSUPPORT) { 6810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 6820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 0; 6830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else if (errno == ENOPROTOOPT) { 6840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 6850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Assume only revision 0 support (old kernel) */ 6860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return (revision == 0); 6870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else { 6880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "getsockopt failed strangely: %s\n", 6890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 6900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 6940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 1; 6950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_match_revision(const char *name, u_int8_t revision) 6990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 70077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_match); 7010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_target_revision(const char *name, u_int8_t revision) 7040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 70577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_target); 7060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_match(struct xtables_match *me) 7090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 7100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match **i, *old; 7110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 712dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 713dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: match \"%s\" has version \"%s\", " 714dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 715dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, 716dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 7170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 7210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 7220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 723dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 7280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 7290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: match %s has invalid protocol family\n", 730dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested match */ 73577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 7360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7382338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); 7390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 74023545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && 74123545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt old->family == me->family) { 7420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 7430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: match `%s' already registered.\n", 744dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 7490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_match_revision(old->name, old->revision) 7500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 7510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 75323545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new match can be used. */ 7540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_match_revision(me->name, me->revision)) 7550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 75723545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */ 75823545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && me->family == AF_UNSPEC) 75923545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt return; 76023545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt 7610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 7620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i!=old; i = &(*i)->next); 7630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 7640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 7670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: match `%s' has invalid size %u.\n", 768dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, (unsigned int)me->size); 7690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Append to list. */ 7730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i; i = &(*i)->next); 7740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = NULL; 7750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = me; 7760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->m = NULL; 7780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->mflags = 0; 7790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_target(struct xtables_target *me) 7820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 7830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *old; 7840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 785dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 786dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: target \"%s\" has version \"%s\", " 787dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 788dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, 789dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 7900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 7940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 7950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 796dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 8010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 8020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: target %s has invalid protocol family\n", 803dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 8040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested target */ 80877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 8090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8112338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_target(me->name, XTF_DURING_LOAD); 8120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 8130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target **i; 8140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 81523545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && 81623545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt old->family == me->family) { 8170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 8180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: target `%s' already registered.\n", 819dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 8200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 8240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_target_revision(old->name, old->revision) 8250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 8260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 82823545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new target can be used. */ 8290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_target_revision(me->name, me->revision)) 8300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 83223545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */ 83323545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && me->family == AF_UNSPEC) 83423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt return; 83523545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt 8360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 8370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_targets; *i!=old; i = &(*i)->next); 8380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 8390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 8420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid size %u.\n", 843dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, (unsigned int)me->size); 8440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Prepend to list. */ 8480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = xtables_targets; 8490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI xtables_targets = me; 8500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->t = NULL; 8510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->tflags = 0; 8520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 853aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 854a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt/** 855a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * xtables_param_act - act on condition 856a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @status: a constant from enum xtables_exittype 857a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 858a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONLY_ONCE: print error message that option may only be used once. 859a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name (e.g. "mark") 860a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2(...): option in conflict (e.g. "--mark") 861a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3(...): condition to match on (see extensions/ for examples) 862a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 863a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_NO_INVERT: option does not support inversion 864a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 865a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option in conflict 866a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: condition to match on 867a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 868a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_BAD_VALUE: bad value for option 869a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 870a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option with which the problem occured (e.g. "--mark") 871a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: string the user passed in (e.g. "99999999999999") 872a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 873a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONE_ACTION: two mutually exclusive actions have been specified 874a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 875a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 876a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * Displays an error message and exits the program. 877a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt */ 878a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardtvoid xtables_param_act(unsigned int status, const char *p1, ...) 879aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt{ 880aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt const char *p2, *p3; 881aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_list args; 882aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt bool b; 883aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 884aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_start(args, p1); 885aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 886aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt switch (status) { 887a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONLY_ONCE: 888aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 889aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 890aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 891aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 8928b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 893aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option may only be specified once", 894aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2); 895aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 896a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_NO_INVERT: 897aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 898aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 899aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 900aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 9018b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 902aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option cannot be inverted", p1, p2); 903aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 904a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_BAD_VALUE: 905aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 906aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p3 = va_arg(args, const char *); 9078b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 908aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: Bad value for \"%s\" option: \"%s\"", 909aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2, p3); 910aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 911a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONE_ACTION: 912aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 913aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 914aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 9158b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 916aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: At most one action is possible", p1); 917aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 918aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt default: 9198b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(status, p1, args); 920aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 921aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt } 922aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 923aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_end(args); 924aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt} 92508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 926e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_numeric(const struct in_addr *addrp) 92708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 92808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 92908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const unsigned char *bytep = (const void *)&addrp->s_addr; 93008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 93108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]); 93208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 93308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 93408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 93508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_host(const struct in_addr *addr) 93608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 93708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct hostent *host; 93808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 93908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt host = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET); 94008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (host == NULL) 94108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 94208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 94308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return host->h_name; 94408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 94508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 94608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_network(const struct in_addr *addr) 94708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 94808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct netent *net; 94908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 95008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((net = getnetbyaddr(ntohl(addr->s_addr), AF_INET)) != NULL) 95108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return net->n_name; 95208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 95308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 95408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 95508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 956e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_anyname(const struct in_addr *addr) 95708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 95808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 95908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 96008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ipaddr_to_host(addr)) != NULL || 96108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt (name = ipaddr_to_network(addr)) != NULL) 96208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 96308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 964e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ipaddr_to_numeric(addr); 96508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 96608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 967e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipmask_to_numeric(const struct in_addr *mask) 96808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 96908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 97008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t maskaddr, bits; 97108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int i; 97208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 97308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt maskaddr = ntohl(mask->s_addr); 97408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 97508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (maskaddr == 0xFFFFFFFFL) 97608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* we don't want to see "/32" */ 97708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return ""; 97808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 97908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt i = 32; 98008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits = 0xFFFFFFFEL; 98108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (--i >= 0 && maskaddr != bits) 98208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits <<= 1; 98308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (i >= 0) 98408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", i); 98508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt else 98608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* mask was not a decent combination of 1's and 0's */ 987e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); 98808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 98908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 99008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 99108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 992bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *__numeric_to_ipaddr(const char *dotted, bool is_mask) 993bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 994bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 995bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned char *addrp; 996bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int onebyte; 997bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[20], *p, *q; 998bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int i; 999bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1000bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* copy dotted string, because we need to modify it */ 1001bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, dotted, sizeof(buf) - 1); 1002bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1003bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = (void *)&addr.s_addr; 1004bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1005bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = buf; 1006bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < 3; ++i) { 1007bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((q = strchr(p, '.')) == NULL) { 1008bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (is_mask) 1009bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1010bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1011bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* autocomplete, this is a network address */ 10125f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1013bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1014bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1015bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 1016bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (i < 3) 1017bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[++i] = 0; 1018bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1019bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1020bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1021bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1022bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *q = '\0'; 10235f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1024bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1025bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1026bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 1027bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = q + 1; 1028bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1029bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1030bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* we have checked 3 bytes, now we check the last one */ 10315f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1032bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1033bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1034bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[3] = onebyte; 1035bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1036bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1037bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 10381e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipaddr(const char *dotted) 1039bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1040bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, false); 1041bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1042bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 10431e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipmask(const char *dotted) 1044bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1045bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, true); 1046bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1047bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1048bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *network_to_ipaddr(const char *name) 1049bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1050bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 1051bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct netent *net; 1052bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1053bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((net = getnetbyname(name)) != NULL) { 1054bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (net->n_addrtype != AF_INET) 1055bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1056bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addr.s_addr = htonl(net->n_net); 1057bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1058bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1059bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1060bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1061bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1062bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1063bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *host_to_ipaddr(const char *name, unsigned int *naddr) 1064bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1065bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct hostent *host; 1066bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addr; 1067bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i; 1068bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1069bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1070bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((host = gethostbyname(name)) != NULL) { 1071bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (host->h_addrtype != AF_INET || 1072bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt host->h_length != sizeof(struct in_addr)) 1073bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1074bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1075bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (host->h_addr_list[*naddr] != NULL) 1076bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++*naddr; 1077630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addr = xtables_calloc(*naddr, sizeof(struct in_addr) * *naddr); 1078bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < *naddr; i++) 1079bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(&addr[i], host->h_addr_list[i], 1080bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in_addr)); 1081bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1082bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1083bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1084bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1085bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1086bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1087bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr * 1088bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtipparse_hostnetwork(const char *name, unsigned int *naddrs) 1089bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1090bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrptmp, *addrp; 1091bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 10921e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ipaddr(name)) != NULL || 1093bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ipaddr(name)) != NULL) { 1094630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in_addr)); 1095bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1096bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1097bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1098bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1099bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrptmp = host_to_ipaddr(name, naddrs)) != NULL) 1100bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrptmp; 1101bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 11028b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1103bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1104bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1105bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *parse_ipmask(const char *mask) 1106bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1107bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr maskaddr; 1108bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1109bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1110bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1111bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1112bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 32 bits */ 1113bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0xFFFFFFFF; 1114bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1115bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 11161e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ipmask(mask)) != NULL) 1117bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* dotted_to_addr already returns a network byte order addr */ 1118bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 11195f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 32)) 11208b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1121bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1122bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1123bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); 1124bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1125bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1126bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1127bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0U; 1128bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1129bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1130bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1131a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt/** 1132a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * xtables_ipparse_any - transform arbitrary name to in_addr 1133a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * 1134a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * Possible inputs (pseudo regex): 1135a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * m{^($hostname|$networkname|$ipaddr)(/$mask)?} 1136a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * "1.2.3.4/5", "1.2.3.4", "hostname", "networkname" 1137a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt */ 1138a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ipparse_any(const char *name, struct in_addr **addrpp, 1139a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in_addr *maskp, unsigned int *naddrs) 1140bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1141bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1142bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1143bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1144bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1145bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1146bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1147bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1148bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1149bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(p + 1); 1150bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1151bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(NULL); 1152bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1153bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1154bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1155bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1156bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (maskp->s_addr == 0U) 1157bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "0.0.0.0"); 1158bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1159bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ipparse_hostnetwork(buf, naddrs); 1160bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1161bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1162bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[j++].s_addr &= maskp->s_addr; 1163bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1164bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (addrp[k].s_addr == addrp[j-1].s_addr) { 1165bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --*naddrs; 1166bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --j; 1167bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1168bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1169bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1170bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1171bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1172e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_numeric(const struct in6_addr *addrp) 117308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 117408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* 0000:0000:0000:0000:0000:000.000.000.000 117508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt * 0000:0000:0000:0000:0000:0000:0000:0000 */ 117608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+1]; 117708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); 117808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 117908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 118008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ip6addr_to_host(const struct in6_addr *addr) 118108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 118208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char hostname[NI_MAXHOST]; 118308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct sockaddr_in6 saddr; 118408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int err; 118508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 118608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memset(&saddr, 0, sizeof(struct sockaddr_in6)); 118708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memcpy(&saddr.sin6_addr, addr, sizeof(*addr)); 118808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt saddr.sin6_family = AF_INET6; 118908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 119008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt err = getnameinfo((const void *)&saddr, sizeof(struct sockaddr_in6), 119108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt hostname, sizeof(hostname) - 1, NULL, 0, 0); 119208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (err != 0) { 119308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 119408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf(stderr,"IP2Name: %s\n",gai_strerror(err)); 119508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 119608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 119708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 119808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 119908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 120008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf (stderr, "\naddr2host: %s\n", hostname); 120108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 120208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return hostname; 120308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 120408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1205e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_anyname(const struct in6_addr *addr) 120608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 120708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 120808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 120908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ip6addr_to_host(addr)) != NULL) 121008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 121108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1212e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ip6addr_to_numeric(addr); 121308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 121408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 121508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic int ip6addr_prefix_length(const struct in6_addr *k) 121608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 121708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt unsigned int bits = 0; 121808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t a, b, c, d; 121908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 122048607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt a = ntohl(k->s6_addr32[0]); 122148607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt b = ntohl(k->s6_addr32[1]); 122248607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt c = ntohl(k->s6_addr32[2]); 122348607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt d = ntohl(k->s6_addr32[3]); 122408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (a & 0x80000000U) { 122508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt ++bits; 122608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a <<= 1; 122708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a |= (b >> 31) & 1; 122808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b <<= 1; 122908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b |= (c >> 31) & 1; 123008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c <<= 1; 123108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c |= (d >> 31) & 1; 123208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt d <<= 1; 123308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 123408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (a != 0 || b != 0 || c != 0 || d != 0) 123508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return -1; 123608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return bits; 123708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 123808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1239e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6mask_to_numeric(const struct in6_addr *addrp) 124008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 124108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+2]; 124208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int l = ip6addr_prefix_length(addrp); 124308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 124408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (l == -1) { 124508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt strcpy(buf, "/"); 1246e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt strcat(buf, xtables_ip6addr_to_numeric(addrp)); 124708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 124808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 124908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", l); 125008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 125108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 1252bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 12531e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in6_addr *xtables_numeric_to_ip6addr(const char *num) 1254bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1255bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr ap; 1256bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1257bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1258bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = inet_pton(AF_INET6, num, &ap)) == 1) 1259bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return ≈ 1260bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1261bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "\nnumeric2addr: %d\n", err); 1262bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1263bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1264bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1265bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1266bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1267bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardthost_to_ip6addr(const char *name, unsigned int *naddr) 1268bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1269bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr *addr; 1270bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo hints; 1271bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo *res; 1272bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1273bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1274bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&hints, 0, sizeof(hints)); 1275bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_flags = AI_CANONNAME; 1276bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_family = AF_INET6; 1277bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_socktype = SOCK_RAW; 1278bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_protocol = IPPROTO_IPV6; 1279bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_next = NULL; 1280bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1281bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1282bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { 1283bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1284bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); 1285bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1286bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1287bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1288bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (res->ai_family != AF_INET6 || 1289bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt res->ai_addrlen != sizeof(struct sockaddr_in6)) 1290bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1291bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1292bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1293bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, 1294bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ip6addr_to_numeric(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)); 1295bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1296bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* Get the first element of the address-chain */ 1297630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addr = xtables_malloc(sizeof(struct in6_addr)); 1298bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addr, &((const struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 1299bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in6_addr)); 1300bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt freeaddrinfo(res); 1301bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 1; 1302bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1303bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1304bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1305bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1306bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1307bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1308bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *network_to_ip6addr(const char *name) 1309bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1310bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* abort();*/ 1311bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* TODO: not implemented yet, but the exception breaks the 1312bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt * name resolvation */ 1313bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1314bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1315bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1316bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1317bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtip6parse_hostnetwork(const char *name, unsigned int *naddrs) 1318bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1319bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp, *addrptmp; 1320bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 13211e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ip6addr(name)) != NULL || 1322bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ip6addr(name)) != NULL) { 1323630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in6_addr)); 1324bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1325bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1326bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1327bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1328bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrp = host_to_ip6addr(name, naddrs)) != NULL) 1329bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1330bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 13318b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1332bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1333bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1334bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *parse_ip6mask(char *mask) 1335bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1336bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr maskaddr; 1337bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1338bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1339bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1340bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1341bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 128 bits */ 1342bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0xff, sizeof maskaddr); 1343bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1344bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 13451e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ip6addr(mask)) != NULL) 1346bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 13475f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 128)) 13488b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1349bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1350bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1351bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char *p = (void *)&maskaddr; 1352bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p, 0xff, bits / 8); 1353bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p + (bits / 8) + 1, 0, (128 - bits) / 8); 1354bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p[bits/8] = 0xff << (8 - (bits & 7)); 1355bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1356bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1357bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1358bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0, sizeof(maskaddr)); 1359bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1360bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1361bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1362a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ip6parse_any(const char *name, struct in6_addr **addrpp, 1363a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in6_addr *maskp, unsigned int *naddrs) 1364bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1365bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1366bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1367bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1368bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1369bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1370bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf)-1] = '\0'; 1371bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1372bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1373bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(p + 1); 1374bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1375bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(NULL); 1376bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1377bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1378bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1379bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1380bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (memcmp(maskp, &in6addr_any, sizeof(in6addr_any)) == 0) 1381bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "::"); 1382bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1383bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ip6parse_hostnetwork(buf, naddrs); 1384bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1385bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1386bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < 4; ++k) 13875a2208c3e62a150e6f6297abbfa63056ab4a8066Yasuyuki Kozakai addrp[j].s6_addr32[k] &= maskp->s6_addr32[k]; 1388bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++j; 1389bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1390bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (IN6_ARE_ADDR_EQUAL(&addrp[k], &addrp[j - 1])) { 1391bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --*naddrs; 1392bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --j; 1393bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1394bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1395bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1396bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1397a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1398a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_save_string(const char *value) 1399a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann{ 1400a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char no_quote_chars[] = "_-0123456789" 1401a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "abcdefghijklmnopqrstuvwxyz" 1402a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 1403a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char escape_chars[] = "\"\\'"; 1404a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann size_t length; 1405a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann const char *p; 1406a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1407a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann length = strcspn(value, no_quote_chars); 1408a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (length > 0 && value[length] == 0) { 1409a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* no quoting required */ 1410a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 1411a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(' '); 1412a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } else { 1413a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* there is at least one dangerous character in the 1414a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value, which we have to quote. Write double quotes 1415a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann around the value and escape special characters with 1416a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann a backslash */ 1417a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('"'); 1418a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1419a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann for (p = strpbrk(value, escape_chars); p != NULL; 1420a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann p = strpbrk(value, escape_chars)) { 1421a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (p > value) 1422a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fwrite(value, 1, p - value, stdout); 1423a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('\\'); 1424a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(*p); 1425a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value = p + 1; 1426a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1427a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1428a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* print the rest and finish the double quoted 1429a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann string */ 1430a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 1431a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann printf("\" "); 1432a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1433a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann} 14340f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 14350f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt/** 14360f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt * Check for option-intrapositional negation. 14370f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt * Do not use in new code. 14380f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt */ 14390f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardtint xtables_check_inverse(const char option[], int *invert, 14400f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt int *my_optind, int argc) 14410f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt{ 14420f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (option && strcmp(option, "!") == 0) { 14430f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt fprintf(stderr, "Using intrapositioned negation " 14440f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "(`--option ! this`) is deprecated in favor of " 14450f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "extrapositioned (`! --option this`).\n"); 14460f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 14470f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (*invert) 14488b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 14490f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "Multiple `!' flags not allowed"); 14500f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt *invert = true; 14510f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (my_optind != NULL) { 14520f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt ++*my_optind; 14530f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (argc && *my_optind > argc) 14548b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 14550f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "no argument following `!'"); 14560f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt } 14570f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 14580f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt return true; 14590f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt } 14600f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt return false; 14610f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt} 14621de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14631de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtconst struct xtables_pprot xtables_chain_protos[] = { 14641de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"tcp", IPPROTO_TCP}, 14651de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"sctp", IPPROTO_SCTP}, 14661de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udp", IPPROTO_UDP}, 14671de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udplite", IPPROTO_UDPLITE}, 14681de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmp", IPPROTO_ICMP}, 14691de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmpv6", IPPROTO_ICMPV6}, 14701de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-icmp", IPPROTO_ICMPV6}, 14711de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"esp", IPPROTO_ESP}, 14721de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ah", IPPROTO_AH}, 14731de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-mh", IPPROTO_MH}, 14741de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"mh", IPPROTO_MH}, 14751de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"all", 0}, 14761de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {NULL}, 14771de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt}; 14781de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14791de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtu_int16_t 14801de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtxtables_parse_protocol(const char *s) 14811de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt{ 14821de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt unsigned int proto; 14831de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14841de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (!xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX)) { 14851de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt struct protoent *pent; 14861de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14871de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt /* first deal with the special case of 'all' to prevent 14881de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * people from being able to redefine 'all' in nsswitch 14891de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * and/or provoke expensive [not working] ldap/nis/... 14901de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * lookups */ 14911de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (!strcmp(s, "all")) 14921de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt return 0; 14931de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 14941de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if ((pent = getprotobyname(s))) 14951de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt proto = pent->p_proto; 14961de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt else { 14971de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt unsigned int i; 14981de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) { 14991de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (strcmp(s, xtables_chain_protos[i].name) == 0) { 15001de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt proto = xtables_chain_protos[i].num; 15011de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt break; 15021de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15031de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15041de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (i == ARRAY_SIZE(xtables_chain_protos)) 15058b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 15061de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt "unknown protocol `%s' specified", 15071de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt s); 15081de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15091de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 15101de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 15111de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt return proto; 15121de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt} 1513