xtables.c revision cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adf
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 */ 183c871010888e1479ef8fca2048485b979ec2661aJan Engelhardt#include "config.h" 19d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt#include <ctype.h> 203dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <errno.h> 210b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <fcntl.h> 220b7a140944738d67b9c4e6f09992c8407eefb18aJan Engelhardt#include <inttypes.h> 2304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI#include <netdb.h> 24aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt#include <stdarg.h> 25cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt#include <stdbool.h> 263dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdio.h> 273dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdlib.h> 280b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <string.h> 290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <unistd.h> 300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#include <sys/socket.h> 310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/stat.h> 32b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski#include <sys/statfs.h> 330b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/types.h> 34f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt#include <sys/utsname.h> 350b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/wait.h> 3608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#include <arpa/inet.h> 373c871010888e1479ef8fca2048485b979ec2661aJan Engelhardt#if defined(HAVE_LINUX_MAGIC_H) 383c871010888e1479ef8fca2048485b979ec2661aJan Engelhardt# include <linux/magic.h> /* for PROC_SUPER_MAGIC */ 393c871010888e1479ef8fca2048485b979ec2661aJan Engelhardt#elif defined(HAVE_LINUX_PROC_FS_H) 403c871010888e1479ef8fca2048485b979ec2661aJan Engelhardt# include <linux/proc_fs.h> /* Linux 2.4 */ 4141a9b481693b4c43c16d0588cc558dd455168af0Jan Engelhardt#else 4241a9b481693b4c43c16d0588cc558dd455168af0Jan Engelhardt# define PROC_SUPER_MAGIC 0x9fa0 433c871010888e1479ef8fca2048485b979ec2661aJan Engelhardt#endif 443dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 455208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#include <xtables.h> 464e41854423b529d3107c23b85434d50a75d08057Jan Engelhardt#include <limits.h> /* INT_MAX in ip_tables.h/ip6_tables.h */ 4777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt#include <linux/netfilter_ipv4/ip_tables.h> 4877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt#include <linux/netfilter_ipv6/ip6_tables.h> 49ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt#include <libiptc/libxtc.h> 503dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 515a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#ifndef NO_SHARED_LIBS 525a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#include <dlfcn.h> 535a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#endif 54c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#ifndef IPT_SO_GET_REVISION_MATCH /* Old kernel source. */ 55c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IPT_SO_GET_REVISION_MATCH (IPT_BASE_CTL + 2) 56c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IPT_SO_GET_REVISION_TARGET (IPT_BASE_CTL + 3) 57c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#endif 58c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#ifndef IP6T_SO_GET_REVISION_MATCH /* Old kernel source. */ 59c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IP6T_SO_GET_REVISION_MATCH 68 60c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt# define IP6T_SO_GET_REVISION_TARGET 69 61c31870f9bebb3d4d082016fcfaf8c2177ae32eb2Jan Engelhardt#endif 6270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim#include <getopt.h> 63aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt#include "iptables/internal.h" 641e128bd804b676ee91beca48312de9b251845d09Jan Engelhardt#include "xshared.h" 655a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger 660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#define NPROTO 255 670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 680b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#ifndef PROC_SYS_MODPROBE 690b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" 700b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#endif 710b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 7237911de507d0597980ad218a044a482501a21b01Maciej Zenczykowski/* we need this for ip6?tables-restore. ip6?tables-restore.c sets line to the 7337911de507d0597980ad218a044a482501a21b01Maciej Zenczykowski * current line of the input file, in order to give a more precise error 7437911de507d0597980ad218a044a482501a21b01Maciej Zenczykowski * message. ip6?tables itself doesn't need this, so it is initialized to the 7537911de507d0597980ad218a044a482501a21b01Maciej Zenczykowski * magic number of -1 */ 7637911de507d0597980ad218a044a482501a21b01Maciej Zenczykowskiint line = -1; 7737911de507d0597980ad218a044a482501a21b01Maciej Zenczykowski 788b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salimvoid basic_exit_err(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3))); 798b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim 8040a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salimstruct xtables_globals *xt_params = NULL; 8140a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 828b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salimvoid basic_exit_err(enum xtables_exittype status, const char *msg, ...) 8340a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim{ 8440a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim va_list args; 8540a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 8640a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim va_start(args, msg); 8740a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim fprintf(stderr, "%s v%s: ", xt_params->program_name, xt_params->program_version); 8840a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim vfprintf(stderr, msg, args); 8940a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim va_end(args); 9040a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim fprintf(stderr, "\n"); 9140a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim exit(status); 9240a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim} 9340a8343d3ad0cdbc3a7e69c8d970ad75807c29edJamal Hadi Salim 94600f38db82548a683775fd89b6e136673e924097Jan Engelhardtvoid xtables_free_opts(int unused) 9584c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim{ 96df288236cd254798be3759fef4cbc3e535f5a1c3Jan Engelhardt if (xt_params->opts != xt_params->orig_opts) { 9759e8114c6792242e80785f4461d5e663fb9a3d64Jan Engelhardt free(xt_params->opts); 98df288236cd254798be3759fef4cbc3e535f5a1c3Jan Engelhardt xt_params->opts = NULL; 99df288236cd254798be3759fef4cbc3e535f5a1c3Jan Engelhardt } 10084c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim} 10184c3055bf08d0a8fe5db6e5f3f96dd826a290147Jamal Hadi Salim 102600f38db82548a683775fd89b6e136673e924097Jan Engelhardtstruct option *xtables_merge_options(struct option *orig_opts, 103600f38db82548a683775fd89b6e136673e924097Jan Engelhardt struct option *oldopts, 10470581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim const struct option *newopts, 10570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim unsigned int *option_offset) 10670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim{ 107600f38db82548a683775fd89b6e136673e924097Jan Engelhardt unsigned int num_oold = 0, num_old = 0, num_new = 0, i; 108600f38db82548a683775fd89b6e136673e924097Jan Engelhardt struct option *merge, *mp; 10970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 11070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim if (newopts == NULL) 11170581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return oldopts; 11270581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 113600f38db82548a683775fd89b6e136673e924097Jan Engelhardt for (num_oold = 0; orig_opts[num_oold].name; num_oold++) ; 114600f38db82548a683775fd89b6e136673e924097Jan Engelhardt if (oldopts != NULL) 115600f38db82548a683775fd89b6e136673e924097Jan Engelhardt for (num_old = 0; oldopts[num_old].name; num_old++) ; 11670581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim for (num_new = 0; newopts[num_new].name; num_new++) ; 11770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 1181dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt /* 1191dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt * Since @oldopts also has @orig_opts already (and does so at the 1201dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt * start), skip these entries. 1211dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt */ 1221dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt oldopts += num_oold; 1231dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt num_old -= num_oold; 1241dc27393b7ba401e6228a5ee2472a6eb72836c43Jan Engelhardt 125600f38db82548a683775fd89b6e136673e924097Jan Engelhardt merge = malloc(sizeof(*mp) * (num_oold + num_old + num_new + 1)); 126600f38db82548a683775fd89b6e136673e924097Jan Engelhardt if (merge == NULL) 127600f38db82548a683775fd89b6e136673e924097Jan Engelhardt return NULL; 128600f38db82548a683775fd89b6e136673e924097Jan Engelhardt 129600f38db82548a683775fd89b6e136673e924097Jan Engelhardt /* Let the base options -[ADI...] have precedence over everything */ 130600f38db82548a683775fd89b6e136673e924097Jan Engelhardt memcpy(merge, orig_opts, sizeof(*mp) * num_oold); 131600f38db82548a683775fd89b6e136673e924097Jan Engelhardt mp = merge + num_oold; 132600f38db82548a683775fd89b6e136673e924097Jan Engelhardt 133600f38db82548a683775fd89b6e136673e924097Jan Engelhardt /* Second, the new options */ 1341e128bd804b676ee91beca48312de9b251845d09Jan Engelhardt xt_params->option_offset += XT_OPTION_OFFSET_SCALE; 13570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim *option_offset = xt_params->option_offset; 136600f38db82548a683775fd89b6e136673e924097Jan Engelhardt memcpy(mp, newopts, sizeof(*mp) * num_new); 13770581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 138600f38db82548a683775fd89b6e136673e924097Jan Engelhardt for (i = 0; i < num_new; ++i, ++mp) 139600f38db82548a683775fd89b6e136673e924097Jan Engelhardt mp->val += *option_offset; 140600f38db82548a683775fd89b6e136673e924097Jan Engelhardt 141600f38db82548a683775fd89b6e136673e924097Jan Engelhardt /* Third, the old options */ 142600f38db82548a683775fd89b6e136673e924097Jan Engelhardt memcpy(mp, oldopts, sizeof(*mp) * num_old); 143600f38db82548a683775fd89b6e136673e924097Jan Engelhardt mp += num_old; 144600f38db82548a683775fd89b6e136673e924097Jan Engelhardt xtables_free_opts(0); 14570581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 146600f38db82548a683775fd89b6e136673e924097Jan Engelhardt /* Clear trailing entry */ 147600f38db82548a683775fd89b6e136673e924097Jan Engelhardt memset(mp, 0, sizeof(*mp)); 14870581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim return merge; 14970581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim} 15070581922f873a88306dd5b1cb83c5081ee239eb8Jamal Hadi Salim 15177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv4 = { 15277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip_tables", 153b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski .proc_exists = "/proc/net/ip_tables_names", 15477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libipt_", 15577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV4, 15677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IP, 15777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IPT_SO_GET_REVISION_MATCH, 15877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IPT_SO_GET_REVISION_TARGET, 15977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 16077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 16177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv6 = { 16277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip6_tables", 163b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski .proc_exists = "/proc/net/ip6_tables_names", 16477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libip6t_", 16577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV6, 16677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IPV6, 16777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IP6T_SO_GET_REVISION_MATCH, 16877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IP6T_SO_GET_REVISION_TARGET, 16977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 17077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 171aa37acc1423126f555135935c687eb91995b9440Jan Engelhardtconst struct xtables_afinfo *afinfo; 17277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 17339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt/* Search path for Xtables .so files */ 17439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtstatic const char *xtables_libdir; 1750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1760b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI/* the path to command to load kernel module */ 177c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtconst char *xtables_modprobe_program; 1780b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1792c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski/* Keep track of matches/targets pending full registration: linked lists. */ 1802c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowskistruct xtables_match *xtables_pending_matches; 1812c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowskistruct xtables_target *xtables_pending_targets; 1822c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 1832c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski/* Keep track of fully registered external matches/targets: linked lists. */ 1840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_match *xtables_matches; 1850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_target *xtables_targets; 1860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1872c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski/* Fully register a match/target which was previously partially registered. */ 1882c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowskistatic void xtables_fully_register_pending_match(struct xtables_match *me); 1892c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowskistatic void xtables_fully_register_pending_target(struct xtables_target *me); 1902c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 19139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtvoid xtables_init(void) 19239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt{ 19339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("XTABLES_LIBDIR"); 19439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) 19539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 19639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("IPTABLES_LIB_DIR"); 19739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) { 19839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt fprintf(stderr, "IPTABLES_LIB_DIR is deprecated, " 19939bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt "use XTABLES_LIBDIR.\n"); 20039bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 20139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt } 202ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt /* 203ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * Well yes, IP6TABLES_LIB_DIR is of lower priority over 204ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * IPTABLES_LIB_DIR since this moved to libxtables; I think that is ok 205ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * for these env vars are deprecated anyhow, and in light of the 206ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * (shared) libxt_*.so files, makes less sense to have 207ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt * IPTABLES_LIB_DIR != IP6TABLES_LIB_DIR. 208ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt */ 209ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt xtables_libdir = getenv("IP6TABLES_LIB_DIR"); 210ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt if (xtables_libdir != NULL) { 211ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt fprintf(stderr, "IP6TABLES_LIB_DIR is deprecated, " 212ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt "use XTABLES_LIBDIR.\n"); 213ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt return; 214ec934198bd6ee2f21171dba440ca96334b0d874bJan Engelhardt } 21539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = XTABLES_LIBDIR; 21639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt} 21739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt 21877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtvoid xtables_set_nfproto(uint8_t nfproto) 21977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt{ 22077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt switch (nfproto) { 22177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV4: 22277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv4; 22377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 22477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV6: 22577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv6; 22677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 22777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt default: 22877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt fprintf(stderr, "libxtables: unhandled NFPROTO in %s\n", 22977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt __func__); 23077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt } 23177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt} 23277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 233630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt/** 2347e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * xtables_set_params - set the global parameters used by xtables 2357e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * @xtp: input xtables_globals structure 2367e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * 2377e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * The app is expected to pass a valid xtables_globals data-filled 2387e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * with proper values 2397e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * @xtp cannot be NULL 2407e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * 2417e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim * Returns -1 on failure to set and 0 on success 2427e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim */ 2437e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salimint xtables_set_params(struct xtables_globals *xtp) 2447e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim{ 2457e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim if (!xtp) { 2467e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim fprintf(stderr, "%s: Illegal global params\n",__func__); 2477e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim return -1; 2487e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim } 2497e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2507e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xt_params = xtp; 2517e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2527e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim if (!xt_params->exit_err) 2537e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xt_params->exit_err = basic_exit_err; 2547e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2557e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim return 0; 2567e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim} 2577e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2587e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salimint xtables_init_all(struct xtables_globals *xtp, uint8_t nfproto) 2597e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim{ 2607e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xtables_init(); 2617e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim xtables_set_nfproto(nfproto); 2627e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim return xtables_set_params(xtp); 2637e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim} 2647e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim 2657e4db2f50133007f549f222468bde4f3adcf41acJamal Hadi Salim/** 266630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt * xtables_*alloc - wrappers that exit on failure 267630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt */ 268630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_calloc(size_t count, size_t size) 2693dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 2703dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 2713dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2723dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = calloc(count, size)) == NULL) { 2733dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: calloc failed"); 2743dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 2753dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 2763dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2773dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 2783dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 2793dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 280630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_malloc(size_t size) 2813dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 2823dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 2833dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2843dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = malloc(size)) == NULL) { 2853dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: malloc failed"); 2863dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 2873dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 2883dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 2893dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 2903dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 2910b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 292332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzowvoid *xtables_realloc(void *ptr, size_t size) 293332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow{ 294332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow void *p; 295332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 296332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow if ((p = realloc(ptr, size)) == NULL) { 297332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow perror("ip[6]tables: realloc failed"); 298332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow exit(1); 299332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 300332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 301332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow return p; 302332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow} 303332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 3040b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIstatic char *get_modprobe(void) 3050b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 3060b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int procfile; 3070b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *ret; 3080b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3090b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROCFILE_BUFSIZ 1024 3100b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI procfile = open(PROC_SYS_MODPROBE, O_RDONLY); 3110b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (procfile < 0) 3120b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 313a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski if (fcntl(procfile, F_SETFD, FD_CLOEXEC) == -1) { 314a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski fprintf(stderr, "Could not set close on exec: %s\n", 315a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski strerror(errno)); 316a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski exit(1); 317a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski } 3180b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 319371cea299f0b2eb100b9fc9fb99089640d2d606fJan Engelhardt ret = malloc(PROCFILE_BUFSIZ); 3200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret) { 3210b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI memset(ret, 0, PROCFILE_BUFSIZ); 3220b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (read(procfile, ret, PROCFILE_BUFSIZ)) { 3230b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: goto fail; 3240b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */ 3250b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret[strlen(ret)-1]=='\n') 3270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret[strlen(ret)-1]=0; 3280b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 3290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return ret; 3300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI fail: 3320b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(ret); 3330b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 3340b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 3350b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 3360b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 337c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_insmod(const char *modname, const char *modprobe, bool quiet) 3380b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 3390b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *buf = NULL; 3400b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *argv[4]; 3410b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int status; 3420b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3430b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* If they don't explicitly set it, read out of kernel */ 3440b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!modprobe) { 3450b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI buf = get_modprobe(); 3460b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!buf) 3470b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3480b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI modprobe = buf; 3490b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3500b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 351c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt /* 352c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt * Need to flush the buffer, or the child may output it again 353c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt * when switching the program thru execv. 354c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt */ 355c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt fflush(stdout); 356c19f880d8aac7c0372381e29d7cea09accd0db26Jan Engelhardt 35794aa2ea67d7b8a669e8541f094661a1dc89722a3Jan Engelhardt switch (vfork()) { 3580b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case 0: 3590b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[0] = (char *)modprobe; 3600b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[1] = (char *)modname; 3610b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (quiet) { 3620b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = "-q"; 3630b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 3640b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } else { 3650b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = NULL; 3660b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 3670b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3680b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI execv(argv[0], argv); 3690b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3700b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* not usually reached */ 3710b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI exit(1); 3720b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: 373f53710b16c2bae1843c3f5fee390f496dfa82526Jiri Popelka free(buf); 3740b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3750b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3760b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI default: /* parent */ 3770b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI wait(&status); 3780b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 3790b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 3800b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(buf); 3810b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 3820b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return 0; 3830b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 3840b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 3850b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 386b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski/* return true if a given file exists within procfs */ 387b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowskistatic bool proc_file_exists(const char *filename) 388b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski{ 389b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski struct stat s; 390b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski struct statfs f; 391b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski 392b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (lstat(filename, &s)) 393b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return false; 394b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (!S_ISREG(s.st_mode)) 395b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return false; 396b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (statfs(filename, &f)) 397b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return false; 398b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (f.f_type != PROC_SUPER_MAGIC) 399b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return false; 400b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return true; 401b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski} 402b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski 403c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_load_ko(const char *modprobe, bool quiet) 4040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 405c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt static bool loaded = false; 406b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski int ret; 4070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 408b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (loaded) 409b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return 0; 410b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski 411b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (proc_file_exists(afinfo->proc_exists)) { 412b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski loaded = true; 413b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski return 0; 414b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski }; 415b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski 416b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski ret = xtables_insmod(afinfo->kmod, modprobe, quiet); 417b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski if (ret == 0) 418b32b361a725c8fe3a3aa494e6cdec09a80785aacMaciej Zenczykowski loaded = true; 4190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ret; 4210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 4220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4235f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt/** 4245f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * xtables_strtou{i,l} - string to number conversion 4255f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @s: input string 4265f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @end: like strtoul's "end" pointer 4275f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @value: pointer for result 4285f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @min: minimum accepted value 4295f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @max: maximum accepted value 4305f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * 4315f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * If @end is NULL, we assume the caller wants a "strict strtoul", and hence 4325f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * "15a" is rejected. 4335f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * In either case, the value obtained is compared for min-max compliance. 4345f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Base is always 0, i.e. autodetect depending on @s. 435cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt * 4365f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Returns true/false whether number was accepted. On failure, *value has 4375f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * undefined contents. 438cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt */ 4390b7a140944738d67b9c4e6f09992c8407eefb18aJan Engelhardtbool xtables_strtoul(const char *s, char **end, uintmax_t *value, 4400b7a140944738d67b9c4e6f09992c8407eefb18aJan Engelhardt uintmax_t min, uintmax_t max) 441cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 4420b7a140944738d67b9c4e6f09992c8407eefb18aJan Engelhardt uintmax_t v; 443d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt const char *p; 444cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt char *my_end; 445cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 446cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt errno = 0; 447d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt /* Since strtoul allows leading minus, we have to check for ourself. */ 448d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt for (p = s; isspace(*p); ++p) 449d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt ; 450d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt if (*p == '-') 451d61b02fbbbe7f6e643aad8649c8559c175c68c52Jan Engelhardt return false; 4520b7a140944738d67b9c4e6f09992c8407eefb18aJan Engelhardt v = strtoumax(s, &my_end, 0); 453cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (my_end == s) 454cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 455cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end != NULL) 456cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *end = my_end; 457cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 458cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (errno != ERANGE && min <= v && (max == 0 || v <= max)) { 459cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 460cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 461cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end == NULL) 462cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return *my_end == '\0'; 463cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return true; 464cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt } 465cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 466cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 467cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 468cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 4695f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoui(const char *s, char **end, unsigned int *value, 4705f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned int min, unsigned int max) 471cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 4720b7a140944738d67b9c4e6f09992c8407eefb18aJan Engelhardt uintmax_t v; 473cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt bool ret; 474cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 4755f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt ret = xtables_strtoul(s, end, &v, min, max); 476cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 477cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 478cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return ret; 479cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 480cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 481aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtint xtables_service_to_port(const char *name, const char *proto) 48204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 48304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI struct servent *service; 48404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 48504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((service = getservbyname(name, proto)) != NULL) 48604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return ntohs((unsigned short) service->s_port); 48704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 48804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return -1; 48904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 49004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4917ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtuint16_t xtables_parse_port(const char *port, const char *proto) 49204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 4937a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt unsigned int portnum; 49404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4955f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (xtables_strtoui(port, NULL, &portnum, 0, UINT16_MAX) || 496aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt (portnum = xtables_service_to_port(port, proto)) != (unsigned)-1) 497213e185afbb298e6708881e4c2adffdc47a8b6daJan Engelhardt return portnum; 49804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 4998b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 50004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "invalid port/service `%s' specified", port); 50104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 50204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 503aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtvoid xtables_parse_interface(const char *arg, char *vianame, 504aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt unsigned char *mask) 50504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 506fcf5723f415c81fcb2c93094cdcc39b35a316ff2Jan Engelhardt unsigned int vialen = strlen(arg); 50704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int i; 50804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 50904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 51004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(vianame, 0, IFNAMSIZ); 51104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 51204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vialen + 1 > IFNAMSIZ) 5138b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 51404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "interface name `%s' must be shorter than IFNAMSIZ" 51504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI " (%i)", arg, IFNAMSIZ-1); 51604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 51704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI strcpy(vianame, arg); 518fcf5723f415c81fcb2c93094cdcc39b35a316ff2Jan Engelhardt if (vialen == 0) 5192ca6273c73b42e8c74afd5f8b1fe10c5c93ce363Richard Weinberger return; 52004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI else if (vianame[vialen - 1] == '+') { 52104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen - 1); 52204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Don't remove `+' here! -HW */ 52304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } else { 52404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Include nul-terminator in match */ 52504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen + 1); 52604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI for (i = 0; vianame[i]; i++) { 527fcf5723f415c81fcb2c93094cdcc39b35a316ff2Jan Engelhardt if (vianame[i] == '/' || 528fcf5723f415c81fcb2c93094cdcc39b35a316ff2Jan Engelhardt vianame[i] == ' ') { 529aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann fprintf(stderr, 530aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann "Warning: weird character in interface" 531fcf5723f415c81fcb2c93094cdcc39b35a316ff2Jan Engelhardt " `%s' ('/' and ' ' are not allowed by the kernel).\n", 532aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann vianame); 53304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI break; 53404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 53504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 53604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 53704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 53804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 539cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#ifndef NO_SHARED_LIBS 540927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardtstatic void *load_extension(const char *search_path, const char *af_prefix, 54121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *name, bool is_target) 54221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt{ 543927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt const char *all_prefixes[] = {"libxt_", af_prefix, NULL}; 544927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt const char **prefix; 54521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *dir = search_path, *next; 54621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt void *ptr = NULL; 54721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt struct stat sb; 54821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt char path[256]; 54921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 55021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt do { 55121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = strchr(dir, ':'); 55221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (next == NULL) 55321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = dir + strlen(dir); 55421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 555927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt for (prefix = all_prefixes; *prefix != NULL; ++prefix) { 556927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt snprintf(path, sizeof(path), "%.*s/%s%s.so", 557927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt (unsigned int)(next - dir), dir, 558927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt *prefix, name); 559927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt 560927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt if (stat(path, &sb) != 0) { 561927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt if (errno == ENOENT) 562927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt continue; 563927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt fprintf(stderr, "%s: %s\n", path, 564927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt strerror(errno)); 565927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt return NULL; 566927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt } 567927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt if (dlopen(path, RTLD_NOW) == NULL) { 568927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 569927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt break; 570927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt } 57121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 57221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 5732338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 57421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 5752338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 5762338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 57721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 578927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt if (ptr != NULL) 579927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt return ptr; 58021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 581927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt fprintf(stderr, "%s: no \"%s\" extension found for " 582927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt "this protocol\n", path, name); 583927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt errno = ENOENT; 584927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt return NULL; 585927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt } 58621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt dir = next + 1; 58721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } while (*next != '\0'); 58821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 58921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return NULL; 59021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt} 591cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#endif 59221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 5932338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_match * 5942338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_match(const char *name, enum xtables_tryload tryload, 5952338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt struct xtables_rule_match **matches) 5960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 5972c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski struct xtables_match **dptr; 5980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *ptr; 5990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI const char *icmp6 = "icmp6"; 6000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6010cb675b8f18c4b074d4c69461638820708e98100Jan Engelhardt if (strlen(name) >= XT_EXTENSION_MAXNAMELEN) 60221d1283750d9c4df7ca80165d2b9dc0b9bd214ebJan Engelhardt xtables_error(PARAMETER_PROBLEM, 60321d1283750d9c4df7ca80165d2b9dc0b9bd214ebJan Engelhardt "Invalid match name \"%s\" (%u chars max)", 6040cb675b8f18c4b074d4c69461638820708e98100Jan Engelhardt name, XT_EXTENSION_MAXNAMELEN - 1); 60521d1283750d9c4df7ca80165d2b9dc0b9bd214ebJan Engelhardt 6060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is ugly as hell. Nonetheless, there is no way of changing 6070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI * this without hurting backwards compatibility */ 6080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if ( (strcmp(name,"icmpv6") == 0) || 6090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"ipv6-icmp") == 0) || 6100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"icmp6") == 0) ) 6110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = icmp6; 6120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6132c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski /* Trigger delayed initialization */ 6142c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski for (dptr = &xtables_pending_matches; *dptr; ) { 6152c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski if (strcmp(name, (*dptr)->name) == 0) { 6162c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski ptr = *dptr; 6172c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski *dptr = (*dptr)->next; 6182c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski ptr->next = NULL; 6192c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski xtables_fully_register_pending_match(ptr); 6202c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski } else { 6212c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski dptr = &((*dptr)->next); 6222c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski } 6232c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski } 6242c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 6250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_matches; ptr; ptr = ptr->next) { 6260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) { 6270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *clone; 6280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* First match of this type: */ 6300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr->m == NULL) 6310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 6320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Second and subsequent clones */ 634630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt clone = xtables_malloc(sizeof(struct xtables_match)); 6350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI memcpy(clone, ptr, sizeof(struct xtables_match)); 6363eab786d6a687187556c92b3dc0f0664d8352471Jan Engelhardt clone->udata = NULL; 6370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->mflags = 0; 6380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is a clone: */ 6390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->next = clone; 6400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = clone; 6420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 6430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 6472338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 64877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 64939bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, false); 650170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 6512338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 6528b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 6530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load match `%s':%s\n", 654927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt name, strerror(errno)); 6550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 6570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 6582338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 6590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 6600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 6610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 6620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6632338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if(!ptr && (tryload == XTF_LOAD_MUST_SUCCEED)) { 6648b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 6650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find match `%s'\n", name); 6660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 6680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && matches) { 6700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match **i; 6710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match *newentry; 6720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 673630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt newentry = xtables_malloc(sizeof(struct xtables_rule_match)); 6740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = matches; *i; i = &(*i)->next) { 6760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, (*i)->match->name) == 0) 6772338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt (*i)->completed = true; 6780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->match = ptr; 6802338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt newentry->completed = false; 6810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->next = NULL; 6820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = newentry; 6830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 6860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6882338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_target * 6892338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_target(const char *name, enum xtables_tryload tryload) 6900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 6912c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski struct xtables_target **dptr; 6920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *ptr; 6930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Standard target? */ 6950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, "") == 0 6960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_ACCEPT) == 0 6970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_DROP) == 0 6980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_QUEUE) == 0 6990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_RETURN) == 0) 7000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = "standard"; 7010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7022c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski /* Trigger delayed initialization */ 7032c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski for (dptr = &xtables_pending_targets; *dptr; ) { 7042c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski if (strcmp(name, (*dptr)->name) == 0) { 7052c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski ptr = *dptr; 7062c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski *dptr = (*dptr)->next; 7072c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski ptr->next = NULL; 7082c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski xtables_fully_register_pending_target(ptr); 7092c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski } else { 7102c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski dptr = &((*dptr)->next); 7112c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski } 7122c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski } 7132c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 7140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_targets; ptr; ptr = ptr->next) { 7150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) 7160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 7170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 7202338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 72177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 72239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, true); 723170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 7242338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 7258b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 7260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load target `%s':%s\n", 727927385017047dce3f01c0aee73ab2989b108bbf0Jan Engelhardt name, strerror(errno)); 7280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 7300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 7312338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 7320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 7330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 7340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 7350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 736854d2d9bd7556cfd8a676b0bc18dc059a9a2dd25Peter Volkov if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) { 7378b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 7380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find target `%s'\n", name); 7390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 7410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr) 7430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->used = 1; 7440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 7460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 7470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7487ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtstatic int compatible_revision(const char *name, uint8_t revision, int opt) 7490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 7500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xt_get_revision rev; 7510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI socklen_t s = sizeof(rev); 7520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI int max_rev, sockfd; 7530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 75477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt sockfd = socket(afinfo->family, SOCK_RAW, IPPROTO_RAW); 7550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (sockfd < 0) { 756df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (errno == EPERM) { 757df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy /* revision 0 is always supported. */ 758df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (revision != 0) 759e1639b0bc28420ca01d733749c8db16d5a3fbd0cJan Engelhardt fprintf(stderr, "%s: Could not determine whether " 760df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "revision %u is supported, " 761df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "assuming it is.\n", 762e1639b0bc28420ca01d733749c8db16d5a3fbd0cJan Engelhardt name, revision); 763df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy return 1; 764df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy } 7650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "Could not open socket to kernel: %s\n", 7660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 7670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 770a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski if (fcntl(sockfd, F_SETFD, FD_CLOEXEC) == -1) { 771a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski fprintf(stderr, "Could not set close on exec: %s\n", 772a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski strerror(errno)); 773a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski exit(1); 774a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski } 775a239728ec064666025de2723997d87b176d57fd6Maciej Zenczykowski 776c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt xtables_load_ko(xtables_modprobe_program, true); 7770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strcpy(rev.name, name); 7790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI rev.revision = revision; 7800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 78177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); 7820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (max_rev < 0) { 7830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Definitely don't support this? */ 7840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (errno == ENOENT || errno == EPROTONOSUPPORT) { 7850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 7860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 0; 7870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else if (errno == ENOPROTOOPT) { 7880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 7890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Assume only revision 0 support (old kernel) */ 7900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return (revision == 0); 7910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else { 7920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "getsockopt failed strangely: %s\n", 7930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 7940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 7980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 1; 7990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 8000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8027ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtstatic int compatible_match_revision(const char *name, uint8_t revision) 8030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 80477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_match); 8050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 8060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8077ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtstatic int compatible_target_revision(const char *name, uint8_t revision) 8080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 80977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_target); 8100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 8110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 812dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardtstatic void xtables_check_options(const char *name, const struct option *opt) 813dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt{ 814dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt for (; opt->name != NULL; ++opt) 815dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt if (opt->val < 0 || opt->val >= XT_OPTION_OFFSET_SCALE) { 816dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt fprintf(stderr, "%s: Extension %s uses invalid " 817dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt "option value %d\n",xt_params->program_name, 818dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt name, opt->val); 819dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt exit(1); 820dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt } 821dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt} 822dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt 8230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_match(struct xtables_match *me) 8240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 825c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt if (me->version == NULL) { 826c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt fprintf(stderr, "%s: match %s<%u> is missing a version\n", 827c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt xt_params->program_name, me->name, me->revision); 828c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt exit(1); 829c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt } 830dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 831dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: match \"%s\" has version \"%s\", " 832dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 8335dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name, 834dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 8350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8380cb675b8f18c4b074d4c69461638820708e98100Jan Engelhardt if (strlen(me->name) >= XT_EXTENSION_MAXNAMELEN) { 839281439ba6b96b729ef1400a49ec53eda298bb9f8Li Yewang fprintf(stderr, "%s: match `%s' has invalid name\n", 8405dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name); 8410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 8450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 8460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: match %s has invalid protocol family\n", 8475dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name); 8480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 8490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 8500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 851aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt if (me->x6_options != NULL) 852aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt xtables_option_metavalidate(me->name, me->x6_options); 853dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt if (me->extra_opts != NULL) 854dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt xtables_check_options(me->name, me->extra_opts); 855dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt 8560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested match */ 85777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 8580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 8590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 8602c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski /* place on linked list of matches pending full registration */ 8612c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski me->next = xtables_pending_matches; 8622c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski xtables_pending_matches = me; 8632c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski} 8642c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 865954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt/** 866954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * Compare two actions for their preference 867954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * @a: one action 868954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * @b: another 869954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * 870954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * Like strcmp, returns a negative number if @a is less preferred than @b, 871954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * positive number if @a is more preferred than @b, or zero if equally 872954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt * preferred. 873954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt */ 874954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardtstatic int 875cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardtxtables_mt_prefer(bool a_alias, unsigned int a_rev, unsigned int a_fam, 876cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt bool b_alias, unsigned int b_rev, unsigned int b_fam) 877954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt{ 878cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt /* 879cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt * Alias ranks higher than no alias. 880cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt * (We want the new action to be used whenever possible.) 881cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt */ 882cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt if (!a_alias && b_alias) 883cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt return -1; 884cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt if (a_alias && !b_alias) 885cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt return 1; 886cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt 887954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt /* Higher revision ranks higher. */ 888954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (a_rev < b_rev) 889954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt return -1; 890954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (a_rev > b_rev) 891954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt return 1; 892954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt 893954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt /* NFPROTO_<specific> ranks higher than NFPROTO_UNSPEC. */ 894954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (a_fam == NFPROTO_UNSPEC && b_fam != NFPROTO_UNSPEC) 895954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt return -1; 896954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (a_fam != NFPROTO_UNSPEC && b_fam == NFPROTO_UNSPEC) 897954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt return 1; 898954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt 899954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt /* Must be the same thing. */ 900954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt return 0; 901954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt} 902954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt 903954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardtstatic int xtables_match_prefer(const struct xtables_match *a, 904954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt const struct xtables_match *b) 905954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt{ 906cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt return xtables_mt_prefer(false, a->revision, a->family, 907cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt false, b->revision, b->family); 908954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt} 909954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt 910954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardtstatic int xtables_target_prefer(const struct xtables_target *a, 911954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt const struct xtables_target *b) 912954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt{ 913cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt /* 914cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt * Note that if x->real_name==NULL, it will be set to x->name in 915cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt * xtables_register_*; the direct pointer comparison here is therefore 916cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt * legitimate to detect an alias. 917cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt */ 918cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt return xtables_mt_prefer(a->name != a->real_name, 919cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt a->revision, a->family, 920cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt b->name != b->real_name, 921954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt b->revision, b->family); 922954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt} 923954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt 9242c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowskistatic void xtables_fully_register_pending_match(struct xtables_match *me) 9252c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski{ 9262c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski struct xtables_match **i, *old; 927954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt int compare; 9282c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 9292338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); 9300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 931954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt compare = xtables_match_prefer(old, me); 932954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (compare == 0) { 9330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 9340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: match `%s' already registered.\n", 9355dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name); 9360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 9370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 9380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 940954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (compare > 0 && 941954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt compatible_match_revision(old->name, old->revision)) 9420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 9430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 94423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new match can be used. */ 9450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_match_revision(me->name, me->revision)) 9460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 9470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 9490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i!=old; i = &(*i)->next); 9500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 9510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 9520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 9540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: match `%s' has invalid size %u.\n", 9555dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name, 9565dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim (unsigned int)me->size); 9570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 9580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 9590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Append to list. */ 9610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i; i = &(*i)->next); 9620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = NULL; 9630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = me; 9640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->m = NULL; 9660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->mflags = 0; 9670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 9680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9699a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardtvoid xtables_register_matches(struct xtables_match *match, unsigned int n) 9709a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt{ 9719a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt do { 9729a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt xtables_register_match(&match[--n]); 9739a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt } while (n > 0); 9749a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt} 9759a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt 9760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_target(struct xtables_target *me) 9770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 978c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt if (me->version == NULL) { 979c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt fprintf(stderr, "%s: target %s<%u> is missing a version\n", 980c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt xt_params->program_name, me->name, me->revision); 981c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt exit(1); 982c284de545d03aad9a04a4e17cfb55d911a96810cJan Engelhardt } 983dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 984dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: target \"%s\" has version \"%s\", " 985dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 9865dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name, 987dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 9880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 9890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 9900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9910cb675b8f18c4b074d4c69461638820708e98100Jan Engelhardt if (strlen(me->name) >= XT_EXTENSION_MAXNAMELEN) { 9920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 9935dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name); 9940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 9950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 9960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 9970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 9980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 9990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: target %s has invalid protocol family\n", 10005dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name); 10010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 10020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 10030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1004cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt if (me->real_name == NULL) 1005cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt me->real_name = me->name; 1006aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt if (me->x6_options != NULL) 1007aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt xtables_option_metavalidate(me->name, me->x6_options); 1008dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt if (me->extra_opts != NULL) 1009dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt xtables_check_options(me->name, me->extra_opts); 1010dfbedfedf610210c4ee3f00e9c4f9ea24c4ffe23Jan Engelhardt 10110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested target */ 101277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 10130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 10140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 10152c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski /* place on linked list of targets pending full registration */ 10162c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski me->next = xtables_pending_targets; 10172c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski xtables_pending_targets = me; 10182c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski} 10192c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 10202c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowskistatic void xtables_fully_register_pending_target(struct xtables_target *me) 10212c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski{ 10222c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski struct xtables_target *old; 1023954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt int compare; 10242c6ac071a9c660b61a76565d1024d372deac8a98Maciej Zenczykowski 10252338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_target(me->name, XTF_DURING_LOAD); 10260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 10270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target **i; 10280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1029954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt compare = xtables_target_prefer(old, me); 1030954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (compare == 0) { 10310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 10320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: target `%s' already registered.\n", 10335dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name); 10340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 10350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 10360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 10370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 1038954b76c317f641b7faf33cc26931d45585cc0deaJan Engelhardt if (compare > 0 && 1039cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt compatible_target_revision(old->real_name, old->revision)) 10400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 10410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 104223545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new target can be used. */ 1043cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt if (!compatible_target_revision(me->real_name, me->revision)) 10440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 10450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 10460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 10470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_targets; *i!=old; i = &(*i)->next); 10480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 10490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 10500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 10510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 10520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid size %u.\n", 10535dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim xt_params->program_name, me->name, 10545dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim (unsigned int)me->size); 10550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 10560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 10570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 10580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Prepend to list. */ 10590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = xtables_targets; 10600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI xtables_targets = me; 10610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->t = NULL; 10620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->tflags = 0; 10630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 1064aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 10659a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardtvoid xtables_register_targets(struct xtables_target *target, unsigned int n) 10669a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt{ 10679a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt do { 10689a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt xtables_register_target(&target[--n]); 10699a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt } while (n > 0); 10709a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt} 10719a8fc4f89ef120d7beda3724994a1544346b947dJan Engelhardt 1072a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt/** 1073a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * xtables_param_act - act on condition 1074a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @status: a constant from enum xtables_exittype 1075a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 1076a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONLY_ONCE: print error message that option may only be used once. 1077a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name (e.g. "mark") 1078a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2(...): option in conflict (e.g. "--mark") 1079a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3(...): condition to match on (see extensions/ for examples) 1080a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 1081a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_NO_INVERT: option does not support inversion 1082a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 1083a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option in conflict 1084a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: condition to match on 1085a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 1086a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_BAD_VALUE: bad value for option 1087a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 1088a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option with which the problem occured (e.g. "--mark") 1089a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: string the user passed in (e.g. "99999999999999") 1090a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 1091a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONE_ACTION: two mutually exclusive actions have been specified 1092a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 1093a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 1094a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * Displays an error message and exits the program. 1095a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt */ 1096a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardtvoid xtables_param_act(unsigned int status, const char *p1, ...) 1097aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt{ 1098aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt const char *p2, *p3; 1099aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_list args; 1100aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt bool b; 1101aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 1102aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_start(args, p1); 1103aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 1104aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt switch (status) { 1105a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONLY_ONCE: 1106aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 1107aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 1108d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka if (!b) { 1109d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka va_end(args); 1110aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 1111d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka } 11128b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1113aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option may only be specified once", 1114aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2); 1115aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 1116a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_NO_INVERT: 1117aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 1118aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 1119d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka if (!b) { 1120d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka va_end(args); 1121aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 1122d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka } 11238b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1124aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option cannot be inverted", p1, p2); 1125aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 1126a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_BAD_VALUE: 1127aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 1128aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p3 = va_arg(args, const char *); 11298b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1130aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: Bad value for \"%s\" option: \"%s\"", 1131aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2, p3); 1132aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 1133a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONE_ACTION: 1134aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 1135d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka if (!b) { 1136d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka va_end(args); 1137aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 1138d0101690d9ae347d8a8ee9e340c5db72480046a3Jiri Popelka } 11398b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1140aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: At most one action is possible", p1); 1141aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 1142aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt default: 11438b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(status, p1, args); 1144aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 1145aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt } 1146aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 1147aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_end(args); 1148aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt} 114908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1150e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_numeric(const struct in_addr *addrp) 115108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 115208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 115308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const unsigned char *bytep = (const void *)&addrp->s_addr; 115408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 115508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]); 115608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 115708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 115808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 115908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_host(const struct in_addr *addr) 116008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 116108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct hostent *host; 116208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 116308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt host = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET); 116408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (host == NULL) 116508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 116608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 116708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return host->h_name; 116808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 116908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 117008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_network(const struct in_addr *addr) 117108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 117208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct netent *net; 117308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 117408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((net = getnetbyaddr(ntohl(addr->s_addr), AF_INET)) != NULL) 117508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return net->n_name; 117608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 117708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 117808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 117908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1180e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_anyname(const struct in_addr *addr) 118108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 118208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 118308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 118408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ipaddr_to_host(addr)) != NULL || 118508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt (name = ipaddr_to_network(addr)) != NULL) 118608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 118708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1188e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ipaddr_to_numeric(addr); 118908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 119008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1191a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayusoint xtables_ipmask_to_cidr(const struct in_addr *mask) 119208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 119308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t maskaddr, bits; 119408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int i; 119508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 119608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt maskaddr = ntohl(mask->s_addr); 1197a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso /* shortcut for /32 networks */ 119808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (maskaddr == 0xFFFFFFFFL) 1199a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso return 32; 120008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 120108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt i = 32; 120208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits = 0xFFFFFFFEL; 120308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (--i >= 0 && maskaddr != bits) 120408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits <<= 1; 120508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (i >= 0) 1206a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso return i; 1207a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso 1208a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso /* this mask cannot be converted to CIDR notation */ 1209a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso return -1; 1210a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso} 1211a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso 1212a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayusoconst char *xtables_ipmask_to_numeric(const struct in_addr *mask) 1213a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso{ 1214a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso static char buf[20]; 1215a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso uint32_t cidr; 1216a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso 1217a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso cidr = xtables_ipmask_to_cidr(mask); 1218a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso if (cidr < 0) { 121908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* mask was not a decent combination of 1's and 0's */ 1220e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); 1221a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso return buf; 1222a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso } else if (cidr == 32) { 1223a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso /* we don't want to see "/32" */ 1224a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso return ""; 1225a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso } 122608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1227a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso sprintf(buf, "/%d", cidr); 122808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 122908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 123008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1231bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *__numeric_to_ipaddr(const char *dotted, bool is_mask) 1232bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1233bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 1234bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned char *addrp; 1235bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int onebyte; 1236bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[20], *p, *q; 1237bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int i; 1238bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1239bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* copy dotted string, because we need to modify it */ 1240bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, dotted, sizeof(buf) - 1); 1241bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1242bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = (void *)&addr.s_addr; 1243bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1244bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = buf; 1245bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < 3; ++i) { 1246bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((q = strchr(p, '.')) == NULL) { 1247bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (is_mask) 1248bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1249bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1250bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* autocomplete, this is a network address */ 12515f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1252bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1253bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1254bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 1255bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (i < 3) 1256bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[++i] = 0; 1257bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1258bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1259bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1260bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1261bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *q = '\0'; 12625f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1263bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1264bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1265bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 1266bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = q + 1; 1267bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1268bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1269bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* we have checked 3 bytes, now we check the last one */ 12705f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 1271bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1272bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1273bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[3] = onebyte; 1274bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1275bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1276bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 12771e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipaddr(const char *dotted) 1278bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1279bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, false); 1280bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1281bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 12821e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipmask(const char *dotted) 1283bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1284bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, true); 1285bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1286bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1287bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *network_to_ipaddr(const char *name) 1288bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1289bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 1290bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct netent *net; 1291bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1292bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((net = getnetbyname(name)) != NULL) { 1293bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (net->n_addrtype != AF_INET) 1294bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1295bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addr.s_addr = htonl(net->n_net); 1296bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 1297bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1298bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1299bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1300bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1301bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1302bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *host_to_ipaddr(const char *name, unsigned int *naddr) 1303bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1304bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct hostent *host; 1305bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addr; 1306bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i; 1307bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1308bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1309bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((host = gethostbyname(name)) != NULL) { 1310bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (host->h_addrtype != AF_INET || 1311bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt host->h_length != sizeof(struct in_addr)) 1312bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1313bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1314bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (host->h_addr_list[*naddr] != NULL) 1315bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++*naddr; 131611e250ba02349cb1e34058673db3d0b54eb56c44Wes Campaigne addr = xtables_calloc(*naddr, sizeof(struct in_addr)); 1317bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < *naddr; i++) 1318bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(&addr[i], host->h_addr_list[i], 1319bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in_addr)); 1320bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1321bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1322bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1323bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1324bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1325bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1326bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr * 1327bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtipparse_hostnetwork(const char *name, unsigned int *naddrs) 1328bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1329bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrptmp, *addrp; 1330bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 13311e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ipaddr(name)) != NULL || 1332bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ipaddr(name)) != NULL) { 1333630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in_addr)); 1334bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1335bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1336bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1337bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1338bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrptmp = host_to_ipaddr(name, naddrs)) != NULL) 1339bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrptmp; 1340bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 13418b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1342bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1343bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1344bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *parse_ipmask(const char *mask) 1345bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1346bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr maskaddr; 1347bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1348bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1349bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1350bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1351bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 32 bits */ 1352bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0xFFFFFFFF; 1353bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1354bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 13551e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ipmask(mask)) != NULL) 1356bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* dotted_to_addr already returns a network byte order addr */ 1357bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 13585f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 32)) 13598b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1360bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1361bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1362bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); 1363bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1364bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1365bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1366bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0U; 1367bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1368bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1369bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1370332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzowvoid xtables_ipparse_multiple(const char *name, struct in_addr **addrpp, 1371332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow struct in_addr **maskpp, unsigned int *naddrs) 1372332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow{ 1373332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow struct in_addr *addrp; 1374c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt char buf[256], *p, *next; 1375332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow unsigned int len, i, j, n, count = 1; 1376332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow const char *loop = name; 1377332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1378332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow while ((loop = strchr(loop, ',')) != NULL) { 1379332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow ++count; 1380332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow ++loop; /* skip ',' */ 1381332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1382332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1383332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *addrpp = xtables_malloc(sizeof(struct in_addr) * count); 1384332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *maskpp = xtables_malloc(sizeof(struct in_addr) * count); 1385332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1386332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow loop = name; 1387332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1388332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (i = 0; i < count; ++i) { 13890c384449ae9511157cd9b34d73f8f4cb71123a45Jan Engelhardt while (isspace(*loop)) 13900c384449ae9511157cd9b34d73f8f4cb71123a45Jan Engelhardt ++loop; 1391c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt next = strchr(loop, ','); 1392c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt if (next != NULL) 1393c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt len = next - loop; 1394332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow else 1395332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow len = strlen(loop); 1396c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt if (len > sizeof(buf) - 1) 1397c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt xt_params->exit_err(PARAMETER_PROBLEM, 1398c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt "Hostname too long"); 1399332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1400332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow strncpy(buf, loop, len); 1401332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow buf[len] = '\0'; 1402332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow if ((p = strrchr(buf, '/')) != NULL) { 1403332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *p = '\0'; 1404332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow addrp = parse_ipmask(p + 1); 1405332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } else { 1406332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow addrp = parse_ipmask(NULL); 1407332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1408332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*maskpp + i, addrp, sizeof(*addrp)); 1409332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1410332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* if a null mask is given, the name is ignored, like in "any/0" */ 1411332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow if ((*maskpp + i)->s_addr == 0) 1412332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* 1413332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow * A bit pointless to process multiple addresses 1414332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow * in this case... 1415332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow */ 1416332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow strcpy(buf, "0.0.0.0"); 1417332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1418332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow addrp = ipparse_hostnetwork(buf, &n); 1419332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow if (n > 1) { 1420332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow count += n - 1; 1421332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *addrpp = xtables_realloc(*addrpp, 1422332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(struct in_addr) * count); 1423332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *maskpp = xtables_realloc(*maskpp, 1424332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(struct in_addr) * count); 1425332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (j = 0; j < n; ++j) 1426332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* for each new addr */ 1427332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*addrpp + i + j, addrp + j, 1428332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(*addrp)); 1429332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (j = 1; j < n; ++j) 1430332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* for each new mask */ 1431332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*maskpp + i + j, *maskpp + i, 1432332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(*addrp)); 1433332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow i += n - 1; 1434332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } else { 1435332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*addrpp + i, addrp, sizeof(*addrp)); 1436332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1437332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* free what ipparse_hostnetwork had allocated: */ 1438332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow free(addrp); 1439c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt if (next == NULL) 1440c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt break; 1441c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt loop = next + 1; 1442332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1443332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *naddrs = count; 14444b110b426df7bf486a3e7884c56ebb3487023601Jan Engelhardt for (i = 0; i < count; ++i) 1445332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow (*addrpp+i)->s_addr &= (*maskpp+i)->s_addr; 1446332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow} 1447332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1448332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1449a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt/** 1450a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * xtables_ipparse_any - transform arbitrary name to in_addr 1451a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * 1452a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * Possible inputs (pseudo regex): 1453a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * m{^($hostname|$networkname|$ipaddr)(/$mask)?} 1454a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * "1.2.3.4/5", "1.2.3.4", "hostname", "networkname" 1455a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt */ 1456a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ipparse_any(const char *name, struct in_addr **addrpp, 1457a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in_addr *maskp, unsigned int *naddrs) 1458bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1459bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1460bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1461bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1462bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1463bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1464bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1465bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1466bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1467bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(p + 1); 1468bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1469bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(NULL); 1470bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1471bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1472bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1473bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1474bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (maskp->s_addr == 0U) 1475bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "0.0.0.0"); 1476bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1477bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ipparse_hostnetwork(buf, naddrs); 1478bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1479bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1480bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[j++].s_addr &= maskp->s_addr; 1481bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1482bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (addrp[k].s_addr == addrp[j-1].s_addr) { 1483adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne /* 1484adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne * Nuke the dup by copying an address from the 1485adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne * tail here, and check the current position 1486adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne * again (--j). 1487adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne */ 1488adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne memcpy(&addrp[--j], &addrp[--*naddrs], 1489adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne sizeof(struct in_addr)); 1490bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1491bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1492bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1493bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1494bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1495e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_numeric(const struct in6_addr *addrp) 149608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 1497cf3e52d00b7d3fedf98ef7710c337c441270d936Maciej Zenczykowski /* 0000:0000:0000:0000:0000:0000:000.000.000.000 149808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt * 0000:0000:0000:0000:0000:0000:0000:0000 */ 149908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+1]; 150008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); 150108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 150208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 150308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ip6addr_to_host(const struct in6_addr *addr) 150408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 150508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char hostname[NI_MAXHOST]; 150608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct sockaddr_in6 saddr; 150708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int err; 150808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 150908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memset(&saddr, 0, sizeof(struct sockaddr_in6)); 151008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memcpy(&saddr.sin6_addr, addr, sizeof(*addr)); 151108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt saddr.sin6_family = AF_INET6; 151208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 151308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt err = getnameinfo((const void *)&saddr, sizeof(struct sockaddr_in6), 151408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt hostname, sizeof(hostname) - 1, NULL, 0, 0); 151508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (err != 0) { 151608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 151708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf(stderr,"IP2Name: %s\n",gai_strerror(err)); 151808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 151908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 152008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 152108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 152208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 152308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf (stderr, "\naddr2host: %s\n", hostname); 152408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 152508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return hostname; 152608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 152708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1528e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_anyname(const struct in6_addr *addr) 152908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 153008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 153108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 153208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ip6addr_to_host(addr)) != NULL) 153308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 153408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1535e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ip6addr_to_numeric(addr); 153608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 153708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1538a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayusoint xtables_ip6mask_to_cidr(const struct in6_addr *k) 153908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 154008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt unsigned int bits = 0; 154108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t a, b, c, d; 154208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 154348607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt a = ntohl(k->s6_addr32[0]); 154448607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt b = ntohl(k->s6_addr32[1]); 154548607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt c = ntohl(k->s6_addr32[2]); 154648607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt d = ntohl(k->s6_addr32[3]); 154708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (a & 0x80000000U) { 154808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt ++bits; 154908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a <<= 1; 155008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a |= (b >> 31) & 1; 155108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b <<= 1; 155208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b |= (c >> 31) & 1; 155308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c <<= 1; 155408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c |= (d >> 31) & 1; 155508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt d <<= 1; 155608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 155708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (a != 0 || b != 0 || c != 0 || d != 0) 155808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return -1; 155908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return bits; 156008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 156108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1562e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6mask_to_numeric(const struct in6_addr *addrp) 156308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 156408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+2]; 1565a96166c24eaac1c91bed4815c09e91733409d888Pablo Neira Ayuso int l = xtables_ip6mask_to_cidr(addrp); 156608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 156708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (l == -1) { 156808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt strcpy(buf, "/"); 1569e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt strcat(buf, xtables_ip6addr_to_numeric(addrp)); 157008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 157108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 157208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", l); 157308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 157408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 1575bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 15761e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in6_addr *xtables_numeric_to_ip6addr(const char *num) 1577bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1578bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr ap; 1579bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1580bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1581bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = inet_pton(AF_INET6, num, &ap)) == 1) 1582bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return ≈ 1583bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1584bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "\nnumeric2addr: %d\n", err); 1585bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1586bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1587bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1588bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1589bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1590bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardthost_to_ip6addr(const char *name, unsigned int *naddr) 1591bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 15922ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne struct in6_addr *addr; 1593bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo hints; 15942ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne struct addrinfo *res, *p; 1595bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 15962ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne unsigned int i; 1597bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1598bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&hints, 0, sizeof(hints)); 1599bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_flags = AI_CANONNAME; 1600bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_family = AF_INET6; 1601bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_socktype = SOCK_RAW; 1602bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1603bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1604bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { 1605bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1606bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); 1607bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1608bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1609bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 16102ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne /* Find length of address chain */ 16112ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne for (p = res; p != NULL; p = p->ai_next) 16122ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne ++*naddr; 1613bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1614bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, 161530290aea009cf3fd76f27336fb4370be3467c4daPatrick McHardy xtables_ip6addr_to_numeric(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)); 1616bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 16172ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne /* Copy each element of the address chain */ 16182ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne addr = xtables_calloc(*naddr, sizeof(struct in6_addr)); 16192ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne for (i = 0, p = res; p != NULL; p = p->ai_next) 16202ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne memcpy(&addr[i++], 16212ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne &((const struct sockaddr_in6 *)p->ai_addr)->sin6_addr, 16222ad8dc895ec28a173c629c695c2e11c41b625b6eWes Campaigne sizeof(struct in6_addr)); 1623bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt freeaddrinfo(res); 1624bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1625bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1626bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1627bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1628bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1629bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1630bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *network_to_ip6addr(const char *name) 1631bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1632bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* abort();*/ 1633bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* TODO: not implemented yet, but the exception breaks the 1634bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt * name resolvation */ 1635bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1636bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1637bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1638bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1639bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtip6parse_hostnetwork(const char *name, unsigned int *naddrs) 1640bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1641bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp, *addrptmp; 1642bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 16431e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ip6addr(name)) != NULL || 1644bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ip6addr(name)) != NULL) { 1645630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in6_addr)); 1646bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1647bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1648bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1649bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1650bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrp = host_to_ip6addr(name, naddrs)) != NULL) 1651bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1652bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 16538b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1654bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1655bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1656bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *parse_ip6mask(char *mask) 1657bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1658bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr maskaddr; 1659bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1660bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1661bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1662bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1663bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 128 bits */ 1664bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0xff, sizeof maskaddr); 1665bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1666bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 16671e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ip6addr(mask)) != NULL) 1668bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 16695f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 128)) 16708b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim xt_params->exit_err(PARAMETER_PROBLEM, 1671bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1672bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1673bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char *p = (void *)&maskaddr; 1674bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p, 0xff, bits / 8); 1675bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p + (bits / 8) + 1, 0, (128 - bits) / 8); 1676bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p[bits/8] = 0xff << (8 - (bits & 7)); 1677bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1678bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1679bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1680bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0, sizeof(maskaddr)); 1681bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1682bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1683bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1684332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzowvoid 1685332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzowxtables_ip6parse_multiple(const char *name, struct in6_addr **addrpp, 1686332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow struct in6_addr **maskpp, unsigned int *naddrs) 1687332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow{ 168858df90174164fd673e8c4103f7ce0c4e55ef1aecOlaf Rempel static const struct in6_addr zero_addr; 1689332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow struct in6_addr *addrp; 1690c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt char buf[256], *p, *next; 1691332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow unsigned int len, i, j, n, count = 1; 1692332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow const char *loop = name; 1693332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1694332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow while ((loop = strchr(loop, ',')) != NULL) { 1695332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow ++count; 1696332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow ++loop; /* skip ',' */ 1697332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1698332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1699332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *addrpp = xtables_malloc(sizeof(struct in6_addr) * count); 1700332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *maskpp = xtables_malloc(sizeof(struct in6_addr) * count); 1701332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1702332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow loop = name; 1703332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1704332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (i = 0; i < count /*NB: count can grow*/; ++i) { 17050c384449ae9511157cd9b34d73f8f4cb71123a45Jan Engelhardt while (isspace(*loop)) 17060c384449ae9511157cd9b34d73f8f4cb71123a45Jan Engelhardt ++loop; 1707c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt next = strchr(loop, ','); 1708c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt if (next != NULL) 1709c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt len = next - loop; 1710332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow else 1711332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow len = strlen(loop); 1712c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt if (len > sizeof(buf) - 1) 1713c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt xt_params->exit_err(PARAMETER_PROBLEM, 1714c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt "Hostname too long"); 1715332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1716332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow strncpy(buf, loop, len); 1717332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow buf[len] = '\0'; 1718332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow if ((p = strrchr(buf, '/')) != NULL) { 1719332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *p = '\0'; 1720332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow addrp = parse_ip6mask(p + 1); 1721332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } else { 1722332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow addrp = parse_ip6mask(NULL); 1723332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1724332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*maskpp + i, addrp, sizeof(*addrp)); 1725332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1726332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* if a null mask is given, the name is ignored, like in "any/0" */ 172758df90174164fd673e8c4103f7ce0c4e55ef1aecOlaf Rempel if (memcmp(*maskpp + i, &zero_addr, sizeof(zero_addr)) == 0) 1728332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow strcpy(buf, "::"); 1729332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1730332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow addrp = ip6parse_hostnetwork(buf, &n); 1731332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow if (n > 1) { 1732332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow count += n - 1; 1733332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *addrpp = xtables_realloc(*addrpp, 1734332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(struct in6_addr) * count); 1735332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *maskpp = xtables_realloc(*maskpp, 1736332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(struct in6_addr) * count); 1737332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (j = 0; j < n; ++j) 1738332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* for each new addr */ 1739332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*addrpp + i + j, addrp + j, 1740332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(*addrp)); 1741332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (j = 1; j < n; ++j) 1742332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* for each new mask */ 1743332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*maskpp + i + j, *maskpp + i, 1744332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow sizeof(*addrp)); 1745332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow i += n - 1; 1746332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } else { 1747332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow memcpy(*addrpp + i, addrp, sizeof(*addrp)); 1748332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1749332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow /* free what ip6parse_hostnetwork had allocated: */ 1750332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow free(addrp); 1751c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt if (next == NULL) 1752c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt break; 1753c0e69db337540b22a3b3f739b1143341e7b759b7Jan Engelhardt loop = next + 1; 1754332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow } 1755332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow *naddrs = count; 17564b110b426df7bf486a3e7884c56ebb3487023601Jan Engelhardt for (i = 0; i < count; ++i) 1757332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow for (j = 0; j < 4; ++j) 1758332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow (*addrpp+i)->s6_addr32[j] &= (*maskpp+i)->s6_addr32[j]; 1759332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow} 1760332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow 1761a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ip6parse_any(const char *name, struct in6_addr **addrpp, 1762a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in6_addr *maskp, unsigned int *naddrs) 1763bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 17649c0fa7d8c84dc2478bd36d31b328b697fbe4d0afJan Engelhardt static const struct in6_addr zero_addr; 1765bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1766bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1767bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1768bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1769bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1770bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf)-1] = '\0'; 1771bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1772bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1773bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(p + 1); 1774bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1775bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(NULL); 1776bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1777bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1778bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1779bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 17809c0fa7d8c84dc2478bd36d31b328b697fbe4d0afJan Engelhardt if (memcmp(maskp, &zero_addr, sizeof(zero_addr)) == 0) 1781bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "::"); 1782bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1783bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ip6parse_hostnetwork(buf, naddrs); 1784bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1785bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1786bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < 4; ++k) 17875a2208c3e62a150e6f6297abbfa63056ab4a8066Yasuyuki Kozakai addrp[j].s6_addr32[k] &= maskp->s6_addr32[k]; 1788bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++j; 1789bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1790bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (IN6_ARE_ADDR_EQUAL(&addrp[k], &addrp[j - 1])) { 1791adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne /* 1792adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne * Nuke the dup by copying an address from the 1793adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne * tail here, and check the current position 1794adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne * again (--j). 1795adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne */ 1796adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne memcpy(&addrp[--j], &addrp[--*naddrs], 1797adcb28101d53c2a7f372de256b1af50804fee899Wes Campaigne sizeof(struct in_addr)); 1798bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1799bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1800bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1801bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1802a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1803a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_save_string(const char *value) 1804a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann{ 1805a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char no_quote_chars[] = "_-0123456789" 1806a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "abcdefghijklmnopqrstuvwxyz" 1807a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 1808a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char escape_chars[] = "\"\\'"; 1809a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann size_t length; 1810a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann const char *p; 1811a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 181287dc7c4c842deb1e2e3d38089ffcad9f238d98deMax Kellerman length = strspn(value, no_quote_chars); 1813a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (length > 0 && value[length] == 0) { 1814a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* no quoting required */ 1815a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(' '); 181673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt fputs(value, stdout); 1817a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } else { 1818a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* there is at least one dangerous character in the 1819a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value, which we have to quote. Write double quotes 1820a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann around the value and escape special characters with 1821a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann a backslash */ 182273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt printf(" \""); 1823a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1824a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann for (p = strpbrk(value, escape_chars); p != NULL; 1825a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann p = strpbrk(value, escape_chars)) { 1826a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (p > value) 1827a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fwrite(value, 1, p - value, stdout); 1828a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('\\'); 1829a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(*p); 1830a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value = p + 1; 1831a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1832a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1833a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* print the rest and finish the double quoted 1834a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann string */ 1835a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 183673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt putchar('\"'); 1837a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1838a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann} 18390f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 18401de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtconst struct xtables_pprot xtables_chain_protos[] = { 18411de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"tcp", IPPROTO_TCP}, 18421de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"sctp", IPPROTO_SCTP}, 18431de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udp", IPPROTO_UDP}, 18441de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udplite", IPPROTO_UDPLITE}, 18451de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmp", IPPROTO_ICMP}, 18461de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmpv6", IPPROTO_ICMPV6}, 18471de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-icmp", IPPROTO_ICMPV6}, 18481de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"esp", IPPROTO_ESP}, 18491de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ah", IPPROTO_AH}, 18501de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-mh", IPPROTO_MH}, 18511de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"mh", IPPROTO_MH}, 18521de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"all", 0}, 18531de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {NULL}, 18541de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt}; 18551de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 18567ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtuint16_t 18571de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtxtables_parse_protocol(const char *s) 18581de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt{ 185985f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt const struct protoent *pent; 186085f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt unsigned int proto, i; 18611de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 186285f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt if (xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX)) 186385f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt return proto; 18641de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 186585f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt /* first deal with the special case of 'all' to prevent 186685f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt * people from being able to redefine 'all' in nsswitch 186785f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt * and/or provoke expensive [not working] ldap/nis/... 186885f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt * lookups */ 186985f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt if (strcmp(s, "all") == 0) 187085f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt return 0; 18711de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 187285f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt pent = getprotobyname(s); 187385f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt if (pent != NULL) 187485f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt return pent->p_proto; 1875e55cc4aaa6e35448c14370e5261c3387d26b257dPablo Neira Ayuso 187685f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) { 187785f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt if (xtables_chain_protos[i].name == NULL) 187885f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt continue; 187985f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt if (strcmp(s, xtables_chain_protos[i].name) == 0) 188085f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt return xtables_chain_protos[i].num; 18811de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 188285f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt xt_params->exit_err(PARAMETER_PROBLEM, 188385f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt "unknown protocol \"%s\" specified", s); 188485f423addb46736e414f70b59c9f885e99aeb488Jan Engelhardt return -1; 18851de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt} 1886f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt 1887f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardtint kernel_version; 1888f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt 1889f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardtvoid get_kernel_version(void) 1890f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt{ 1891f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt static struct utsname uts; 1892f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt int x = 0, y = 0, z = 0; 1893f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt 1894f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt if (uname(&uts) == -1) { 1895f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt fprintf(stderr, "Unable to retrieve kernel version.\n"); 1896f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt xtables_free_opts(1); 1897f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt exit(1); 1898f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt } 1899f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt 1900f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt sscanf(uts.release, "%d.%d.%d", &x, &y, &z); 1901f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt kernel_version = LINUX_VERSION(x, y, z); 1902f56b8a8bf4b1041cb875fd8439778f35276bdb30Jan Engelhardt} 1903