xtables.c revision df1ef3862761e534c6cec6bd9370285cb5909dd0
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 190b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <dlfcn.h> 203dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <errno.h> 210b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <fcntl.h> 2204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI#include <netdb.h> 233dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdio.h> 243dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <stdlib.h> 250b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <string.h> 260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <unistd.h> 270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#include <sys/socket.h> 280b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/stat.h> 290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/types.h> 300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#include <sys/wait.h> 313dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 325208806f2708f761e97e62550561e3164b541770Yasuyuki KOZAKAI#include <xtables.h> 333dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#define NPROTO 255 350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 360b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#ifndef PROC_SYS_MODPROBE 370b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROC_SYS_MODPROBE "/proc/sys/kernel/modprobe" 380b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#endif 390b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIchar *lib_dir; 410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 420b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI/* the path to command to load kernel module */ 430b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIconst char *modprobe = NULL; 440b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI/* Keeping track of external matches and targets: linked lists. */ 460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_match *xtables_matches; 470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_target *xtables_targets; 480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 493dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAIvoid *fw_calloc(size_t count, size_t size) 503dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 513dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 523dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 533dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = calloc(count, size)) == NULL) { 543dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: calloc failed"); 553dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 563dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 573dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 583dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 593dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 603dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 613dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAIvoid *fw_malloc(size_t size) 623dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI{ 633dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI void *p; 643dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 653dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI if ((p = malloc(size)) == NULL) { 663dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI perror("ip[6]tables: malloc failed"); 673dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI exit(1); 683dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI } 693dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI 703dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI return p; 713dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI} 720b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 730b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIstatic char *get_modprobe(void) 740b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 750b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int procfile; 760b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *ret; 770b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 780b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI#define PROCFILE_BUFSIZ 1024 790b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI procfile = open(PROC_SYS_MODPROBE, O_RDONLY); 800b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (procfile < 0) 810b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 820b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 830b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret = (char *) malloc(PROCFILE_BUFSIZ); 840b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret) { 850b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI memset(ret, 0, PROCFILE_BUFSIZ); 860b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (read(procfile, ret, PROCFILE_BUFSIZ)) { 870b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: goto fail; 880b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case PROCFILE_BUFSIZ: goto fail; /* Partial read. Wierd */ 890b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 900b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (ret[strlen(ret)-1]=='\n') 910b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI ret[strlen(ret)-1]=0; 920b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 930b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return ret; 940b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 950b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI fail: 960b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(ret); 970b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI close(procfile); 980b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return NULL; 990b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 1000b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1010b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAIint xtables_insmod(const char *modname, const char *modprobe, int quiet) 1020b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI{ 1030b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *buf = NULL; 1040b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI char *argv[4]; 1050b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI int status; 1060b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1070b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* If they don't explicitly set it, read out of kernel */ 1080b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!modprobe) { 1090b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI buf = get_modprobe(); 1100b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (!buf) 1110b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 1120b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI modprobe = buf; 1130b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 1140b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1150b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI switch (fork()) { 1160b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case 0: 1170b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[0] = (char *)modprobe; 1180b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[1] = (char *)modname; 1190b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (quiet) { 1200b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = "-q"; 1210b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 1220b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } else { 1230b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[2] = NULL; 1240b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI argv[3] = NULL; 1250b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 1260b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI execv(argv[0], argv); 1270b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1280b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI /* not usually reached */ 1290b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI exit(1); 1300b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI case -1: 1310b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 1320b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1330b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI default: /* parent */ 1340b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI wait(&status); 1350b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI } 1360b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1370b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI free(buf); 1380b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI if (WIFEXITED(status) && WEXITSTATUS(status) == 0) 1390b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return 0; 1400b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI return -1; 1410b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI} 1420b82e8e81e887843011c8771f70d2302901f7e5eYasuyuki KOZAKAI 1430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIint load_xtables_ko(const char *modprobe, int quiet) 1440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 1450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI static int loaded = 0; 1460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI static int ret = -1; 1470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!loaded) { 1490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ret = xtables_insmod(afinfo.kmod, modprobe, quiet); 1500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI loaded = (ret == 0); 1510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 1520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 1530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ret; 1540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 1550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 15604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAIint string_to_number_ll(const char *s, unsigned long long min, 15704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned long long max, unsigned long long *ret) 15804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 15904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned long long number; 16004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI char *end; 16104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 16204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Handle hex, octal, etc. */ 16304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI errno = 0; 16404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI number = strtoull(s, &end, 0); 16504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (*end == '\0' && end != s) { 16604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* we parsed a number, let's see if we want this */ 16704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (errno != ERANGE && min <= number && (!max || number <= max)) { 16804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI *ret = number; 16904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return 0; 17004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 17104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 17204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return -1; 17304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 17404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 17504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAIint string_to_number_l(const char *s, unsigned long min, unsigned long max, 17604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned long *ret) 17704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 17804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI int result; 17904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned long long number; 18004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 18104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI result = string_to_number_ll(s, min, max, &number); 18204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI *ret = (unsigned long)number; 18304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 18404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return result; 18504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 18604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 18704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAIint string_to_number(const char *s, unsigned int min, unsigned int max, 18804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int *ret) 18904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 19004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI int result; 19104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned long number; 19204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 19304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI result = string_to_number_l(s, min, max, &number); 19404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI *ret = (unsigned int)number; 19504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 19604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return result; 19704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 19804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 19904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAIint service_to_port(const char *name, const char *proto) 20004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 20104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI struct servent *service; 20204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 20304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((service = getservbyname(name, proto)) != NULL) 20404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return ntohs((unsigned short) service->s_port); 20504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 20604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return -1; 20704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 20804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 20904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAIu_int16_t parse_port(const char *port, const char *proto) 21004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 21104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int portnum; 21204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 21304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((string_to_number(port, 0, 65535, &portnum)) != -1 || 21404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI (portnum = service_to_port(port, proto)) != -1) 21504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI return (u_int16_t)portnum; 21604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 21704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 21804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "invalid port/service `%s' specified", port); 21904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 22004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 22104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAIvoid parse_interface(const char *arg, char *vianame, unsigned char *mask) 22204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI{ 22304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI int vialen = strlen(arg); 22404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI unsigned int i; 22504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 22604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 22704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(vianame, 0, IFNAMSIZ); 22804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 22904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vialen + 1 > IFNAMSIZ) 23004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 23104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI "interface name `%s' must be shorter than IFNAMSIZ" 23204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI " (%i)", arg, IFNAMSIZ-1); 23304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 23404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI strcpy(vianame, arg); 23504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if ((vialen == 0) || (vialen == 1 && vianame[0] == '+')) 23604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0, IFNAMSIZ); 23704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI else if (vianame[vialen - 1] == '+') { 23804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen - 1); 23904f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1); 24004f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Don't remove `+' here! -HW */ 24104f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } else { 24204f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI /* Include nul-terminator in match */ 24304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask, 0xFF, vialen + 1); 24404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1); 24504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI for (i = 0; vianame[i]; i++) { 24604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI if (vianame[i] == ':' || 24704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '!' || 24804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI vianame[i] == '*') { 249aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann fprintf(stderr, 250aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann "Warning: weird character in interface" 251aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann " `%s' (No aliases, :, ! or *).\n", 252aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann vianame); 25304f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI break; 25404f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 25504f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 25604f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI } 25704f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI} 25804f8c54dc52e19096d31d94593bd1040716afe4dYasuyuki KOZAKAI 2590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_match *find_match(const char *name, enum xt_tryload tryload, 2600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match **matches) 2610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 2620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *ptr; 2630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI const char *icmp6 = "icmp6"; 2640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is ugly as hell. Nonetheless, there is no way of changing 2660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI * this without hurting backwards compatibility */ 2670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if ( (strcmp(name,"icmpv6") == 0) || 2680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"ipv6-icmp") == 0) || 2690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (strcmp(name,"icmp6") == 0) ) 2700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = icmp6; 2710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_matches; ptr; ptr = ptr->next) { 2730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) { 2740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match *clone; 2750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* First match of this type: */ 2770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr->m == NULL) 2780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 2790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Second and subsequent clones */ 2810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone = fw_malloc(sizeof(struct xtables_match)); 2820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI memcpy(clone, ptr, sizeof(struct xtables_match)); 2830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->mflags = 0; 2840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* This is a clone: */ 2850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI clone->next = clone; 2860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = clone; 2880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 2890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 2900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 2910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 2920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 2930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) { 2940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI char path[strlen(lib_dir) + sizeof("/.so") 2950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI + strlen(afinfo.libprefix) + strlen(name)]; 296170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 297170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI sprintf(path, "%s/libxt_%s.so", lib_dir, name); 298170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (dlopen(path, RTLD_NOW) != NULL) 2990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Found library. If it didn't register itself, 3000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI maybe they specified target as match. */ 3010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = find_match(name, DONT_LOAD, NULL); 3020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 303170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (ptr == NULL) { 304170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI sprintf(path, "%s/%s%s.so", lib_dir, afinfo.libprefix, 305170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI name); 306170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (dlopen(path, RTLD_NOW) != NULL) 307170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI ptr = find_match(name, DONT_LOAD, NULL); 308170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI } 309170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 310170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (ptr == NULL && tryload == LOAD_MUST_SUCCEED) 3110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 3120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load match `%s':%s\n", 3130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 3140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 3160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 3170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (tryload != DONT_LOAD) 3180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 3190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 3200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 3210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if(!ptr && (tryload == LOAD_MUST_SUCCEED)) { 3230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 3240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find match `%s'\n", name); 3250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 3270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && matches) { 3290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match **i; 3300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_rule_match *newentry; 3310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry = fw_malloc(sizeof(struct xtables_rule_match)); 3330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = matches; *i; i = &(*i)->next) { 3350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, (*i)->match->name) == 0) 3360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI (*i)->completed = 1; 3370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->match = ptr; 3390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->completed = 0; 3400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI newentry->next = NULL; 3410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = newentry; 3420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 3450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 3460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstruct xtables_target *find_target(const char *name, enum xt_tryload tryload) 3490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 3500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *ptr; 3510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Standard target? */ 3530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, "") == 0 3540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_ACCEPT) == 0 3550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_DROP) == 0 3560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_QUEUE) == 0 3570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI || strcmp(name, XTC_LABEL_RETURN) == 0) 3580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name = "standard"; 3590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (ptr = xtables_targets; ptr; ptr = ptr->next) { 3610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(name, ptr->name) == 0) 3620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI break; 3630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 3650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#ifndef NO_SHARED_LIBS 3660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!ptr && tryload != DONT_LOAD && tryload != DURING_LOAD) { 3670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI char path[strlen(lib_dir) + sizeof("/.so") 3680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI + strlen(afinfo.libprefix) + strlen(name)]; 369170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 370170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI sprintf(path, "%s/libxt_%s.so", lib_dir, name); 371170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (dlopen(path, RTLD_NOW) != NULL) 3720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Found library. If it didn't register itself, 3730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI maybe they specified match as a target. */ 3740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = find_target(name, DONT_LOAD); 375170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI 376170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (ptr == NULL) { 377170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI sprintf(path, "%s/%s%s.so", lib_dir, afinfo.libprefix, 378170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI name); 379170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (dlopen(path, RTLD_NOW) != NULL) 380170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI ptr = find_target(name, DONT_LOAD); 381170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI } 382170af8c566faa9605c1ead558792a031f1d0d48dYasuyuki KOZAKAI if (ptr == NULL && tryload == LOAD_MUST_SUCCEED) 3830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 3840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't load target `%s':%s\n", 3850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI name, dlerror()); 3860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#else 3880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr && !ptr->loaded) { 3890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (tryload != DONT_LOAD) 3900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->loaded = 1; 3910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI else 3920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr = NULL; 3930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if(!ptr && (tryload == LOAD_MUST_SUCCEED)) { 3950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit_error(PARAMETER_PROBLEM, 3960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "Couldn't find target `%s'\n", name); 3970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 3980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI#endif 3990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (ptr) 4010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI ptr->used = 1; 4020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return ptr; 4040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 4050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_revision(const char *name, u_int8_t revision, int opt) 4070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 4080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xt_get_revision rev; 4090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI socklen_t s = sizeof(rev); 4100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI int max_rev, sockfd; 4110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI sockfd = socket(afinfo.family, SOCK_RAW, IPPROTO_RAW); 4130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (sockfd < 0) { 414df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (errno == EPERM) { 415df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy /* revision 0 is always supported. */ 416df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy if (revision != 0) 417df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy fprintf(stderr, "Could not determine whether " 418df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "revision %u is supported, " 419df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy "assuming it is.\n", 420df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy revision); 421df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy return 1; 422df1ef3862761e534c6cec6bd9370285cb5909dd0Patrick McHardy } 4230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "Could not open socket to kernel: %s\n", 4240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 4250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 4260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI load_xtables_ko(modprobe, 1); 4290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strcpy(rev.name, name); 4310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI rev.revision = revision; 4320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI max_rev = getsockopt(sockfd, afinfo.ipproto, opt, &rev, &s); 4340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (max_rev < 0) { 4350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Definitely don't support this? */ 4360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (errno == ENOENT || errno == EPROTONOSUPPORT) { 4370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 4380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 0; 4390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else if (errno == ENOPROTOOPT) { 4400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 4410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Assume only revision 0 support (old kernel) */ 4420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return (revision == 0); 4430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } else { 4440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "getsockopt failed strangely: %s\n", 4450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI strerror(errno)); 4460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 4470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI close(sockfd); 4500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return 1; 4510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 4520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_match_revision(const char *name, u_int8_t revision) 4550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 4560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return compatible_revision(name, revision, afinfo.so_rev_match); 4570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 4580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIstatic int compatible_target_revision(const char *name, u_int8_t revision) 4600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 4610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return compatible_revision(name, revision, afinfo.so_rev_target); 4620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 4630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_match(struct xtables_match *me) 4650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 4660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_match **i, *old; 4670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(me->version, program_version) != 0) { 4690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: match `%s' v%s (I'm v%s).\n", 4700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name, me->version, program_version); 4710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 4720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 4750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 4760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 4770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name); 4780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 4790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 4820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 4830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: match %s has invalid protocol family\n", 4840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name); 4850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 4860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 4870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested match */ 4890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family != afinfo.family) 4900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 4910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 4920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI old = find_match(me->name, DURING_LOAD, NULL); 4930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 4940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old->revision == me->revision) { 4950d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 4960d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: match `%s' already registered.\n", 4970d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name); 4980d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 4990d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5000d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5010d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 5020d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_match_revision(old->name, old->revision) 5030d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 5040d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 5050d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5060d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Replace if compatible. */ 5070d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_match_revision(me->name, me->revision)) 5080d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 5090d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5100d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 5110d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i!=old; i = &(*i)->next); 5120d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 5130d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5140d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5150d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 5160d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: match `%s' has invalid size %u.\n", 5170d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name, (unsigned int)me->size); 5180d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5190d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5200d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Append to list. */ 5220d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_matches; *i; i = &(*i)->next); 5230d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = NULL; 5240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = me; 5250d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5260d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->m = NULL; 5270d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->mflags = 0; 5280d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 5290d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5300d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAIvoid xtables_register_target(struct xtables_target *me) 5310d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI{ 5320d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target *old; 5330d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5340d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strcmp(me->version, program_version) != 0) { 5350d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' v%s (I'm v%s).\n", 5360d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name, me->version, program_version); 5370d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5380d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5390d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5400d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Revision field stole a char from name. */ 5410d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (strlen(me->name) >= XT_FUNCTION_MAXNAMELEN-1) { 5420d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid name\n", 5430d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name); 5440d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5450d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5460d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5470d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family >= NPROTO) { 5480d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 5490d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: BUG: target %s has invalid protocol family\n", 5500d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name); 5510d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5520d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5530d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5540d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* ignore not interested target */ 5550d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->family != afinfo.family) 5560d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 5570d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5580d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI old = find_target(me->name, DURING_LOAD); 5590d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old) { 5600d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI struct xtables_target **i; 5610d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5620d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (old->revision == me->revision) { 5630d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, 5640d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI "%s: target `%s' already registered.\n", 5650d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name); 5660d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5670d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5680d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5690d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Now we have two (or more) options, check compatibility. */ 5700d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (compatible_target_revision(old->name, old->revision) 5710d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI && old->revision > me->revision) 5720d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 5730d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5740d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Replace if compatible. */ 5750d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (!compatible_target_revision(me->name, me->revision)) 5760d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI return; 5770d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5780d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Delete old one. */ 5790d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI for (i = &xtables_targets; *i!=old; i = &(*i)->next); 5800d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI *i = old->next; 5810d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5820d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5830d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI if (me->size != XT_ALIGN(me->size)) { 5840d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI fprintf(stderr, "%s: target `%s' has invalid size %u.\n", 5850d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI program_name, me->name, (unsigned int)me->size); 5860d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI exit(1); 5870d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI } 5880d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI 5890d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI /* Prepend to list. */ 5900d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->next = xtables_targets; 5910d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI xtables_targets = me; 5920d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->t = NULL; 5930d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI me->tflags = 0; 5940d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI} 595