xtables.c revision 77f48c2f1ef21fa43aa68c25a1457db319ca2526
15208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI/* 25208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * (C) 2000-2006 by the netfilter coreteam <coreteam@netfilter.org>: 35208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * 45208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * This program is free software; you can redistribute it and/or modify 55208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * it under the terms of the GNU General Public License as published by 65208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * the Free Software Foundation; either version 2 of the License, or 75208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * (at your option) any later version. 85208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * 95208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * This program is distributed in the hope that it will be useful, 105208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * but WITHOUT ANY WARRANTY; without even the implied warranty of 115208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 125208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * GNU General Public License for more details. 135208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * 145208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * You should have received a copy of the GNU General Public License 155208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * along with this program; if not, write to the Free Software 165208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 175208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI */ 185208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI 193dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <errno.h> 200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <fcntl.h> 2104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI#include <netdb.h> 22aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt#include <stdarg.h> 23cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt#include <stdbool.h> 243dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdio.h> 253dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdlib.h> 260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <string.h> 270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <unistd.h> 280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#include <sys/socket.h> 290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/stat.h> 300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/types.h> 310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/wait.h> 3208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#include <arpa/inet.h> 333dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 345208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#include <xtables.h> 3577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt#include <linux/netfilter_ipv4/ip_tables.h> 3677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt#include <linux/netfilter_ipv6/ip6_tables.h> 37ef18e8147903885708d1c264904129af4fb636d6Jan Engelhardt#include <libiptc/libxtc.h> 383dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 395a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#ifndef NO_SHARED_LIBS 405a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#include <dlfcn.h> 415a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger#endif 425a26b5fd7bf11ca93d54fe7dc24b3423fb7d89b2Mike Frysinger 430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#define NPROTO 255 440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 450b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#ifndef PROC_SYS_MODPROBE 460b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" 470b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#endif 480b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 49dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt/** 5077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * xtables_afinfo - protocol family dependent information 5177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @kmod: kernel module basename (e.g. "ip_tables") 5277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @libprefix: prefix of .so library name (e.g. "libipt_") 5377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @family: nfproto family 5477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @ipproto: used by setsockopt (e.g. IPPROTO_IP) 5577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @so_rev_match: optname to check revision support of match 5677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt * @so_rev_target: optname to check revision support of target 5777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt */ 5877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstruct xtables_afinfo { 5977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt const char *kmod; 6077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt const char *libprefix; 6177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt uint8_t family; 6277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt uint8_t ipproto; 6377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt int so_rev_match; 6477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt int so_rev_target; 6577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 6677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 6777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv4 = { 6877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip_tables", 6977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libipt_", 7077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV4, 7177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IP, 7277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IPT_SO_GET_REVISION_MATCH, 7377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IPT_SO_GET_REVISION_TARGET, 7477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 7577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 7677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo afinfo_ipv6 = { 7777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .kmod = "ip6_tables", 7877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .libprefix = "libip6t_", 7977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .family = NFPROTO_IPV6, 8077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .ipproto = IPPROTO_IPV6, 8177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_match = IP6T_SO_GET_REVISION_MATCH, 8277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt .so_rev_target = IP6T_SO_GET_REVISION_TARGET, 8377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt}; 8477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 8577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtstatic const struct xtables_afinfo *afinfo; 8677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 8777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt/** 88dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt * Program will set this to its own name. 89dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt */ 90dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardtconst char *xtables_program_name; 91dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt 9239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt/* Search path for Xtables .so files */ 9339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtstatic const char *xtables_libdir; 940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 950b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI/* the path to command to load kernel module */ 96c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtconst char *xtables_modprobe_program; 970b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI/* Keeping track of external matches and targets: linked lists. */ 990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_match *xtables_matches; 1000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_target *xtables_targets; 1010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 10239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardtvoid xtables_init(void) 10339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt{ 10439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("XTABLES_LIBDIR"); 10539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) 10639bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 10739bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = getenv("IPTABLES_LIB_DIR"); 10839bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt if (xtables_libdir != NULL) { 10939bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt fprintf(stderr, "IPTABLES_LIB_DIR is deprecated, " 11039bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt "use XTABLES_LIBDIR.\n"); 11139bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt return; 11239bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt } 11339bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt xtables_libdir = XTABLES_LIBDIR; 11439bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt} 11539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt 11677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardtvoid xtables_set_nfproto(uint8_t nfproto) 11777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt{ 11877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt switch (nfproto) { 11977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV4: 12077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv4; 12177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 12277f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt case NFPROTO_IPV6: 12377f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt afinfo = &afinfo_ipv6; 12477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt break; 12577f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt default: 12677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt fprintf(stderr, "libxtables: unhandled NFPROTO in %s\n", 12777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt __func__); 12877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt } 12977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt} 13077f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt 131630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt/** 132630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt * xtables_*alloc - wrappers that exit on failure 133630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt */ 134630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_calloc(size_t count, size_t size) 1353dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 1363dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 1373dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 1383dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = calloc(count, size)) == NULL) { 1393dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: calloc failed"); 1403dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 1413dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 1423dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 1433dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 1443dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 1453dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 146630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardtvoid *xtables_malloc(size_t size) 1473dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 1483dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 1493dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 1503dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = malloc(size)) == NULL) { 1513dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: malloc failed"); 1523dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 1533dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 1543dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 1553dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 1563dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 1570b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1580b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIstatic char *get_modprobe(void) 1590b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 1600b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int procfile; 1610b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *ret; 1620b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1630b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROCFILE_BUFSIZ 1024 1640b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI procfile = open(PROC_SYS_MODPROBE, O_RDONLY); 1650b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (procfile < 0) 1660b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 1670b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1680b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret = (char *) malloc(PROCFILE_BUFSIZ); 1690b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret) { 1700b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI memset(ret, 0, PROCFILE_BUFSIZ); 1710b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (read(procfile, ret, PROCFILE_BUFSIZ)) { 1720b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: goto fail; 1730b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */ 1740b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 1750b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret[strlen(ret)-1]=='\n') 1760b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret[strlen(ret)-1]=0; 1770b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 1780b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return ret; 1790b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 1800b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI fail: 1810b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(ret); 1820b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 1830b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 1840b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 1850b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 186c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_insmod(const char *modname, const char *modprobe, bool quiet) 1870b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 1880b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *buf = NULL; 1890b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *argv[4]; 1900b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int status; 1910b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1920b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* If they don't explicitly set it, read out of kernel */ 1930b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!modprobe) { 1940b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI buf = get_modprobe(); 1950b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!buf) 1960b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 1970b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI modprobe = buf; 1980b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 1990b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2000b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (fork()) { 2010b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case 0: 2020b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[0] = (char *)modprobe; 2030b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[1] = (char *)modname; 2040b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (quiet) { 2050b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = "-q"; 2060b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 2070b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } else { 2080b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = NULL; 2090b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 2100b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 2110b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI execv(argv[0], argv); 2120b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2130b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* not usually reached */ 2140b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI exit(1); 2150b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: 2160b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 2170b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2180b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI default: /* parent */ 2190b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI wait(&status); 2200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 2210b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 2220b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(buf); 2230b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 2240b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return 0; 2250b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 2260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 2270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 228c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardtint xtables_load_ko(const char *modprobe, bool quiet) 2290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 230c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt static bool loaded = false; 2310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI static int ret = -1; 2320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!loaded) { 23477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ret = xtables_insmod(afinfo->kmod, modprobe, quiet); 2350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI loaded = (ret == 0); 2360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 2370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ret; 2390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 2400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2415f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt/** 2425f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * xtables_strtou{i,l} - string to number conversion 2435f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @s: input string 2445f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @end: like strtoul's "end" pointer 2455f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @value: pointer for result 2465f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @min: minimum accepted value 2475f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * @max: maximum accepted value 2485f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * 2495f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * If @end is NULL, we assume the caller wants a "strict strtoul", and hence 2505f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * "15a" is rejected. 2515f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * In either case, the value obtained is compared for min-max compliance. 2525f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Base is always 0, i.e. autodetect depending on @s. 253cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt * 2545f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * Returns true/false whether number was accepted. On failure, *value has 2555f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt * undefined contents. 256cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt */ 2575f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoul(const char *s, char **end, unsigned long *value, 2585f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned long min, unsigned long max) 259cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 260cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt unsigned long v; 261cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt char *my_end; 262cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 263cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt errno = 0; 264cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt v = strtoul(s, &my_end, 0); 265cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 266cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (my_end == s) 267cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 268cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end != NULL) 269cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *end = my_end; 270cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 271cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (errno != ERANGE && min <= v && (max == 0 || v <= max)) { 272cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 273cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 274cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (end == NULL) 275cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return *my_end == '\0'; 276cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return true; 277cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt } 278cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 279cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return false; 280cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 281cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 2825f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardtbool xtables_strtoui(const char *s, char **end, unsigned int *value, 2835f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt unsigned int min, unsigned int max) 284cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt{ 285cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt unsigned long v; 286cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt bool ret; 287cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 2885f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt ret = xtables_strtoul(s, end, &v, min, max); 289cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt if (value != NULL) 290cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt *value = v; 291cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt return ret; 292cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt} 293cd9e7aa106e80c44bd526af74b616701b0772d05Jan Engelhardt 294aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtint xtables_service_to_port(const char *name, const char *proto) 29504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 29604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI struct servent *service; 29704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 29804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((service = getservbyname(name, proto)) != NULL) 29904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return ntohs((unsigned short) service->s_port); 30004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 30104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return -1; 30204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 30304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 304aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtu_int16_t xtables_parse_port(const char *port, const char *proto) 30504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 3067a236f4cc685a420c1a782a5db614a93baf37ccfJan Engelhardt unsigned int portnum; 30704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 3085f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (xtables_strtoui(port, NULL, &portnum, 0, UINT16_MAX) || 309aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt (portnum = xtables_service_to_port(port, proto)) != (unsigned)-1) 310213e185afbb298e6708881e4c2adffdc47a8b6daJan Engelhardt return portnum; 31104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 31204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 31304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "invalid port/service `%s' specified", port); 31404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 31504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 316aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardtvoid xtables_parse_interface(const char *arg, char *vianame, 317aae6be9edc99e58164a3592c510fe5488141c698Jan Engelhardt unsigned char *mask) 31804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 31904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI int vialen = strlen(arg); 32004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int i; 32104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 32204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 32304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(vianame, 0, IFNAMSIZ); 32404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 32504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vialen + 1 > IFNAMSIZ) 32604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 32704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "interface name `%s' must be shorter than IFNAMSIZ" 32804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI " (%i)", arg, IFNAMSIZ-1); 32904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 33004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI strcpy(vianame, arg); 33104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((vialen == 0) || (vialen == 1 && vianame[0] == '+')) 33204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 33304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI else if (vianame[vialen - 1] == '+') { 33404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen - 1); 33504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1); 33604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Don't remove `+' here! -HW */ 33704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } else { 33804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Include nul-terminator in match */ 33904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen + 1); 34004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1); 34104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI for (i = 0; vianame[i]; i++) { 34204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vianame[i] == ':' || 34304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '!' || 34404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '*') { 345aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann fprintf(stderr, 346aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann "Warning: weird character in interface" 347aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann " `%s' (No aliases, :, ! or *).\n", 348aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann vianame); 34904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI break; 35004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 35104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 35204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 35304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 35404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 355cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#ifndef NO_SHARED_LIBS 35621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardtstatic void *load_extension(const char *search_path, const char *prefix, 35721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *name, bool is_target) 35821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt{ 35921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt const char *dir = search_path, *next; 36021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt void *ptr = NULL; 36121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt struct stat sb; 36221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt char path[256]; 36321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 36421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt do { 36521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = strchr(dir, ':'); 36621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (next == NULL) 36721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt next = dir + strlen(dir); 36821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt snprintf(path, sizeof(path), "%.*s/libxt_%s.so", 3692c0a0c9eba1d1ab39dcde54bc822d4788f9531fcJan Engelhardt (unsigned int)(next - dir), dir, name); 37021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 37121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (dlopen(path, RTLD_NOW) != NULL) { 37221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt /* Found library. If it didn't register itself, 37321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt maybe they specified target as match. */ 37421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 3752338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 37621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 3772338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 3782338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 37921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } else if (stat(path, &sb) == 0) { 38021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 38121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } 38221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 38321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (ptr != NULL) 38421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return ptr; 38521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 38621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt snprintf(path, sizeof(path), "%.*s/%s%s.so", 3872c0a0c9eba1d1ab39dcde54bc822d4788f9531fcJan Engelhardt (unsigned int)(next - dir), dir, prefix, name); 38821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (dlopen(path, RTLD_NOW) != NULL) { 38921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (is_target) 3902338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_target(name, XTF_DONT_LOAD); 39121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt else 3922338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt ptr = xtables_find_match(name, 3932338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt XTF_DONT_LOAD, NULL); 39421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } else if (stat(path, &sb) == 0) { 39521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt fprintf(stderr, "%s: %s\n", path, dlerror()); 39621b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } 39721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 39821b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt if (ptr != NULL) 39921b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return ptr; 40021b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 40121b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt dir = next + 1; 40221b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt } while (*next != '\0'); 40321b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 40421b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt return NULL; 40521b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt} 406cb25af809a8734c4766b6bfa4cca99596cbf01dbJan Engelhardt#endif 40721b41eea4724c57d2b6e5998cf38255046e43ad3Jan Engelhardt 4082338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_match * 4092338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_match(const char *name, enum xtables_tryload tryload, 4102338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt struct xtables_rule_match **matches) 4110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 4120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *ptr; 4130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI const char *icmp6 = "icmp6"; 4140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is ugly as hell. Nonetheless, there is no way of changing 4160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI * this without hurting backwards compatibility */ 4170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if ( (strcmp(name,"icmpv6") == 0) || 4180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"ipv6-icmp") == 0) || 4190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"icmp6") == 0) ) 4200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = icmp6; 4210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_matches; ptr; ptr = ptr->next) { 4230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) { 4240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *clone; 4250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* First match of this type: */ 4270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr->m == NULL) 4280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 4290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Second and subsequent clones */ 431630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt clone = xtables_malloc(sizeof(struct xtables_match)); 4320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI memcpy(clone, ptr, sizeof(struct xtables_match)); 4330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->mflags = 0; 4340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is a clone: */ 4350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->next = clone; 4360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = clone; 4380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 4390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 4432338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 44477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 44539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, false); 446170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 4472338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 4480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 4490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load match `%s':%s\n", 4500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 4510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 4530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 4542338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 4550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 4560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 4570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 4580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4592338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if(!ptr && (tryload == XTF_LOAD_MUST_SUCCEED)) { 4600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 4610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find match `%s'\n", name); 4620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 4640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && matches) { 4660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match **i; 4670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match *newentry; 4680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 469630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt newentry = xtables_malloc(sizeof(struct xtables_rule_match)); 4700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = matches; *i; i = &(*i)->next) { 4720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, (*i)->match->name) == 0) 4732338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt (*i)->completed = true; 4740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->match = ptr; 4762338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt newentry->completed = false; 4770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->next = NULL; 4780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = newentry; 4790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 4820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 4830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4842338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtstruct xtables_target * 4852338efd8f799d8373dc196c797bda9690283b698Jan Engelhardtxtables_find_target(const char *name, enum xtables_tryload tryload) 4860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 4870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *ptr; 4880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Standard target? */ 4900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, "") == 0 4910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_ACCEPT) == 0 4920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_DROP) == 0 4930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_QUEUE) == 0 4940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_RETURN) == 0) 4950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = "standard"; 4960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_targets; ptr; ptr = ptr->next) { 4980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) 4990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 5000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 5032338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (!ptr && tryload != XTF_DONT_LOAD && tryload != XTF_DURING_LOAD) { 50477f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt ptr = load_extension(xtables_libdir, afinfo->libprefix, 50539bf9c8214d3073a496a8a1eff91046a8d6fbbdfJan Engelhardt name, true); 506170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 5072338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (ptr == NULL && tryload == XTF_LOAD_MUST_SUCCEED) 5080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 5090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load target `%s':%s\n", 5100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 5110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 5130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 5142338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt if (tryload != XTF_DONT_LOAD) 5150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 5160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 5170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 5180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if(!ptr && (tryload == LOAD_MUST_SUCCEED)) { 5200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 5210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find target `%s'\n", name); 5220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 5240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr) 5260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->used = 1; 5270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 5290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 5300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_revision(const char *name, u_int8_t revision, int opt) 5320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 5330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xt_get_revision rev; 5340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI socklen_t s = sizeof(rev); 5350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI int max_rev, sockfd; 5360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 53777f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt sockfd = socket(afinfo->family, SOCK_RAW, IPPROTO_RAW); 5380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (sockfd < 0) { 539df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (errno == EPERM) { 540df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy /* revision 0 is always supported. */ 541df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (revision != 0) 542df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy fprintf(stderr, "Could not determine whether " 543df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "revision %u is supported, " 544df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "assuming it is.\n", 545df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy revision); 546df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy return 1; 547df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy } 5480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "Could not open socket to kernel: %s\n", 5490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 5500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 553c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt xtables_load_ko(xtables_modprobe_program, true); 5540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strcpy(rev.name, name); 5560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI rev.revision = revision; 5570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 55877f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt max_rev = getsockopt(sockfd, afinfo->ipproto, opt, &rev, &s); 5590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (max_rev < 0) { 5600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Definitely don't support this? */ 5610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (errno == ENOENT || errno == EPROTONOSUPPORT) { 5620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 5630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 0; 5640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else if (errno == ENOPROTOOPT) { 5650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 5660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Assume only revision 0 support (old kernel) */ 5670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return (revision == 0); 5680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else { 5690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "getsockopt failed strangely: %s\n", 5700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 5710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 5750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 1; 5760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 5770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_match_revision(const char *name, u_int8_t revision) 5800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 58177f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_match); 5820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 5830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_target_revision(const char *name, u_int8_t revision) 5850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 58677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt return compatible_revision(name, revision, afinfo->so_rev_target); 5870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 5880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_match(struct xtables_match *me) 5900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 5910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match **i, *old; 5920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 593dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 594dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: match \"%s\" has version \"%s\", " 595dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 596dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, 597dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 5980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 6020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 6030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 604dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 6050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 6090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 6100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: match %s has invalid protocol family\n", 611dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 6120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested match */ 61677f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 6170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 6180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6192338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_match(me->name, XTF_DURING_LOAD, NULL); 6200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 62123545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && 62223545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt old->family == me->family) { 6230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 6240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: match `%s' already registered.\n", 625dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 6260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 6300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_match_revision(old->name, old->revision) 6310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 6320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 6330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 63423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new match can be used. */ 6350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_match_revision(me->name, me->revision)) 6360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 6370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 63823545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */ 63923545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && me->family == AF_UNSPEC) 64023545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt return; 64123545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt 6420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 6430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i!=old; i = &(*i)->next); 6440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 6450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 6480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: match `%s' has invalid size %u.\n", 649dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, (unsigned int)me->size); 6500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Append to list. */ 6540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i; i = &(*i)->next); 6550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = NULL; 6560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = me; 6570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->m = NULL; 6590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->mflags = 0; 6600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 6610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_target(struct xtables_target *me) 6630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 6640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *old; 6650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 666dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt if (strcmp(me->version, XTABLES_VERSION) != 0) { 667dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt fprintf(stderr, "%s: target \"%s\" has version \"%s\", " 668dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt "but \"%s\" is required.\n", 669dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, 670dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt me->version, XTABLES_VERSION); 6710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 6750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 6760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 677dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 6780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 6820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 6830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: target %s has invalid protocol family\n", 684dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 6850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 6860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 6870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested target */ 68977f48c2f1ef21fa43aa68c25a1457db319ca2526Jan Engelhardt if (me->family != afinfo->family && me->family != AF_UNSPEC) 6900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 6910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 6922338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt old = xtables_find_target(me->name, XTF_DURING_LOAD); 6930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 6940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target **i; 6950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 69623545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && 69723545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt old->family == me->family) { 6980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 6990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: target `%s' already registered.\n", 700dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name); 7010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 7050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_target_revision(old->name, old->revision) 7060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 7070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 70923545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* See if new target can be used. */ 7100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_target_revision(me->name, me->revision)) 7110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 7120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 71323545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt /* Prefer !AF_UNSPEC over AF_UNSPEC for same revision. */ 71423545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt if (old->revision == me->revision && me->family == AF_UNSPEC) 71523545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt return; 71623545c2a7a31c68c1e49c7c901b632c2f1c59968Jan Engelhardt 7170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 7180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_targets; *i!=old; i = &(*i)->next); 7190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 7200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 7230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid size %u.\n", 724dacafa55379fd98212031d8c559096c91d7ce93bJan Engelhardt xtables_program_name, me->name, (unsigned int)me->size); 7250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 7260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 7270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 7280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Prepend to list. */ 7290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = xtables_targets; 7300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI xtables_targets = me; 7310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->t = NULL; 7320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->tflags = 0; 7330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 734aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 735a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt/** 736a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * xtables_param_act - act on condition 737a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @status: a constant from enum xtables_exittype 738a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 739a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONLY_ONCE: print error message that option may only be used once. 740a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name (e.g. "mark") 741a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2(...): option in conflict (e.g. "--mark") 742a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3(...): condition to match on (see extensions/ for examples) 743a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 744a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_NO_INVERT: option does not support inversion 745a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 746a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option in conflict 747a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: condition to match on 748a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 749a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_BAD_VALUE: bad value for option 750a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 751a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p2: option with which the problem occured (e.g. "--mark") 752a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p3: string the user passed in (e.g. "99999999999999") 753a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 754a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * %XTF_ONE_ACTION: two mutually exclusive actions have been specified 755a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * @p1: module name 756a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * 757a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt * Displays an error message and exits the program. 758a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt */ 759a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardtvoid xtables_param_act(unsigned int status, const char *p1, ...) 760aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt{ 761aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt const char *p2, *p3; 762aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_list args; 763aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt bool b; 764aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 765aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_start(args, p1); 766aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 767aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt switch (status) { 768a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONLY_ONCE: 769aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 770aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 771aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 772aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 773aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt exit_error(PARAMETER_PROBLEM, 774aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option may only be specified once", 775aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2); 776aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 777a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_NO_INVERT: 778aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 779aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 780aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 781aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 782aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt exit_error(PARAMETER_PROBLEM, 783aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: \"%s\" option cannot be inverted", p1, p2); 784aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 785a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_BAD_VALUE: 786aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p2 = va_arg(args, const char *); 787aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p3 = va_arg(args, const char *); 788aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt exit_error(PARAMETER_PROBLEM, 789aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: Bad value for \"%s\" option: \"%s\"", 790aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt p1, p2, p3); 791aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 792a41545ca7cde43e0ba53260ba74bd9bf74025a68Jan Engelhardt case XTF_ONE_ACTION: 793aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt b = va_arg(args, unsigned int); 794aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt if (!b) 795aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt return; 796aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt exit_error(PARAMETER_PROBLEM, 797aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt "%s: At most one action is possible", p1); 798aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 799aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt default: 800aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt exit_error(status, p1, args); 801aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt break; 802aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt } 803aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt 804aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt va_end(args); 805aafd269675fc45bac6340027c866ea6073643c3bJan Engelhardt} 80608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 807e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_numeric(const struct in_addr *addrp) 80808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 80908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 81008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const unsigned char *bytep = (const void *)&addrp->s_addr; 81108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 81208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "%u.%u.%u.%u", bytep[0], bytep[1], bytep[2], bytep[3]); 81308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 81408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 81508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 81608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_host(const struct in_addr *addr) 81708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 81808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct hostent *host; 81908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 82008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt host = gethostbyaddr(addr, sizeof(struct in_addr), AF_INET); 82108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (host == NULL) 82208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 82308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 82408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return host->h_name; 82508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 82608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 82708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ipaddr_to_network(const struct in_addr *addr) 82808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 82908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct netent *net; 83008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 83108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((net = getnetbyaddr(ntohl(addr->s_addr), AF_INET)) != NULL) 83208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return net->n_name; 83308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 83408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 83508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 83608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 837e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipaddr_to_anyname(const struct in_addr *addr) 83808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 83908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 84008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 84108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ipaddr_to_host(addr)) != NULL || 84208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt (name = ipaddr_to_network(addr)) != NULL) 84308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 84408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 845e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ipaddr_to_numeric(addr); 84608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 84708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 848e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ipmask_to_numeric(const struct in_addr *mask) 84908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 85008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[20]; 85108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t maskaddr, bits; 85208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int i; 85308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 85408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt maskaddr = ntohl(mask->s_addr); 85508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 85608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (maskaddr == 0xFFFFFFFFL) 85708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* we don't want to see "/32" */ 85808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return ""; 85908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 86008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt i = 32; 86108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits = 0xFFFFFFFEL; 86208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (--i >= 0 && maskaddr != bits) 86308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt bits <<= 1; 86408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (i >= 0) 86508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", i); 86608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt else 86708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* mask was not a decent combination of 1's and 0's */ 868e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); 86908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 87008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 87108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 87208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 873bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *__numeric_to_ipaddr(const char *dotted, bool is_mask) 874bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 875bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 876bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned char *addrp; 877bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int onebyte; 878bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[20], *p, *q; 879bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int i; 880bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 881bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* copy dotted string, because we need to modify it */ 882bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, dotted, sizeof(buf) - 1); 883bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 884bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = (void *)&addr.s_addr; 885bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 886bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = buf; 887bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < 3; ++i) { 888bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((q = strchr(p, '.')) == NULL) { 889bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (is_mask) 890bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 891bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 892bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* autocomplete, this is a network address */ 8935f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 894bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 895bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 896bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 897bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (i < 3) 898bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[++i] = 0; 899bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 900bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 901bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 902bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 903bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *q = '\0'; 9045f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 905bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 906bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 907bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[i] = onebyte; 908bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p = q + 1; 909bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 910bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 911bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* we have checked 3 bytes, now we check the last one */ 9125f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(p, NULL, &onebyte, 0, UINT8_MAX)) 913bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 914bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 915bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[3] = onebyte; 916bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 917bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 918bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 9191e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipaddr(const char *dotted) 920bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 921bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, false); 922bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 923bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 9241e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in_addr *xtables_numeric_to_ipmask(const char *dotted) 925bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 926bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return __numeric_to_ipaddr(dotted, true); 927bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 928bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 929bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *network_to_ipaddr(const char *name) 930bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 931bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr addr; 932bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct netent *net; 933bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 934bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((net = getnetbyname(name)) != NULL) { 935bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (net->n_addrtype != AF_INET) 936bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 937bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addr.s_addr = htonl(net->n_net); 938bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &addr; 939bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 940bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 941bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 942bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 943bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 944bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *host_to_ipaddr(const char *name, unsigned int *naddr) 945bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 946bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct hostent *host; 947bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addr; 948bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i; 949bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 950bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 951bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((host = gethostbyname(name)) != NULL) { 952bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (host->h_addrtype != AF_INET || 953bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt host->h_length != sizeof(struct in_addr)) 954bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 955bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 956bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt while (host->h_addr_list[*naddr] != NULL) 957bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++*naddr; 958630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addr = xtables_calloc(*naddr, sizeof(struct in_addr) * *naddr); 959bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0; i < *naddr; i++) 960bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(&addr[i], host->h_addr_list[i], 961bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in_addr)); 962bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 963bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 964bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 965bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 966bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 967bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 968bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr * 969bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtipparse_hostnetwork(const char *name, unsigned int *naddrs) 970bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 971bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrptmp, *addrp; 972bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 9731e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ipaddr(name)) != NULL || 974bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ipaddr(name)) != NULL) { 975630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in_addr)); 976bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 977bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 978bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 979bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 980bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrptmp = host_to_ipaddr(name, naddrs)) != NULL) 981bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrptmp; 982bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 983bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", name); 984bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 985bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 986bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in_addr *parse_ipmask(const char *mask) 987bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 988bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in_addr maskaddr; 989bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 990bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 991bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 992bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 993bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 32 bits */ 994bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0xFFFFFFFF; 995bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 996bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 9971e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ipmask(mask)) != NULL) 998bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* dotted_to_addr already returns a network byte order addr */ 999bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 10005f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 32)) 1001bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt exit_error(PARAMETER_PROBLEM, 1002bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1003bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1004bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); 1005bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1006bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1007bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1008bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt maskaddr.s_addr = 0U; 1009bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1010bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1011bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1012a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt/** 1013a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * xtables_ipparse_any - transform arbitrary name to in_addr 1014a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * 1015a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * Possible inputs (pseudo regex): 1016a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * m{^($hostname|$networkname|$ipaddr)(/$mask)?} 1017a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt * "1.2.3.4/5", "1.2.3.4", "hostname", "networkname" 1018a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt */ 1019a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ipparse_any(const char *name, struct in_addr **addrpp, 1020a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in_addr *maskp, unsigned int *naddrs) 1021bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1022bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1023bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in_addr *addrp; 1024bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1025bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1026bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1027bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf) - 1] = '\0'; 1028bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1029bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1030bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(p + 1); 1031bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1032bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ipmask(NULL); 1033bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1034bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1035bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1036bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1037bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (maskp->s_addr == 0U) 1038bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "0.0.0.0"); 1039bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1040bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ipparse_hostnetwork(buf, naddrs); 1041bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1042bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1043bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp[j++].s_addr &= maskp->s_addr; 1044bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1045bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (addrp[k].s_addr == addrp[j-1].s_addr) { 1046bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --*naddrs; 1047bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --j; 1048bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1049bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1050bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1051bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1052bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1053e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_numeric(const struct in6_addr *addrp) 105408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 105508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt /* 0000:0000:0000:0000:0000:000.000.000.000 105608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt * 0000:0000:0000:0000:0000:0000:0000:0000 */ 105708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+1]; 105808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); 105908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 106008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 106108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic const char *ip6addr_to_host(const struct in6_addr *addr) 106208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 106308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char hostname[NI_MAXHOST]; 106408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt struct sockaddr_in6 saddr; 106508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int err; 106608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 106708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memset(&saddr, 0, sizeof(struct sockaddr_in6)); 106808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt memcpy(&saddr.sin6_addr, addr, sizeof(*addr)); 106908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt saddr.sin6_family = AF_INET6; 107008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 107108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt err = getnameinfo((const void *)&saddr, sizeof(struct sockaddr_in6), 107208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt hostname, sizeof(hostname) - 1, NULL, 0, 0); 107308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (err != 0) { 107408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 107508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf(stderr,"IP2Name: %s\n",gai_strerror(err)); 107608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 107708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return NULL; 107808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 107908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 108008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#ifdef DEBUG 108108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt fprintf (stderr, "\naddr2host: %s\n", hostname); 108208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt#endif 108308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return hostname; 108408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 108508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1086e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6addr_to_anyname(const struct in6_addr *addr) 108708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 108808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt const char *name; 108908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 109008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if ((name = ip6addr_to_host(addr)) != NULL) 109108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return name; 109208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1093e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt return xtables_ip6addr_to_numeric(addr); 109408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 109508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 109608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardtstatic int ip6addr_prefix_length(const struct in6_addr *k) 109708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 109808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt unsigned int bits = 0; 109908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt uint32_t a, b, c, d; 110008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 110148607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt a = ntohl(k->s6_addr32[0]); 110248607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt b = ntohl(k->s6_addr32[1]); 110348607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt c = ntohl(k->s6_addr32[2]); 110448607816796124ce2177ee22645d3fd8180f1e98Jan Engelhardt d = ntohl(k->s6_addr32[3]); 110508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt while (a & 0x80000000U) { 110608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt ++bits; 110708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a <<= 1; 110808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt a |= (b >> 31) & 1; 110908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b <<= 1; 111008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt b |= (c >> 31) & 1; 111108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c <<= 1; 111208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt c |= (d >> 31) & 1; 111308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt d <<= 1; 111408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 111508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (a != 0 || b != 0 || c != 0 || d != 0) 111608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return -1; 111708b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return bits; 111808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 111908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 1120e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardtconst char *xtables_ip6mask_to_numeric(const struct in6_addr *addrp) 112108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt{ 112208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt static char buf[50+2]; 112308b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt int l = ip6addr_prefix_length(addrp); 112408b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt 112508b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt if (l == -1) { 112608b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt strcpy(buf, "/"); 1127e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt strcat(buf, xtables_ip6addr_to_numeric(addrp)); 112808b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 112908b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt } 113008b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt sprintf(buf, "/%d", l); 113108b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt return buf; 113208b1616e068166e016b3ee7110db10ae5d853422Jan Engelhardt} 1133bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 11341e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardtstruct in6_addr *xtables_numeric_to_ip6addr(const char *num) 1135bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1136bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr ap; 1137bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1138bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1139bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = inet_pton(AF_INET6, num, &ap)) == 1) 1140bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return ≈ 1141bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1142bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "\nnumeric2addr: %d\n", err); 1143bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1144bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1145bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1146bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1147bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1148bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardthost_to_ip6addr(const char *name, unsigned int *naddr) 1149bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1150bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr *addr; 1151bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo hints; 1152bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct addrinfo *res; 1153bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt int err; 1154bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1155bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&hints, 0, sizeof(hints)); 1156bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_flags = AI_CANONNAME; 1157bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_family = AF_INET6; 1158bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_socktype = SOCK_RAW; 1159bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_protocol = IPPROTO_IPV6; 1160bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt hints.ai_next = NULL; 1161bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1162bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 0; 1163bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((err = getaddrinfo(name, NULL, &hints, &res)) != 0) { 1164bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1165bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr,"Name2IP: %s\n",gai_strerror(err)); 1166bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1167bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1168bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1169bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (res->ai_family != AF_INET6 || 1170bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt res->ai_addrlen != sizeof(struct sockaddr_in6)) 1171bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1172bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1173bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#ifdef DEBUG 1174bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt fprintf(stderr, "resolved: len=%d %s ", res->ai_addrlen, 1175bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ip6addr_to_numeric(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr)); 1176bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt#endif 1177bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* Get the first element of the address-chain */ 1178630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addr = xtables_malloc(sizeof(struct in6_addr)); 1179bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addr, &((const struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 1180bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt sizeof(struct in6_addr)); 1181bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt freeaddrinfo(res); 1182bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddr = 1; 1183bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addr; 1184bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1185bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1186bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1187bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1188bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1189bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *network_to_ip6addr(const char *name) 1190bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1191bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* abort();*/ 1192bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* TODO: not implemented yet, but the exception breaks the 1193bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt * name resolvation */ 1194bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return NULL; 1195bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1196bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1197bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr * 1198bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtip6parse_hostnetwork(const char *name, unsigned int *naddrs) 1199bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1200bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp, *addrptmp; 1201bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 12021e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrptmp = xtables_numeric_to_ip6addr(name)) != NULL || 1203bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt (addrptmp = network_to_ip6addr(name)) != NULL) { 1204630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt addrp = xtables_malloc(sizeof(struct in6_addr)); 1205bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(addrp, addrptmp, sizeof(*addrp)); 1206bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *naddrs = 1; 1207bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1208bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1209bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((addrp = host_to_ip6addr(name, naddrs)) != NULL) 1210bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 1211bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1212bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", name); 1213bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1214bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1215bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardtstatic struct in6_addr *parse_ip6mask(char *mask) 1216bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1217bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt static struct in6_addr maskaddr; 1218bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1219bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int bits; 1220bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1221bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (mask == NULL) { 1222bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* no mask at all defaults to 128 bits */ 1223bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0xff, sizeof maskaddr); 1224bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1225bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 12261e01b0b82f70b0b11dcfbced485dbe7aeac4fb8cJan Engelhardt if ((addrp = xtables_numeric_to_ip6addr(mask)) != NULL) 1227bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return addrp; 12285f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt if (!xtables_strtoui(mask, NULL, &bits, 0, 128)) 1229bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt exit_error(PARAMETER_PROBLEM, 1230bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt "invalid mask `%s' specified", mask); 1231bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (bits != 0) { 1232bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char *p = (void *)&maskaddr; 1233bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p, 0xff, bits / 8); 1234bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(p + (bits / 8) + 1, 0, (128 - bits) / 8); 1235bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt p[bits/8] = 0xff << (8 - (bits & 7)); 1236bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1237bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1238bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1239bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memset(&maskaddr, 0, sizeof(maskaddr)); 1240bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt return &maskaddr; 1241bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1242bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1243a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_ip6parse_any(const char *name, struct in6_addr **addrpp, 1244a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardt struct in6_addr *maskp, unsigned int *naddrs) 1245bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt{ 1246bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt struct in6_addr *addrp; 1247bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt unsigned int i, j, k, n; 1248bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt char buf[256], *p; 1249bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1250bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strncpy(buf, name, sizeof(buf) - 1); 1251bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt buf[sizeof(buf)-1] = '\0'; 1252bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if ((p = strrchr(buf, '/')) != NULL) { 1253bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt *p = '\0'; 1254bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(p + 1); 1255bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } else { 1256bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = parse_ip6mask(NULL); 1257bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1258bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt memcpy(maskp, addrp, sizeof(*maskp)); 1259bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1260bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt /* if a null mask is given, the name is ignored, like in "any/0" */ 1261bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (memcmp(maskp, &in6addr_any, sizeof(in6addr_any)) == 0) 1262bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt strcpy(buf, "::"); 1263bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt 1264bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt addrp = *addrpp = ip6parse_hostnetwork(buf, naddrs); 1265bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt n = *naddrs; 1266bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (i = 0, j = 0; i < n; ++i) { 1267bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < 4; ++k) 12685a2208c3e62a150e6f6297abbfa63056ab4a8066Yasuyuki Kozakai addrp[j].s6_addr32[k] &= maskp->s6_addr32[k]; 1269bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt ++j; 1270bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt for (k = 0; k < j - 1; ++k) 1271bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt if (IN6_ARE_ADDR_EQUAL(&addrp[k], &addrp[j - 1])) { 1272bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --*naddrs; 1273bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt --j; 1274bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt break; 1275bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1276bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt } 1277bd9438420d92c41a5cf20a53b7a18d3ddea4216dJan Engelhardt} 1278a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1279a0baae85f8159f03d52535934aa9b3a375e0f1f3Jan Engelhardtvoid xtables_save_string(const char *value) 1280a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann{ 1281a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char no_quote_chars[] = "_-0123456789" 1282a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "abcdefghijklmnopqrstuvwxyz" 1283a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 1284a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann static const char escape_chars[] = "\"\\'"; 1285a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann size_t length; 1286a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann const char *p; 1287a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1288a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann length = strcspn(value, no_quote_chars); 1289a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (length > 0 && value[length] == 0) { 1290a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* no quoting required */ 1291a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 1292a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(' '); 1293a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } else { 1294a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* there is at least one dangerous character in the 1295a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value, which we have to quote. Write double quotes 1296a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann around the value and escape special characters with 1297a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann a backslash */ 1298a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('"'); 1299a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1300a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann for (p = strpbrk(value, escape_chars); p != NULL; 1301a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann p = strpbrk(value, escape_chars)) { 1302a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann if (p > value) 1303a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fwrite(value, 1, p - value, stdout); 1304a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar('\\'); 1305a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann putchar(*p); 1306a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann value = p + 1; 1307a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1308a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann 1309a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann /* print the rest and finish the double quoted 1310a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann string */ 1311a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann fputs(value, stdout); 1312a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann printf("\" "); 1313a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann } 1314a5d099400fd6f9ad3880dda10f85d2aa36b5ec65Max Kellermann} 13150f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 13160f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt/** 13170f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt * Check for option-intrapositional negation. 13180f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt * Do not use in new code. 13190f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt */ 13200f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardtint xtables_check_inverse(const char option[], int *invert, 13210f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt int *my_optind, int argc) 13220f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt{ 13230f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (option && strcmp(option, "!") == 0) { 13240f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt fprintf(stderr, "Using intrapositioned negation " 13250f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "(`--option ! this`) is deprecated in favor of " 13260f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "extrapositioned (`! --option this`).\n"); 13270f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 13280f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (*invert) 13290f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt exit_error(PARAMETER_PROBLEM, 13300f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "Multiple `!' flags not allowed"); 13310f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt *invert = true; 13320f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (my_optind != NULL) { 13330f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt ++*my_optind; 13340f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt if (argc && *my_optind > argc) 13350f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt exit_error(PARAMETER_PROBLEM, 13360f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt "no argument following `!'"); 13370f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt } 13380f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt 13390f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt return true; 13400f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt } 13410f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt return false; 13420f16c725aadaac7e670d632ecbaea3661ff00827Jan Engelhardt} 13431de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 13441de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtconst struct xtables_pprot xtables_chain_protos[] = { 13451de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"tcp", IPPROTO_TCP}, 13461de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"sctp", IPPROTO_SCTP}, 13471de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udp", IPPROTO_UDP}, 13481de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"udplite", IPPROTO_UDPLITE}, 13491de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmp", IPPROTO_ICMP}, 13501de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"icmpv6", IPPROTO_ICMPV6}, 13511de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-icmp", IPPROTO_ICMPV6}, 13521de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"esp", IPPROTO_ESP}, 13531de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ah", IPPROTO_AH}, 13541de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"ipv6-mh", IPPROTO_MH}, 13551de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"mh", IPPROTO_MH}, 13561de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {"all", 0}, 13571de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt {NULL}, 13581de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt}; 13591de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 13601de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtu_int16_t 13611de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardtxtables_parse_protocol(const char *s) 13621de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt{ 13631de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt unsigned int proto; 13641de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 13651de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (!xtables_strtoui(s, NULL, &proto, 0, UINT8_MAX)) { 13661de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt struct protoent *pent; 13671de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 13681de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt /* first deal with the special case of 'all' to prevent 13691de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * people from being able to redefine 'all' in nsswitch 13701de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * and/or provoke expensive [not working] ldap/nis/... 13711de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt * lookups */ 13721de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (!strcmp(s, "all")) 13731de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt return 0; 13741de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 13751de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if ((pent = getprotobyname(s))) 13761de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt proto = pent->p_proto; 13771de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt else { 13781de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt unsigned int i; 13791de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt for (i = 0; i < ARRAY_SIZE(xtables_chain_protos); ++i) { 13801de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (strcmp(s, xtables_chain_protos[i].name) == 0) { 13811de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt proto = xtables_chain_protos[i].num; 13821de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt break; 13831de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 13841de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 13851de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt if (i == ARRAY_SIZE(xtables_chain_protos)) 13861de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt exit_error(PARAMETER_PROBLEM, 13871de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt "unknown protocol `%s' specified", 13881de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt s); 13891de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 13901de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt } 13911de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt 13921de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt return proto; 13931de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt} 1394