iptables.c revision 228e98dd6303af11925235af4cf3c3ec450f3f41
1e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* Code to take an iptables-style command line and do it. */ 2e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 3e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* 4e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * Author: Paul.Russell@rustcorp.com.au and mneuling@radlogic.com.au 5e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * 6e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * This program is free software; you can redistribute it and/or modify 7e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * it under the terms of the GNU General Public License as published by 8e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * the Free Software Foundation; either version 2 of the License, or 9e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * (at your option) any later version. 10e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * 11e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * This program is distributed in the hope that it will be useful, 12e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * but WITHOUT ANY WARRANTY; without even the implied warranty of 13e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * GNU General Public License for more details. 15e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * 16e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * You should have received a copy of the GNU General Public License 17e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * along with this program; if not, write to the Free Software 18e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher */ 20e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 21e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <getopt.h> 22e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <string.h> 23e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <netdb.h> 24e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <errno.h> 25e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <stdio.h> 26e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <stdlib.h> 27e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <dlfcn.h> 28e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <ctype.h> 29e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <stdarg.h> 30e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <limits.h> 31e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#include <iptables.h> 32e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 33e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#ifndef TRUE 34e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define TRUE 1 35e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#endif 36e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#ifndef FALSE 37e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FALSE 0 38e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#endif 39e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 40e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#ifndef IPT_LIB_DIR 41e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define IPT_LIB_DIR "/usr/local/lib/iptables" 42e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#endif 43e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 44e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_NUMERIC 0x0001 45e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_NOCOUNTS 0x0002 46e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_KILOMEGAGIGA 0x0004 47e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_OPTIONS 0x0008 48e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_NOTABLE 0x0010 49e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_NOTARGET 0x0020 50e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_VIA 0x0040 51e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_NONEWLINE 0x0080 52e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_LINENUMBERS 0x0100 53e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 54e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT_PRINT_RULE (FMT_NOCOUNTS | FMT_OPTIONS | FMT_VIA \ 55e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher | FMT_NUMERIC | FMT_NOTABLE) 56e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define FMT(tab,notab) ((format) & FMT_NOTABLE ? (notab) : (tab)) 57e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 58e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 59e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_NONE 0x0000U 60e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_INSERT 0x0001U 61e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_DELETE 0x0002U 62e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_DELETE_NUM 0x0004U 63e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_REPLACE 0x0008U 64e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_APPEND 0x0010U 65e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_LIST 0x0020U 66e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_FLUSH 0x0040U 67e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_ZERO 0x0080U 68e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_NEW_CHAIN 0x0100U 69e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_DELETE_CHAIN 0x0200U 70e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_SET_POLICY 0x0400U 71e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_CHECK 0x0800U 72e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define CMD_RENAME_CHAIN 0x1000U 73e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define NUMBER_OF_CMD 13 74e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z', 75e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 'N', 'X', 'P', 'C', 'E' }; 76e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 77e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPTION_OFFSET 256 78e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 79e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_NONE 0x00000U 80e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_NUMERIC 0x00001U 81e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_SOURCE 0x00002U 82e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_DESTINATION 0x00004U 83e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_PROTOCOL 0x00008U 84e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_JUMP 0x00010U 85e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_VERBOSE 0x00020U 86e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_EXPANDED 0x00040U 87e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_VIANAMEIN 0x00080U 88e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_VIANAMEOUT 0x00100U 89e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_FRAGMENT 0x00200U 90e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define OPT_LINENUMBERS 0x00400U 91e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher#define NUMBER_OF_OPT 11 92e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic const char optflags[NUMBER_OF_OPT] 93e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', 'f', '3'}; 94e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 95e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct option original_opts[] = { 96e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "append", 1, 0, 'A' }, 97e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "delete", 1, 0, 'D' }, 98e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "insert", 1, 0, 'I' }, 99e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "replace", 1, 0, 'R' }, 100e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "list", 2, 0, 'L' }, 101e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "flush", 2, 0, 'F' }, 102e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "zero", 2, 0, 'Z' }, 103e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "check", 1, 0, 'C' }, 104e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "new-chain", 1, 0, 'N' }, 105e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "delete-chain", 2, 0, 'X' }, 106e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "rename-chain", 2, 0, 'E' }, 107e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "policy", 1, 0, 'P' }, 108e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "source", 1, 0, 's' }, 109e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "destination", 1, 0, 'd' }, 110e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "src", 1, 0, 's' }, /* synonym */ 111e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "dst", 1, 0, 'd' }, /* synonym */ 1122e0a3216c501753709781769f83e29821e62c805Rusty Russell { "protocol", 1, 0, 'p' }, 113e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "in-interface", 1, 0, 'i' }, 114e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "jump", 1, 0, 'j' }, 115e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "table", 1, 0, 't' }, 116e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "match", 1, 0, 'm' }, 117e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "numeric", 0, 0, 'n' }, 118e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "out-interface", 1, 0, 'o' }, 119e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "verbose", 0, 0, 'v' }, 120e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "exact", 0, 0, 'x' }, 121e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "fragments", 0, 0, 'f' }, 122e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "version", 0, 0, 'V' }, 123e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "help", 2, 0, 'h' }, 124e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "line-numbers", 0, 0, '0' }, 125e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { 0 } 126e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 127e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1289e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell#if 0 1299e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russellstatic struct ipt_entry_target * 1309e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russellipt_get_target(struct ipt_entry *e) 1319e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell{ 1329e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell return (void *)e + e->target_offset; 1339e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell} 1349e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell#endif 1359e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell 136e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct option *opts = original_opts; 137e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic unsigned int global_option_offset = 0; 138e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 139e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* Table of legal combinations of commands and options. If any of the 140e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * given commands make an option legal, that option is legal (applies to 141e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * CMD_LIST and CMD_ZERO only). 142e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * Key: 143e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * + compulsory 144e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * x illegal 145e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * optional 146e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher */ 147e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 148e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = 149e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* Well, it's better than "Re: Linux vs FreeBSD" */ 150e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 151e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* -n -s -d -p -j -v -x -i -o -f --line */ 152e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*INSERT*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x'}, 153e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*DELETE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x'}, 154e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x'}, 155e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*REPLACE*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x'}, 156e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*APPEND*/ {'x',' ',' ',' ',' ',' ','x',' ',' ',' ','x'}, 157e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*LIST*/ {' ','x','x','x','x',' ',' ','x','x','x',' '}, 158e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*FLUSH*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, 159e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*ZERO*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, 160e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, 161e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'}, 162e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x','x'}, 163e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*CHECK*/ {'x','+','+','+','x',' ','x','+','+',' ','x'}, 164e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*RENAME*/ {'x','x','x','x','x',' ','x','x','x','x','x'} 165e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 166e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 167e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int inverse_for_options[NUMBER_OF_OPT] = 168e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 169e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -n */ 0, 170e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -s */ IPT_INV_SRCIP, 171e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -d */ IPT_INV_DSTIP, 172e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -p */ IPT_INV_PROTO, 173e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -j */ 0, 174e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -v */ 0, 175e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -x */ 0, 176e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -i */ IPT_INV_VIA_IN, 177e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -o */ IPT_INV_VIA_OUT, 178e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* -f */ IPT_INV_FRAG, 179e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/*--line*/ 0 180e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 181e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 182e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherconst char *program_version; 183e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherconst char *program_name; 184e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1852e0a3216c501753709781769f83e29821e62c805Rusty Russell/* Keeping track of external matches and targets: linked lists. */ 186e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct iptables_match *iptables_matches = NULL; 187e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct iptables_target *iptables_targets = NULL; 188e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 189e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* Extra debugging from libiptc */ 190e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherextern void dump_entries(const iptc_handle_t handle); 191e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 192e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* A few hardcoded protocols for 'all' and in case the user has no 193e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /etc/protocols */ 194e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct pprot { 195e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *name; 196e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher u_int8_t num; 197e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 198e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 199e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic const struct pprot chain_protos[] = { 200e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "tcp", IPPROTO_TCP }, 201e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "udp", IPPROTO_UDP }, 202e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "icmp", IPPROTO_ICMP }, 203e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { "all", 0 }, 204e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher}; 205e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 206e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char * 207e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherproto_to_name(u_int8_t proto) 208e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 209e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 210e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 211e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (proto) { 212e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct protoent *pent = getprotobynumber(proto); 213e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (pent) 214e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return pent->p_name; 215e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 216e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 217e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < sizeof(chain_protos)/sizeof(struct pprot); i++) 218e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (chain_protos[i].num == proto) 219e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return chain_protos[i].name; 220e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 221e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return NULL; 222e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 223e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 224e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct in_addr * 225e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherdotted_to_addr(const char *dotted) 226e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 227e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher static struct in_addr addr; 228e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned char *addrp; 229e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *p, *q; 230e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int onebyte, i; 231e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char buf[20]; 232e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 233e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* copy dotted string, because we need to modify it */ 234e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strncpy(buf, dotted, sizeof(buf) - 1); 235e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp = (unsigned char *) &(addr.s_addr); 236e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 237e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher p = buf; 238e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < 3; i++) { 239e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((q = strchr(p, '.')) == NULL) 240e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 241e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 242e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *q = '\0'; 243e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((onebyte = string_to_number(p, 0, 255)) == -1) 244e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 245e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 246e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp[i] = (unsigned char) onebyte; 247e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher p = q + 1; 248e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 249e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 250e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* we've checked 3 bytes, now we check the last one */ 251e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((onebyte = string_to_number(p, 0, 255)) == -1) 252e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 253e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 254e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp[3] = (unsigned char) onebyte; 255e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 256e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return &addr; 257e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 258e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 259e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct in_addr * 260e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchernetwork_to_addr(const char *name) 261e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 262e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct netent *net; 263e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher static struct in_addr addr; 264e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 265e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((net = getnetbyname(name)) != NULL) { 266e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (net->n_addrtype != AF_INET) 267e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 268e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addr.s_addr = htonl((unsigned long) net->n_net); 269e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return &addr; 270e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 271e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 272e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 273e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 274e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 275e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 276e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherinaddrcpy(struct in_addr *dst, struct in_addr *src) 277e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 278e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* memcpy(dst, src, sizeof(struct in_addr)); */ 279e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher dst->s_addr = src->s_addr; 280e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 281e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 282e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchervoid 283e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherexit_error(enum exittype status, char *msg, ...) 284e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 285e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher va_list args; 286e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 287e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher va_start(args, msg); 288e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "%s v%s: ", program_name, program_version); 289e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher vfprintf(stderr, msg, args); 290e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher va_end(args); 291e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "\n"); 292e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (status == PARAMETER_PROBLEM) 293e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_tryhelp(status); 294e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (status == VERSION_PROBLEM) 295e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, 296e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Perhaps iptables or your kernel needs to be upgraded.\n"); 297e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(status); 298e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 299e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 300e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchervoid 301e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherexit_tryhelp(int status) 302e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 303e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n", 304e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, program_name ); 305e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(status); 306e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 307e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 308e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchervoid 309e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherexit_printhelp(void) 310e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 3112e0a3216c501753709781769f83e29821e62c805Rusty Russell struct iptables_match *m = NULL; 3122e0a3216c501753709781769f83e29821e62c805Rusty Russell struct iptables_target *t = NULL; 3132e0a3216c501753709781769f83e29821e62c805Rusty Russell 314e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("%s v%s\n\n" 315e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher"Usage: %s -[ADC] chain rule-specification [options]\n" 316e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -[RI] chain rulenum rule-specification [options]\n" 317e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -D chain rulenum [options]\n" 318e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -[LFZ] [chain] [options]\n" 319e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -[NX] chain\n" 320e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -E old-chain-name new-chain-name\n" 321e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -P chain target [options]\n" 322e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" %s -h (print this help information)\n\n", 323e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, program_version, program_name, program_name, 324e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, program_name, program_name, program_name, 325e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, program_name); 326e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 327e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf( 328e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher"Commands:\n" 329e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher"Either long or short options are allowed.\n" 330e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --append -A chain Append to chain\n" 331e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --delete -D chain Delete matching rule from chain\n" 332e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --delete -D chain rulenum\n" 333e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" Delete rule rulenum (1 = first) from chain\n" 334e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --insert -I chain [rulenum]\n" 335e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" Insert in chain as rulenum (default 1=first)\n" 336e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --replace -R chain rulenum\n" 337e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" Replace rule rulenum (1 = first) in chain\n" 338e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --list -L [chain] List the rules in a chain or all chains\n" 339e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --flush -F [chain] Delete all rules in chain or all chains\n" 340e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --zero -Z [chain] Zero counters in chain or all chains\n" 341e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --check -C chain Test this packet on chain\n" 342e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --new -N chain Create a new user-defined chain\n" 343e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --delete-chain\n" 344e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" -X [chain] Delete a user-defined chain\n" 345e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --policy -P chain target\n" 346e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" Change policy on chain to target\n" 347e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --rename-chain\n" 348e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" -E old-chain new-chain\n" 349e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" Change chain name, (moving any references)\n" 350e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 351e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher"Options:\n" 352e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --proto -p [!] proto protocol: by number or name, eg. `tcp'\n" 353e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --source -s [!] address[/mask]\n" 354e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" source specification\n" 355e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --destination -d [!] address[/mask]\n" 356e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" destination specification\n" 357e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --in-interface -i [!] input name[+]\n" 358e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" network interface name ([+] for wildcard)\n" 359e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --jump -j target\n" 360e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" target for rule\n" 361e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --numeric -n numeric output of addresses and ports\n" 362e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --out-interface -o [!] output name[+]\n" 363e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" network interface name ([+] for wildcard)\n" 364e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --table -t table table to manipulate (default: `filter')\n" 365e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --verbose -v verbose mode\n" 366e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher" --exact -x expand numbers (display exact values)\n" 367e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher"[!] --fragment -f match second or further fragments only\n" 368e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher"[!] --version -V print package version.\n"); 369e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 3702e0a3216c501753709781769f83e29821e62c805Rusty Russell /* Print out any special helps. A user might like to be able to add a --help 3712e0a3216c501753709781769f83e29821e62c805Rusty Russell to the commandline, and see expected results. So we call help for all 3722e0a3216c501753709781769f83e29821e62c805Rusty Russell matches & targets */ 3732e0a3216c501753709781769f83e29821e62c805Rusty Russell for (t=iptables_targets;t;t=t->next) { 374e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("\n"); 3752e0a3216c501753709781769f83e29821e62c805Rusty Russell t->help(); 376e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 3772e0a3216c501753709781769f83e29821e62c805Rusty Russell for (m=iptables_matches;m;m=m->next) { 378e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("\n"); 3792e0a3216c501753709781769f83e29821e62c805Rusty Russell m->help(); 380e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 381e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(0); 382e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 383e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 384e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 385e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchergeneric_opt_check(int command, int options) 386e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 387e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int i, j, legal = 0; 388e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 389e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Check that commands are valid with options. Complicated by the 390e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * fact that if an option is legal with *any* command given, it is 391e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * legal overall (ie. -z and -l). 392e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher */ 393e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < NUMBER_OF_OPT; i++) { 394e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */ 395e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 396e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (j = 0; j < NUMBER_OF_CMD; j++) { 397e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(command & (1<<j))) 398e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher continue; 399e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 400e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(options & (1<<i))) { 401e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (commands_v_options[j][i] == '+') 402e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 403e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "You need to supply the `-%c' " 404e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "option for this command\n", 405e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optflags[i]); 406e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 407e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (commands_v_options[j][i] != 'x') 408e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher legal = 1; 409e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (legal == 0) 410e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher legal = -1; 411e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 412e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 413e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (legal == -1) 414e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 415e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Illegal option `-%c' with this command\n", 416e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optflags[i]); 417e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 418e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 419e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 420e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char 421e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucheropt2char(int option) 422e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 423e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *ptr; 424e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (ptr = optflags; option > 1; option >>= 1, ptr++); 425e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 426e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return *ptr; 427e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 428e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 429e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char 430e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchercmd2char(int option) 431e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 432e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *ptr; 433e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (ptr = cmdflags; option > 1; option >>= 1, ptr++); 434e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 435e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return *ptr; 436e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 437e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 438e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 439e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucheradd_command(int *cmd, const int newcmd, const int othercmds, int invert) 440e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 441e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 442e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "unexpected ! flag"); 443e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (*cmd & (~othercmds)) 444e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "Can't use -%c with -%c\n", 445e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher cmd2char(newcmd), cmd2char(*cmd & (~othercmds))); 446e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *cmd |= newcmd; 447e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 448e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 449e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherint 450e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchercheck_inverse(const char option[], int *invert) 451e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 452e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (option && strcmp(option, "!") == 0) { 453e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (*invert) 454e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 455e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Multiple `!' flags not allowed"); 456e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 457e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *invert = TRUE; 458e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return TRUE; 459e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 460e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return FALSE; 461e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 462e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 463e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void * 464e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherfw_calloc(size_t count, size_t size) 465e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 466e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher void *p; 467e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 468e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((p = calloc(count, size)) == NULL) { 469e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher perror("iptables: calloc failed"); 470e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(1); 471e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 472e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return p; 473e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 474e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 475e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void * 476e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherfw_malloc(size_t size) 477e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 478e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher void *p; 479e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 480e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((p = malloc(size)) == NULL) { 481e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher perror("iptables: malloc failed"); 482e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(1); 483e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 484e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return p; 485e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 486e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 487e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct in_addr * 488e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherhost_to_addr(const char *name, unsigned int *naddr) 489e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 490e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct hostent *host; 491e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct in_addr *addr; 492e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 493e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 494e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *naddr = 0; 495e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((host = gethostbyname(name)) != NULL) { 496e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (host->h_addrtype != AF_INET || 497e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher host->h_length != sizeof(struct in_addr)) 498e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 499e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 500e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher while (host->h_addr_list[*naddr] != (char *) NULL) 501e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher (*naddr)++; 502e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addr = fw_calloc(*naddr, sizeof(struct in_addr)); 503e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < *naddr; i++) 504e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher inaddrcpy(&(addr[i]), 505e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher (struct in_addr *) host->h_addr_list[i]); 506e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return addr; 507e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 508e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 509e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (struct in_addr *) NULL; 510e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 511e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 512e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char * 513e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucheraddr_to_host(const struct in_addr *addr) 514e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 515e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct hostent *host; 516e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 517e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((host = gethostbyaddr((char *) addr, 518e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sizeof(struct in_addr), AF_INET)) != NULL) 519e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (char *) host->h_name; 520e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 521e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (char *) NULL; 522e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 523e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 524e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* 525e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * All functions starting with "parse" should succeed, otherwise 526e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * the program fails. 527e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * Most routines return pointers to static data that may change 528e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * between calls to the same or other routines with a few exceptions: 529e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * "host_to_addr", "parse_hostnetwork", and "parse_hostnetworkmask" 530e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * return global static data. 531e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher*/ 532e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 533e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct in_addr * 534e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_hostnetwork(const char *name, unsigned int *naddrs) 535e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 536e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct in_addr *addrp, *addrptmp; 537e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 538e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((addrptmp = dotted_to_addr(name)) != NULL || 539e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher (addrptmp = network_to_addr(name)) != NULL) { 540e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp = fw_malloc(sizeof(struct in_addr)); 541e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher inaddrcpy(addrp, addrptmp); 542e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *naddrs = 1; 543e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return addrp; 544e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 545e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((addrp = host_to_addr(name, naddrs)) != NULL) 546e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return addrp; 547e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 548e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "host/network `%s' not found", name); 549e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 550e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 551e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct in_addr * 552e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_mask(char *mask) 553e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 554e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher static struct in_addr maskaddr; 555e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct in_addr *addrp; 556e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int bits; 557e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 558e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (mask == NULL) { 559e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* no mask at all defaults to 32 bits */ 560e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher maskaddr.s_addr = 0xFFFFFFFF; 561e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return &maskaddr; 562e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 563e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((addrp = dotted_to_addr(mask)) != NULL) 564e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* dotted_to_addr already returns a network byte order addr */ 565e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return addrp; 566e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((bits = string_to_number(mask, 0, 32)) == -1) 567e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 568e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "invalid mask `%s' specified", mask); 569e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (bits != 0) { 570e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher maskaddr.s_addr = htonl(0xFFFFFFFF << (32 - bits)); 571e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return &maskaddr; 572e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 573e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 574e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher maskaddr.s_addr = 0L; 575e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return &maskaddr; 576e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 577e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 578e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 579e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_hostnetworkmask(const char *name, struct in_addr **addrpp, 580e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct in_addr *maskp, unsigned int *naddrs) 581e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 582e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct in_addr *addrp; 583e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char buf[256]; 584e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *p; 585e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int i, j, k, n; 586e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 587e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strncpy(buf, name, sizeof(buf) - 1); 588e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((p = strrchr(buf, '/')) != NULL) { 589e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *p = '\0'; 590e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp = parse_mask(p + 1); 591e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else 592e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp = parse_mask(NULL); 593e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher inaddrcpy(maskp, addrp); 594e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 595e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* if a null mask is given, the name is ignored, like in "any/0" */ 596e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (maskp->s_addr == 0L) 597e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcpy(buf, "0.0.0.0"); 598e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 599e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp = *addrpp = parse_hostnetwork(buf, naddrs); 600e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher n = *naddrs; 601e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0, j = 0; i < n; i++) { 602e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher addrp[j++].s_addr &= maskp->s_addr; 603e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (k = 0; k < j - 1; k++) { 604e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (addrp[k].s_addr == addrp[j - 1].s_addr) { 605e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher (*naddrs)--; 606e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher j--; 607e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 608e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 609e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 610e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 611e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 612e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 613e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct iptables_match * 614e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherfind_match(const char *name, int tryload) 615e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 616e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_match *ptr; 617e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 618e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (ptr = iptables_matches; ptr; ptr = ptr->next) { 619e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(name, ptr->name) == 0) 620e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 621e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 622e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 623e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!ptr && tryload) { 624e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so") 625e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher + strlen(name)]; 626e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(path, IPT_LIB_DIR "/libipt_%s.so", name); 6279e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (dlopen(path, RTLD_NOW)) { 6289e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell /* Found library. If it didn't register itself, 6299e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell maybe they specified target as match. */ 6309e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell ptr = find_match(name, 0); 6319e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (!ptr) 6329e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell exit_error(PARAMETER_PROBLEM, 6339e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell "Couldn't load match `%s'\n", 6349e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell name); 6359e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell } 636e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 637e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 638e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ptr; 639e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 640e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 641e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic u_int16_t 642e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_protocol(const char *s) 643e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 644e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int proto = string_to_number(s, 0, 65535); 645e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 646e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (proto == -1) { 647e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct protoent *pent; 648e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 649e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((pent = getprotobyname(s))) 650e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher proto = pent->p_proto; 651e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else { 652e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 653e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; 654e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher i < sizeof(chain_protos)/sizeof(struct pprot); 655e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher i++) { 656e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(s, chain_protos[i].name) == 0) { 657e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher proto = chain_protos[i].num; 658e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 659e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 660e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 661e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (i == sizeof(chain_protos)/sizeof(struct pprot)) 662e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 663e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "unknown protocol `%s' specified", 664e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher s); 665e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 666e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 667e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 668e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (u_int16_t)proto; 669e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 670e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 671e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 672e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_interface(const char *arg, char *vianame, unsigned char *mask) 673e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 674e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int vialen = strlen(arg); 675e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 676e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 677e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(mask, 0, IFNAMSIZ); 678e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(vianame, 0, IFNAMSIZ); 679e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 680e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (vialen + 1 > IFNAMSIZ) 681e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 682e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "interface name `%s' must be shorter than IFNAMSIZ" 683e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher " (%i)", arg, IFNAMSIZ-1); 6847e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell 685e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcpy(vianame, arg); 686e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (vialen == 0) 687e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(mask, 0, IFNAMSIZ); 688e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (vianame[vialen - 1] == '+') { 689e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(mask, 0xFF, vialen - 1); 690e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(mask + vialen - 1, 0, IFNAMSIZ - vialen + 1); 691e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Remove `+' */ 692e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher vianame[vialen - 1] = '\0'; 693e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 694e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Include nul-terminator in match */ 695e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(mask, 0xFF, vialen + 1); 696e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(mask + vialen + 1, 0, IFNAMSIZ - vialen - 1); 697e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 698e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; vianame[i]; i++) { 699e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!isalnum(vianame[i])) { 700e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("Warning: wierd character in interface" 701e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher " `%s' (No aliases, :, ! or *).\n", 702e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher vianame); 703e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 704e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 705e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 706e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 707e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 708e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* Can't be zero. */ 709e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 710e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_rulenumber(const char *rule) 711e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 712e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int rulenum = string_to_number(rule, 1, INT_MAX); 713e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 714e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (rulenum == -1) 715e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 716e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Invalid rule number `%s'", rule); 717e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 718e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return rulenum; 719e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 720e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 721e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic const char * 722e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherparse_target(const char *targetname) 723e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 724e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *ptr; 725e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 726e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strlen(targetname) < 1) 727e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 728e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Invalid target name (too short)"); 729e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 730e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strlen(targetname)+1 > sizeof(ipt_chainlabel)) 731e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 732e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Invalid target name `%s' (%i chars max)", 733e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher targetname, sizeof(ipt_chainlabel)-1); 734e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 735e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (ptr = targetname; *ptr; ptr++) 736e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (isspace(*ptr)) 737e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 738e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Invalid target name `%s'", targetname); 739e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return targetname; 740e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 741e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 742e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char * 743e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucheraddr_to_network(const struct in_addr *addr) 744e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 745e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct netent *net; 746e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 747e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((net = getnetbyaddr((long) ntohl(addr->s_addr), AF_INET)) != NULL) 748e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (char *) net->n_name; 749e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 750e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return (char *) NULL; 751e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 752e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 753e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherchar * 754e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucheraddr_to_dotted(const struct in_addr *addrp) 755e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 756e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher static char buf[20]; 757e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const unsigned char *bytep; 758e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 759e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher bytep = (const unsigned char *) &(addrp->s_addr); 760e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "%d.%d.%d.%d", bytep[0], bytep[1], bytep[2], bytep[3]); 761e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return buf; 762e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 763e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char * 764e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucheraddr_to_anyname(const struct in_addr *addr) 765e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 766e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *name; 767e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 768e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((name = addr_to_host(addr)) != NULL || 769e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher (name = addr_to_network(addr)) != NULL) 770e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return name; 771e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 772e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return addr_to_dotted(addr); 773e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 774e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 775e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic char * 776e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchermask_to_dotted(const struct in_addr *mask) 777e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 778e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int i; 779e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher static char buf[20]; 780e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher u_int32_t maskaddr, bits; 781e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 782e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher maskaddr = ntohl(mask->s_addr); 783e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 784e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (maskaddr == 0xFFFFFFFFL) 785e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* we don't want to see "/32" */ 786e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ""; 787e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 788e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher i = 32; 789e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher bits = 0xFFFFFFFEL; 790e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher while (--i >= 0 && maskaddr != bits) 791e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher bits <<= 1; 792e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (i >= 0) 793e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "/%d", i); 794e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 795e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* mask was not a decent combination of 1's and 0's */ 796e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "/%s", addr_to_dotted(mask)); 797e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 798e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return buf; 799e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 800e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 801e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherint 802e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstring_to_number(const char *s, int min, int max) 803e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 804e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int number; 805e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *end; 806e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 807e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Handle hex, octal, etc. */ 808e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher number = (int)strtol(s, &end, 0); 809e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (*end == '\0' && end != s) { 810e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* we parsed a number, let's see if we want this */ 811e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (min <= number && number <= max) 812e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return number; 813e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 814e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return -1; 815e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 816e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 817e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 818e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherset_option(unsigned int *options, unsigned int option, u_int8_t *invflg, 819e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int invert) 820e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 821e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (*options & option) 822e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed", 823e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opt2char(option)); 824e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *options |= option; 825e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 826e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) { 827e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i; 828e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; 1 << i != option; i++); 829e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 830e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!inverse_for_options[i]) 831e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 832e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "cannot have ! before -%c", 833e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opt2char(option)); 834e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *invflg |= inverse_for_options[i]; 835e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 836e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 837e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 838e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstruct iptables_target * 839e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherfind_target(const char *name, int tryload) 840e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 841e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_target *ptr; 842e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 843e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Standard target? */ 844e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(name, "") == 0 845e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || strcmp(name, IPTC_LABEL_ACCEPT) == 0 846e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || strcmp(name, IPTC_LABEL_DROP) == 0 847e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || strcmp(name, IPTC_LABEL_QUEUE) == 0 848e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || strcmp(name, IPTC_LABEL_RETURN) == 0) 849e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher name = "standard"; 850e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 851e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (ptr = iptables_targets; ptr; ptr = ptr->next) { 852e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(name, ptr->name) == 0) 853e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 854e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 855e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 856e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!ptr && tryload) { 857e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char path[sizeof(IPT_LIB_DIR) + sizeof("/libipt_.so") 858e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher + strlen(name)]; 859e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(path, IPT_LIB_DIR "/libipt_%s.so", name); 8609e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (dlopen(path, RTLD_NOW)) { 8619e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell /* Found library. If it didn't register itself, 8629e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell maybe they specified match as a target. */ 8639e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell ptr = find_target(name, 0); 8649e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (!ptr) 8659e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell exit_error(PARAMETER_PROBLEM, 8669e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell "Couldn't load target `%s'\n", 8679e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell name); 8689e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell } 869e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 870e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 871e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ptr; 872e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 873e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 874e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct option * 875e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchermerge_options(struct option *oldopts, struct option *newopts, 876e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int *option_offset) 877e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 878e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int num_old, num_new, i; 879e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct option *merge; 880e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 881e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (num_old = 0; oldopts[num_old].name; num_old++); 882e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (num_new = 0; newopts[num_new].name; num_new++); 883e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 884e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher global_option_offset += OPTION_OFFSET; 885e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *option_offset = global_option_offset; 886e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 887e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher merge = malloc(sizeof(struct option) * (num_new + num_old + 1)); 888e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memcpy(merge, oldopts, num_old * sizeof(struct option)); 889e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < num_new; i++) { 890e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher merge[num_old + i] = newopts[i]; 891e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher merge[num_old + i].val += *option_offset; 892e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 893e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(merge + num_old + num_new, 0, sizeof(struct option)); 894e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 895e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return merge; 896e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 897e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 898e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchervoid 899e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherregister_match(struct iptables_match *me) 900e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 901e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(me->version, program_version) != 0) { 902e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "%s: match `%s' v%s (I'm v%s).\n", 903e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, me->name, me->version, program_version); 904e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(1); 905e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 906e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 907e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (find_match(me->name, 0)) { 908e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "%s: match `%s' already registered.\n", 909e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, me->name); 910e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(1); 911e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 912e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 913e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Prepend to list. */ 914e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher me->next = iptables_matches; 915e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptables_matches = me; 916e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher me->m = NULL; 917e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher me->mflags = 0; 918e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 919e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opts = merge_options(opts, me->extra_opts, &me->option_offset); 920e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 921e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 922e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchervoid 923e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherregister_target(struct iptables_target *me) 924e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 925e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(me->version, program_version) != 0) { 926e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "%s: target `%s' v%s (I'm v%s).\n", 927e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, me->name, me->version, program_version); 928e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(1); 929e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 930e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 931e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (find_target(me->name, 0)) { 932e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stderr, "%s: target `%s' already registered.\n", 933e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, me->name); 934e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(1); 935e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 936e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 937e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Prepend to list. */ 938e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher me->next = iptables_targets; 939e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptables_targets = me; 940e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher me->t = NULL; 941e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher me->tflags = 0; 942e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 943e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opts = merge_options(opts, me->extra_opts, &me->option_offset); 944e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 945e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 946e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 947e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherprint_header(unsigned int format, const char *chain, iptc_handle_t *handle) 948e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 949e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_counters counters; 950e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *pol = iptc_get_policy(chain, &counters, handle); 951e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("Chain %s", chain); 952e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (pol) { 953e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(" (policy %s", pol); 954e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(format & FMT_NOCOUNTS)) 955e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(" %llu packets, %llu bytes", 956e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher counters.pcnt, counters.bcnt); 957e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(")\n"); 958e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 959e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int refs; 9609e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (!iptc_get_references(&refs, chain, handle)) 9619e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell printf(" (ERROR obtaining refs)\n"); 9629e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell else 9639e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell printf(" (%u references)\n", refs); 964e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 965e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 966e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_LINENUMBERS) 967e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-4s ", "%s "), "num"); 968e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(format & FMT_NOCOUNTS)) { 969e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_KILOMEGAGIGA) { 970e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%5s ","%s "), "pkts"); 971e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%5s ","%s "), "bytes"); 972e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 973e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%8s ","%s "), "pkts"); 974e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%10s ","%s "), "bytes"); 975e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 976e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 977e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(format & FMT_NOTARGET)) 978e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-9s ","%s "), "target"); 979e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputs(" prot ", stdout); 980e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_OPTIONS) 981e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputs("opt", stdout); 982e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_VIA) { 983e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT(" %-6s ","%s "), "in"); 984e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-6s ","%s "), "out"); 985e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 986e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT(" %-19s ","%s "), "source"); 987e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT(" %-19s "," %s "), "destination"); 988e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("\n"); 989e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 990e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 991e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 992e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherprint_num(u_int64_t number, unsigned int format) 993e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 994e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_KILOMEGAGIGA) { 995e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (number > 99999) { 996e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher number = (number + 500) / 1000; 997e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (number > 9999) { 998e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher number = (number + 500) / 1000; 999e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (number > 9999) { 1000e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher number = (number + 500) / 1000; 1001e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%4lluG ","%lluG "),number); 1002e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1003e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else printf(FMT("%4lluM ","%lluM "), number); 1004e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else 1005e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%4lluK ","%lluK "), number); 1006e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else 1007e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%5llu ","%llu "), number); 1008e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else 1009e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%8llu ","%llu "), number); 1010e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1011e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1012e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1013e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherprint_match(const struct ipt_entry_match *m, 1014e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct ipt_ip *ip, 1015e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int numeric) 1016e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1017228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell struct iptables_match *match = find_match(m->u.user.name, 1); 1018e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1019e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (match) { 1020e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (match->print) 1021e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher match->print(ip, m, numeric); 1022e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 1023228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell if (m->u.user.name[0]) 1024228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell printf("UNKNOWN match `%s' ", m->u.user.name); 1025e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1026e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Don't stop iterating. */ 1027e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return 0; 1028e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1029e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1030e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher/* e is called `fw' here for hysterical raisins */ 1031e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 1032e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherprint_firewall(const struct ipt_entry *fw, 1033e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *targname, 1034e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int num, 1035e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int format, 1036e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const iptc_handle_t handle) 1037e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1038e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_target *target = NULL; 1039e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct ipt_entry_target *t; 1040e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher u_int8_t flags; 1041e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char buf[BUFSIZ]; 1042e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1043e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* User creates a chain called "REJECT": this overrides the 1044e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher `REJECT' target module. Keep feeding them rope until the 1045e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher revolution... Bwahahahahah */ 1046e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!iptc_is_chain(targname, handle)) 1047e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target = find_target(targname, 1); 1048e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1049e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target = find_target(IPT_STANDARD_TARGET, 1); 1050e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1051e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher t = ipt_get_target((struct ipt_entry *)fw); 1052e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher flags = fw->ip.flags; 1053e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1054e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_LINENUMBERS) 1055e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-4u ", "%u "), num+1); 1056e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1057e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(format & FMT_NOCOUNTS)) { 1058e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_num(fw->counters.pcnt, format); 1059e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_num(fw->counters.bcnt, format); 1060e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1061e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1062e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(format & FMT_NOTARGET)) 1063e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-9s ", "%s "), targname); 1064e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1065e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc(fw->ip.invflags & IPT_INV_PROTO ? '!' : ' ', stdout); 1066e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher { 1067e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *pname = proto_to_name(fw->ip.proto); 1068e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (pname) 1069e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-5s", "%s "), pname); 1070e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1071e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-5hu", "%hu "), fw->ip.proto); 1072e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1073e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1074e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_OPTIONS) { 1075e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_NOTABLE) 1076e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputs("opt ", stdout); 1077e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc(fw->ip.invflags & IPT_INV_FRAG ? '!' : '-', stdout); 1078e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc(flags & IPT_F_FRAG ? 'f' : '-', stdout); 1079e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc(' ', stdout); 1080e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1081e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1082e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_VIA) { 1083e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char iface[IFNAMSIZ+2]; 1084e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1085e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.invflags & IPT_INV_VIA_IN) { 1086e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iface[0] = '!'; 1087e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iface[1] = '\0'; 1088e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1089e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else iface[0] = '\0'; 1090e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1091e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.iniface[0] != '\0') { 1092e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcat(iface, fw->ip.iniface); 1093e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* If it doesn't compare the nul-term, it's a 1094e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher wildcard. */ 1095e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.iniface_mask[strlen(fw->ip.iniface)] == 0) 1096e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcat(iface, "+"); 1097e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1098e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (format & FMT_NUMERIC) strcat(iface, "*"); 1099e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else strcat(iface, "any"); 1100e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT(" %-6s ","in %s "), iface); 1101e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1102e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.invflags & IPT_INV_VIA_OUT) { 1103e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iface[0] = '!'; 1104e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iface[1] = '\0'; 1105e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1106e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else iface[0] = '\0'; 1107e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1108e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.outiface[0] != '\0') { 1109e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcat(iface, fw->ip.outiface); 1110e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* If it doesn't compare the nul-term, it's a 1111e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher wildcard. */ 1112e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.outiface_mask[strlen(fw->ip.outiface)] == 0) 1113e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcat(iface, "+"); 1114e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1115e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (format & FMT_NUMERIC) strcat(iface, "*"); 1116e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else strcat(iface, "any"); 1117e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-6s ","out %s "), iface); 1118e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1119e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1120e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc(fw->ip.invflags & IPT_INV_SRCIP ? '!' : ' ', stdout); 1121e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.smsk.s_addr == 0L && !(format & FMT_NUMERIC)) 1122e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-19s ","%s "), "anywhere"); 1123e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else { 1124e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_NUMERIC) 1125e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "%s", addr_to_dotted(&(fw->ip.src))); 1126e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1127e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "%s", addr_to_anyname(&(fw->ip.src))); 1128e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcat(buf, mask_to_dotted(&(fw->ip.smsk))); 1129e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-19s ","%s "), buf); 1130e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1131e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1132e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc(fw->ip.invflags & IPT_INV_DSTIP ? '!' : ' ', stdout); 1133e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw->ip.dmsk.s_addr == 0L && !(format & FMT_NUMERIC)) 1134e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-19s","-> %s"), "anywhere"); 1135e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else { 1136e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_NUMERIC) 1137e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "%s", addr_to_dotted(&(fw->ip.dst))); 1138e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1139e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher sprintf(buf, "%s", addr_to_anyname(&(fw->ip.dst))); 1140e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher strcat(buf, mask_to_dotted(&(fw->ip.dmsk))); 1141e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf(FMT("%-19s","-> %s"), buf); 1142e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1143e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1144e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (format & FMT_NOTABLE) 1145e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputs(" ", stdout); 1146e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1147e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher IPT_MATCH_ITERATE(fw, print_match, &fw->ip, format & FMT_NUMERIC); 1148e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1149e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (target) { 1150e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (target->print) 1151e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Print the target information. */ 1152e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target->print(&fw->ip, t, format & FMT_NUMERIC); 1153228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell } else if (t->u.target_size != sizeof(*t)) 1154e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("[%u bytes of unknown target data] ", 1155228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell t->u.target_size - sizeof(*t)); 1156e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1157e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(format & FMT_NONEWLINE)) 1158e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fputc('\n', stdout); 1159e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1160e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1161e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic void 1162e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherprint_firewall_line(const struct ipt_entry *fw, 1163e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const iptc_handle_t h) 1164e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1165e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry_target *t; 1166e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1167e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher t = ipt_get_target((struct ipt_entry *)fw); 1168228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell print_firewall(fw, t->u.user.name, 0, FMT_PRINT_RULE, h); 1169e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1170e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1171e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1172e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherappend_entry(const ipt_chainlabel chain, 1173e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry *fw, 1174e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int nsaddrs, 1175e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr saddrs[], 1176e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int ndaddrs, 1177e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr daddrs[], 1178e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int verbose, 1179e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1180e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1181e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i, j; 1182e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int ret = 1; 1183e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1184e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < nsaddrs; i++) { 1185e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.src.s_addr = saddrs[i].s_addr; 1186e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (j = 0; j < ndaddrs; j++) { 1187e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.dst.s_addr = daddrs[j].s_addr; 1188e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1189e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_firewall_line(fw, *handle); 1190e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret &= iptc_append_entry(chain, fw, handle); 1191e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1192e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1193e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1194e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ret; 1195e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1196e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1197e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1198e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherreplace_entry(const ipt_chainlabel chain, 1199e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry *fw, 1200e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int rulenum, 1201e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr *saddr, 1202e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr *daddr, 1203e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int verbose, 1204e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1205e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1206e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.src.s_addr = saddr->s_addr; 1207e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.dst.s_addr = daddr->s_addr; 1208e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1209e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1210e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_firewall_line(fw, *handle); 1211e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return iptc_replace_entry(chain, fw, rulenum, handle); 1212e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1213e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1214e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1215e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherinsert_entry(const ipt_chainlabel chain, 1216e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry *fw, 1217e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int rulenum, 1218e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int nsaddrs, 1219e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr saddrs[], 1220e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int ndaddrs, 1221e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr daddrs[], 1222e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int verbose, 1223e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1224e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1225e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i, j; 1226e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int ret = 1; 1227e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1228e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < nsaddrs; i++) { 1229e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.src.s_addr = saddrs[i].s_addr; 1230e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (j = 0; j < ndaddrs; j++) { 1231e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.dst.s_addr = daddrs[j].s_addr; 1232e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1233e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_firewall_line(fw, *handle); 1234e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret &= iptc_insert_entry(chain, fw, rulenum, handle); 1235e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1236e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1237e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1238e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ret; 1239e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1240e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 12412e0a3216c501753709781769f83e29821e62c805Rusty Russellstatic unsigned char * 12422e0a3216c501753709781769f83e29821e62c805Rusty Russellmake_delete_mask(struct ipt_entry *fw) 12432e0a3216c501753709781769f83e29821e62c805Rusty Russell{ 12442e0a3216c501753709781769f83e29821e62c805Rusty Russell /* Establish mask for comparison */ 12452e0a3216c501753709781769f83e29821e62c805Rusty Russell unsigned int size; 12462e0a3216c501753709781769f83e29821e62c805Rusty Russell struct iptables_match *m; 12472e0a3216c501753709781769f83e29821e62c805Rusty Russell unsigned char *mask, *mptr; 12482e0a3216c501753709781769f83e29821e62c805Rusty Russell 12492e0a3216c501753709781769f83e29821e62c805Rusty Russell size = sizeof(struct ipt_entry); 12502e0a3216c501753709781769f83e29821e62c805Rusty Russell for (m = iptables_matches; m; m = m->next) 12512e0a3216c501753709781769f83e29821e62c805Rusty Russell size += sizeof(struct ipt_entry_match) + m->size; 12522e0a3216c501753709781769f83e29821e62c805Rusty Russell 12539e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell mask = fw_calloc(1, size 12549e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell + sizeof(struct ipt_entry_target) 12559e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell + iptables_targets->size); 12562e0a3216c501753709781769f83e29821e62c805Rusty Russell 12579e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell memset(mask, 0xFF, sizeof(struct ipt_entry)); 12589e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell mptr = mask + sizeof(struct ipt_entry); 12592e0a3216c501753709781769f83e29821e62c805Rusty Russell 12602e0a3216c501753709781769f83e29821e62c805Rusty Russell for (m = iptables_matches; m; m = m->next) { 12612e0a3216c501753709781769f83e29821e62c805Rusty Russell memset(mptr, 0xFF, 12622e0a3216c501753709781769f83e29821e62c805Rusty Russell sizeof(struct ipt_entry_match) + m->userspacesize); 12632e0a3216c501753709781769f83e29821e62c805Rusty Russell mptr += sizeof(struct ipt_entry_match) + m->size; 12642e0a3216c501753709781769f83e29821e62c805Rusty Russell } 12652e0a3216c501753709781769f83e29821e62c805Rusty Russell 12662e0a3216c501753709781769f83e29821e62c805Rusty Russell memset(mptr, 0xFF, sizeof(struct ipt_entry_target)); 12672e0a3216c501753709781769f83e29821e62c805Rusty Russell mptr += sizeof(struct ipt_entry_target); 12689e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell memset(mptr, 0xFF, iptables_targets->userspacesize); 12692e0a3216c501753709781769f83e29821e62c805Rusty Russell 12702e0a3216c501753709781769f83e29821e62c805Rusty Russell return mask; 12712e0a3216c501753709781769f83e29821e62c805Rusty Russell} 12722e0a3216c501753709781769f83e29821e62c805Rusty Russell 1273e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1274e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherdelete_entry(const ipt_chainlabel chain, 1275e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry *fw, 1276e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int nsaddrs, 1277e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr saddrs[], 1278e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int ndaddrs, 1279e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr daddrs[], 1280e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int verbose, 1281e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1282e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1283e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i, j; 1284e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int ret = 1; 12852e0a3216c501753709781769f83e29821e62c805Rusty Russell unsigned char *mask; 1286e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 12872e0a3216c501753709781769f83e29821e62c805Rusty Russell mask = make_delete_mask(fw); 1288e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < nsaddrs; i++) { 1289e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.src.s_addr = saddrs[i].s_addr; 1290e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (j = 0; j < ndaddrs; j++) { 1291e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.dst.s_addr = daddrs[j].s_addr; 1292e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1293e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_firewall_line(fw, *handle); 12942e0a3216c501753709781769f83e29821e62c805Rusty Russell ret &= iptc_delete_entry(chain, fw, mask, handle); 1295e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1296e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1297e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ret; 1298e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1299e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1300e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1301e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchercheck_packet(const ipt_chainlabel chain, 1302e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry *fw, 1303e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int nsaddrs, 1304e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr saddrs[], 1305e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int ndaddrs, 1306e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const struct in_addr daddrs[], 1307e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int verbose, 1308e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1309e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1310e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int ret = 1; 1311e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int i, j; 1312e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *msg; 1313e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1314e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (i = 0; i < nsaddrs; i++) { 1315e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.src.s_addr = saddrs[i].s_addr; 1316e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (j = 0; j < ndaddrs; j++) { 1317e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw->ip.dst.s_addr = daddrs[j].s_addr; 1318e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1319e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_firewall_line(fw, *handle); 1320e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher msg = iptc_check_packet(chain, fw, handle); 1321e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!msg) ret = 0; 1322e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else printf("%s\n", msg); 1323e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1324e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1325e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1326e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ret; 1327e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1328e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1329e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1330e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherfor_each_chain(int (*fn)(const ipt_chainlabel, int, iptc_handle_t *), 13319e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell int verbose, int builtinstoo, iptc_handle_t *handle) 1332e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1333e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int ret = 1; 13349e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell const char *chain; 13359e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell char *chains; 13369e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell unsigned int i, chaincount = 0; 13379e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell 13389e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell chain = iptc_first_chain(handle); 13399e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell while (chain) { 13409e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell chaincount++; 13419e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell chain = iptc_next_chain(handle); 13429e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell } 1343e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 13449e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell chains = fw_malloc(sizeof(ipt_chainlabel) * chaincount); 13459e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell i = 0; 13469e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell chain = iptc_first_chain(handle); 13479e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell while (chain) { 13489e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell strcpy(chains + i*sizeof(ipt_chainlabel), chain); 13499e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell i++; 13509e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell chain = iptc_next_chain(handle); 1351e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1352e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 13539e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell for (i = 0; i < chaincount; i++) { 13549e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (!builtinstoo 13559e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell && iptc_builtin(chains + i*sizeof(ipt_chainlabel), 13569e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell *handle)) 13579e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell continue; 13589e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell ret &= fn(chains + i*sizeof(ipt_chainlabel), verbose, handle); 13599e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell } 13609e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell 13619e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell free(chains); 1362e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ret; 1363e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1364e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1365e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1366e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherflush_entries(const ipt_chainlabel chain, int verbose, 1367e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1368e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1369e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!chain) 13709e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell return for_each_chain(flush_entries, verbose, 1, handle); 13717e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell 13727e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell if (verbose) 13737e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell fprintf(stdout, "Flushing chain `%s'\n", chain); 13747e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell return iptc_flush_entries(chain, handle); 13757e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell} 1376e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1377e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1378e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherzero_entries(const ipt_chainlabel chain, int verbose, 1379e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1380e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1381e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!chain) 13829e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell return for_each_chain(zero_entries, verbose, 1, handle); 13837e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell 1384e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1385e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stdout, "Zeroing chain `%s'\n", chain); 1386e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return iptc_zero_entries(chain, handle); 1387e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1388e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1389e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1390e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherdelete_chain(const ipt_chainlabel chain, int verbose, 1391e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher iptc_handle_t *handle) 1392e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 13939e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (!chain) 13949e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell return for_each_chain(delete_chain, verbose, 0, handle); 1395e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1396e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose) 1397e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fprintf(stdout, "Deleting chain `%s'\n", chain); 1398e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return iptc_delete_chain(chain, handle); 1399e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1400e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1401e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic int 1402e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherlist_entries(const ipt_chainlabel chain, int verbose, int numeric, 1403e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int expanded, int linenumbers, iptc_handle_t *handle) 1404e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1405e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int found = 0; 14069e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell unsigned int format; 14079e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell const char *this; 1408e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1409e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format = FMT_OPTIONS; 1410e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!verbose) 1411e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format |= FMT_NOCOUNTS; 1412e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1413e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format |= FMT_VIA; 1414e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1415e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (numeric) 1416e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format |= FMT_NUMERIC; 1417e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1418e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!expanded) 1419e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format |= FMT_KILOMEGAGIGA; 1420e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1421e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (linenumbers) 1422e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format |= FMT_LINENUMBERS; 1423e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 14249e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell for (this = iptc_first_chain(handle); 14259e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell this; 14269e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell this = iptc_next_chain(handle)) { 14279e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell const struct ipt_entry *i; 14289e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell unsigned int num; 1429e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1430e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (chain && strcmp(chain, this) != 0) 1431e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher continue; 1432e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1433e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (found) printf("\n"); 1434e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1435e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher print_header(format, this, handle); 14369e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell i = iptc_first_rule(this, handle); 14379e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell 14389e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell num = 0; 14399e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell while (i) { 14409e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell print_firewall(i, 14419e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell iptc_get_target(i, handle), 14429e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell num++, 1443e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher format, 1444e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *handle); 14459e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell i = iptc_next_rule(i, handle); 14469e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell } 1447e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher found = 1; 1448e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1449e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1450e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher errno = ENOENT; 1451e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return found; 1452e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1453e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1454e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherstatic struct ipt_entry * 1455e6869a8f59d779ff4d5a0984c86d80db7078496Marc Bouchergenerate_entry(const struct ipt_entry *fw, 1456e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_match *matches, 1457e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry_target *target) 1458e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1459e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int size; 1460e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_match *m; 1461e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry *e; 1462e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1463e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher size = sizeof(struct ipt_entry); 1464e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (m = matches; m; m = m->next) 1465228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size += m->m->u.match_size; 1466e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1467228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell e = fw_malloc(size + target->u.target_size); 1468e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *e = *fw; 1469e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher e->target_offset = size; 1470228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell e->next_offset = size + target->u.target_size; 1471e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1472e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher size = 0; 1473e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (m = matches; m; m = m->next) { 1474228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell memcpy(e->elems + size, m->m, m->m->u.match_size); 1475228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size += m->m->u.match_size; 1476e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1477228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell memcpy(e->elems + size, target, target->u.target_size); 1478e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1479e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return e; 1480e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 1481e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1482e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucherint do_command(int argc, char *argv[], char **table, iptc_handle_t *handle) 1483e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher{ 1484e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry fw, *e = NULL; 1485e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int invert = 0; 1486e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int nsaddrs = 0, ndaddrs = 0; 1487e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct in_addr *saddrs = NULL, *daddrs = NULL; 1488e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1489e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int c, verbose = 0; 1490e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *chain = NULL; 1491e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL; 1492e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *policy = NULL, *newname = NULL; 1493e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher unsigned int rulenum = 0, options = 0, command = 0; 1494e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher int ret = 1; 1495e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_match *m; 1496e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct iptables_target *target = NULL; 1497e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher const char *jumpto = ""; 1498e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher char *protocol = NULL; 1499e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1500e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher memset(&fw, 0, sizeof(fw)); 1501e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1502e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Suppress error messages: we may add new options if we 1503e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher demand-load a protocol. */ 1504e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opterr = 0; 1505e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1506e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher while ((c = getopt_long(argc, argv, 1507e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "-A:C:D:R:I:L::F::Z::N:X::E:P:Vh::o:p:s:d:j:i:fbvnt:m:x", 1508e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opts, NULL)) != -1) { 1509e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher switch (c) { 1510e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* 1511e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * Command selection 1512e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher */ 1513e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'A': 1514e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_APPEND, CMD_NONE, 1515e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1516e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1517e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1518e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1519e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'D': 1520e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_DELETE, CMD_NONE, 1521e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1522e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1523e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optind < argc && argv[optind][0] != '-' 1524e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') { 1525e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher rulenum = parse_rulenumber(argv[optind++]); 1526e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher command = CMD_DELETE_NUM; 1527e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1528e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1529e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1530e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'C': 1531e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_CHECK, CMD_NONE, 1532e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1533e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1534e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1535e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1536e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'R': 1537e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_REPLACE, CMD_NONE, 1538e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1539e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1540e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optind < argc && argv[optind][0] != '-' 1541e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1542e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher rulenum = parse_rulenumber(argv[optind++]); 1543e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1544e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1545e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "-%c requires a rule number", 1546e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher cmd2char(CMD_REPLACE)); 1547e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1548e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1549e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'I': 1550e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_INSERT, CMD_NONE, 1551e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1552e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1553e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optind < argc && argv[optind][0] != '-' 1554e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1555e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher rulenum = parse_rulenumber(argv[optind++]); 1556e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else rulenum = 1; 1557e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1558e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1559e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'L': 1560e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_LIST, CMD_ZERO, 1561e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1562e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optarg) chain = optarg; 1563e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (optind < argc && argv[optind][0] != '-' 1564e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1565e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = argv[optind++]; 1566e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1567e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1568e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'F': 1569e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_FLUSH, CMD_NONE, 1570e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1571e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optarg) chain = optarg; 1572e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (optind < argc && argv[optind][0] != '-' 1573e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1574e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = argv[optind++]; 1575e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1576e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1577e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'Z': 1578e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_ZERO, CMD_LIST, 1579e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1580e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optarg) chain = optarg; 1581e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (optind < argc && argv[optind][0] != '-' 1582e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1583e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = argv[optind++]; 1584e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1585e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1586e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'N': 1587e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_NEW_CHAIN, CMD_NONE, 1588e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1589e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1590e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1591e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1592e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'X': 1593e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_DELETE_CHAIN, CMD_NONE, 1594e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1595e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optarg) chain = optarg; 1596e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else if (optind < argc && argv[optind][0] != '-' 1597e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1598e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = argv[optind++]; 1599e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1600e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1601e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'E': 1602e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_RENAME_CHAIN, CMD_NONE, 1603e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1604e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1605e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optind < argc && argv[optind][0] != '-' 1606e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1607e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher newname = argv[optind++]; 1608e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1609e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1610e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'P': 1611e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher add_command(&command, CMD_SET_POLICY, CMD_NONE, 1612e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1613e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain = optarg; 1614e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optind < argc && argv[optind][0] != '-' 1615e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && argv[optind][0] != '!') 1616e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher policy = argv[optind++]; 1617e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1618e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1619e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "-%c requires a chain and a policy", 1620e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher cmd2char(CMD_SET_POLICY)); 1621e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1622e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1623e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'h': 1624e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!optarg) 1625e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optarg = argv[optind]; 1626e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 16272e0a3216c501753709781769f83e29821e62c805Rusty Russell /* iptables -p icmp -h */ 16282e0a3216c501753709781769f83e29821e62c805Rusty Russell if (!iptables_matches && protocol) 16292e0a3216c501753709781769f83e29821e62c805Rusty Russell find_match(protocol, 1); 16302e0a3216c501753709781769f83e29821e62c805Rusty Russell 1631e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_printhelp(); 1632e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1633e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* 1634e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher * Option selection 1635e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher */ 1636e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'p': 1637e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (check_inverse(optarg, &invert)) 1638e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optind++; 1639e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_PROTOCOL, &fw.ip.invflags, 1640e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1641e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1642e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Canonicalize into lower case */ 1643e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (protocol = argv[optind-1]; *protocol; protocol++) 1644e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *protocol = tolower(*protocol); 1645e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1646e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher protocol = argv[optind-1]; 1647e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.ip.proto = parse_protocol(protocol); 1648e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1649e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (fw.ip.proto == 0 1650e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && (fw.ip.invflags & IPT_INV_PROTO)) 1651e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1652e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "rule would never match protocol"); 1653e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.nfcache |= NFC_IP_PROTO; 1654e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1655e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1656e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 's': 1657e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (check_inverse(optarg, &invert)) 1658e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optind++; 1659e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_SOURCE, &fw.ip.invflags, 1660e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1661e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher shostnetworkmask = argv[optind-1]; 1662e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.nfcache |= NFC_IP_SRC; 1663e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1664e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1665e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'd': 1666e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (check_inverse(optarg, &invert)) 1667e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optind++; 1668e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_DESTINATION, &fw.ip.invflags, 1669e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1670e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher dhostnetworkmask = argv[optind-1]; 1671e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.nfcache |= NFC_IP_DST; 1672e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1673e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1674e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'j': 1675e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_JUMP, &fw.ip.invflags, 1676e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1677e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher jumpto = parse_target(optarg); 1678e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target = find_target(jumpto, 1); 1679e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1680e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (target) { 1681228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size_t size; 1682228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell 1683228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size = IPT_ALIGN(sizeof(struct ipt_entry_target) 1684228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell + target->size); 1685e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 16862e0a3216c501753709781769f83e29821e62c805Rusty Russell target->t = fw_calloc(1, size); 1687228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell target->t->u.target_size = size; 1688228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell strcpy(target->t->u.user.name, jumpto); 1689e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target->init(target->t, &fw.nfcache); 1690e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1691e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1692e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1693e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1694e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'i': 1695e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (check_inverse(optarg, &invert)) 1696e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optind++; 1697e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_VIANAMEIN, &fw.ip.invflags, 1698e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1699e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher parse_interface(argv[optind-1], 1700e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.ip.iniface, 1701e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.ip.iniface_mask); 1702e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.nfcache |= NFC_IP_IF_IN; 1703e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1704e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1705e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'o': 1706e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (check_inverse(optarg, &invert)) 1707e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optind++; 1708e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_VIANAMEOUT, &fw.ip.invflags, 1709e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1710e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher parse_interface(argv[optind-1], 1711e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.ip.outiface, 1712e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.ip.outiface_mask); 1713e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.nfcache |= NFC_IP_IF_OUT; 1714e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1715e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1716e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'f': 1717e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_FRAGMENT, &fw.ip.invflags, 1718e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1719e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.ip.flags |= IPT_F_FRAG; 1720e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher fw.nfcache |= NFC_IP_FRAG; 1721e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1722e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1723e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'v': 1724e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!verbose) 1725e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_VERBOSE, 1726e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &fw.ip.invflags, invert); 1727e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher verbose++; 1728e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1729e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1730e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'm': 1731e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 1732e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1733e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "unexpected ! flag before --match"); 1734e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1735e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher m = find_match(optarg, 1); 1736e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!m) 1737e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1738e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Couldn't load match `%s'", optarg); 1739e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else { 1740228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size_t size; 1741228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell 1742228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size = IPT_ALIGN(sizeof(struct ipt_entry_match) 1743228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell + m->size); 17442e0a3216c501753709781769f83e29821e62c805Rusty Russell m->m = fw_calloc(1, size); 1745228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell m->m->u.match_size = size; 1746228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell strcpy(m->m->u.user.name, optarg); 1747e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher m->init(m->m, &fw.nfcache); 1748e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1749e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1750e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1751e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'n': 1752e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_NUMERIC, &fw.ip.invflags, 1753e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1754e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1755e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1756e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 't': 1757e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 1758e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1759e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "unexpected ! flag before --table"); 1760e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *table = argv[optind-1]; 1761e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1762e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1763e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'x': 1764e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_EXPANDED, &fw.ip.invflags, 1765e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1766e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1767e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1768e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 'V': 1769e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 1770e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("Not %s ;-)\n", program_version); 1771e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher else 1772e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("%s v%s\n", 1773e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher program_name, program_version); 1774e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit(0); 1775e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1776e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case '0': 1777e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher set_option(&options, OPT_LINENUMBERS, &fw.ip.invflags, 1778e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert); 1779e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1780e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1781e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case 1: /* non option */ 1782e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optarg[0] == '!' && optarg[1] == '\0') { 1783e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 1784e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1785e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "multiple consecutive ! not" 1786e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher " allowed"); 1787e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert = TRUE; 1788e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optarg[0] = '\0'; 1789e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher continue; 1790e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 17919e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell printf("Bad argument `%s'\n", optarg); 1792e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_tryhelp(2); 1793e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1794e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher default: 1795e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* FIXME: This scheme doesn't allow two of the same 1796e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher matches --RR */ 1797e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!target 1798e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || !(target->parse(c - target->option_offset, 1799e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher argv, invert, 1800e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &target->tflags, 1801e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &fw, &target->t))) { 1802e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (m = iptables_matches; m; m = m->next) { 1803e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (m->parse(c - m->option_offset, 1804e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher argv, invert, 1805e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &m->mflags, 1806e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &fw, 1807e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &fw.nfcache, 1808e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &m->m)) 1809e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1810e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1811e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1812e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* If you listen carefully, you can 1813e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher acually hear this code suck. */ 18149e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell if (m == NULL 1815e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && protocol 18169e1d214b30b916df55b4c1c5db224200f02e15a5Rusty Russell && !find_match(protocol, 0) 1817e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && (m = find_match(protocol, 1))) { 1818e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Try loading protocol */ 1819228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size_t size; 1820228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell 1821228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell size = IPT_ALIGN(sizeof(struct ipt_entry_match) 1822228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell + m->size); 1823e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 18242e0a3216c501753709781769f83e29821e62c805Rusty Russell m->m = fw_calloc(1, size); 1825228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell m->m->u.match_size = size; 1826228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell strcpy(m->m->u.user.name, protocol); 1827e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher m->init(m->m, &fw.nfcache); 1828e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1829e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher optind--; 1830e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher continue; 1831e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1832e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!m) 1833e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1834e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Unknown arg `%s'", 1835e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher argv[optind-1]); 1836e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1837e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1838e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher invert = FALSE; 1839e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1840e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1841e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher for (m = iptables_matches; m; m = m->next) 1842e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher m->final_check(m->mflags); 1843e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (target) 1844e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target->final_check(target->tflags); 1845e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1846e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Fix me: must put inverse options checking here --MN */ 1847e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1848e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (optind < argc) 1849e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1850e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "unknown arguments found on commandline"); 1851e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!command) 1852e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "no command specified"); 1853e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (invert) 1854e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1855e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "nothing appropriate following !"); 1856e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1857744bd02e37167ca6b5646cefd8f0f24e71b512c4Marc Boucher if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | 1858744bd02e37167ca6b5646cefd8f0f24e71b512c4Marc Boucher CMD_CHECK)) { 1859e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(options & OPT_DESTINATION)) 1860e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher dhostnetworkmask = "0.0.0.0/0"; 1861e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!(options & OPT_SOURCE)) 1862e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher shostnetworkmask = "0.0.0.0/0"; 1863e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1864e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1865e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (shostnetworkmask) 1866e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher parse_hostnetworkmask(shostnetworkmask, &saddrs, 1867e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &(fw.ip.smsk), &nsaddrs); 1868e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1869e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (dhostnetworkmask) 1870e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher parse_hostnetworkmask(dhostnetworkmask, &daddrs, 1871e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &(fw.ip.dmsk), &ndaddrs); 1872e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1873e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if ((nsaddrs > 1 || ndaddrs > 1) && 1874e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher (fw.ip.invflags & (IPT_INV_SRCIP | IPT_INV_DSTIP))) 1875e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "! not allowed with multiple" 1876e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher " source or destination IP addresses"); 1877e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1878e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (command == CMD_CHECK && fw.ip.invflags != 0) 1879e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "! not allowed with -%c", 1880e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher cmd2char(CMD_CHECK)); 1881e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1882e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (command == CMD_REPLACE && (nsaddrs != 1 || ndaddrs != 1)) 1883e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, "Replacement rule does not " 1884e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "specify a unique address"); 1885e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1886e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher generic_opt_check(command, options); 1887e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1888e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (chain && strlen(chain) > IPT_FUNCTION_MAXNAMELEN) 1889e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1890e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "chain name `%s' too long (must be under %i chars)", 1891e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain, IPT_FUNCTION_MAXNAMELEN); 1892e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1893e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *handle = iptc_init(*table); 1894e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!*handle) 1895e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(VERSION_PROBLEM, 1896e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "can't initialize iptables table `%s': %s", 1897e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher *table, iptc_strerror(errno)); 1898e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1899744bd02e37167ca6b5646cefd8f0f24e71b512c4Marc Boucher if (command == CMD_CHECK 1900744bd02e37167ca6b5646cefd8f0f24e71b512c4Marc Boucher || command == CMD_APPEND 1901e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || command == CMD_DELETE 1902e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || command == CMD_INSERT 1903e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || command == CMD_REPLACE) { 1904e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* -o not valid with incoming packets. */ 1905e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (options & OPT_VIANAMEOUT) 1906e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(chain, "PREROUTING") == 0 1907e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || strcmp(chain, "INPUT") == 0) { 1908e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1909e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Can't use -%c with %s\n", 1910e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opt2char(OPT_VIANAMEOUT), 1911e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain); 1912e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1913e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1914e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* -i not valid with outgoing packets */ 1915e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (options & OPT_VIANAMEIN) 1916e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (strcmp(chain, "POSTROUTING") == 0 1917e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || strcmp(chain, "OUTPUT") == 0) { 1918e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(PARAMETER_PROBLEM, 1919e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Can't use -%c with %s\n", 1920e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher opt2char(OPT_VIANAMEIN), 1921e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher chain); 1922e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1923e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1924e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (target && iptc_is_chain(jumpto, *handle)) { 1925e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher printf("Warning: using chain %s, not extension\n", 1926e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher jumpto); 1927e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1928e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target = NULL; 1929e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1930e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1931e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* If they didn't specify a target, or it's a chain 1932e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher name, use standard. */ 1933e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!target 1934e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher && (strlen(jumpto) == 0 1935e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher || iptc_is_chain(jumpto, *handle))) { 1936e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher size_t size; 1937e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target = find_target(IPT_STANDARD_TARGET, 1); 1938e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1939e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (!target) 1940e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_error(OTHER_PROBLEM, 1941e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher "Can't find standard target\n"); 1942e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1943e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher size = sizeof(struct ipt_entry_target) 1944228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell + target->size; 19452e0a3216c501753709781769f83e29821e62c805Rusty Russell target->t = fw_calloc(1, size); 1946228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell target->t->u.target_size = size; 1947228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell strcpy(target->t->u.user.name, jumpto); 1948e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher target->init(target->t, &fw.nfcache); 1949e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1950e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 19517e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell if (!target) { 1952e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher struct ipt_entry_target unknown_target; 19537e53bf9c2a697abdb6f1385557338423a86612a3Rusty Russell 1954e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* Don't know it. Must be extension with no 1955e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options? */ 1956228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell unknown_target.u.target_size = sizeof(unknown_target); 1957228e98dd6303af11925235af4cf3c3ec450f3f41Rusty Russell strcpy(unknown_target.u.user.name, jumpto); 1958e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1959e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher e = generate_entry(&fw, iptables_matches, 1960e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher &unknown_target); 1961e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } else { 1962e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher e = generate_entry(&fw, iptables_matches, target->t); 1963e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1964e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 1965e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 1966e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher switch (command) { 1967e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_APPEND: 1968e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = append_entry(chain, e, 1969e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher nsaddrs, saddrs, ndaddrs, daddrs, 1970e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, 1971e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher handle); 1972e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1973e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_CHECK: 1974e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = check_packet(chain, e, 1975e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher nsaddrs, saddrs, ndaddrs, daddrs, 1976e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, handle); 1977e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1978e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_DELETE: 1979e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = delete_entry(chain, e, 1980e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher nsaddrs, saddrs, ndaddrs, daddrs, 1981e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, 1982e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher handle); 1983e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1984e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_DELETE_NUM: 1985e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = iptc_delete_num_entry(chain, rulenum - 1, handle); 1986e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1987e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_REPLACE: 1988e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = replace_entry(chain, e, rulenum - 1, 1989e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher saddrs, daddrs, options&OPT_VERBOSE, 1990e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher handle); 1991e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1992e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_INSERT: 1993e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = insert_entry(chain, e, rulenum - 1, 1994e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher nsaddrs, saddrs, ndaddrs, daddrs, 1995e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, 1996e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher handle); 1997e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 1998e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_LIST: 1999e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = list_entries(chain, 2000e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, 2001e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_NUMERIC, 2002e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_EXPANDED, 2003e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_LINENUMBERS, 2004e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher handle); 2005e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2006e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_FLUSH: 2007e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = flush_entries(chain, options&OPT_VERBOSE, handle); 2008e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2009e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_ZERO: 2010e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = zero_entries(chain, options&OPT_VERBOSE, handle); 2011e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2012e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_LIST|CMD_ZERO: 2013e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = list_entries(chain, 2014e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, 2015e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_NUMERIC, 2016e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_EXPANDED, 2017e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_LINENUMBERS, 2018e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher handle); 2019e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (ret) 2020e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = zero_entries(chain, 2021e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher options&OPT_VERBOSE, handle); 2022e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2023e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_NEW_CHAIN: 2024e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = iptc_create_chain(chain, handle); 2025e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2026e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_DELETE_CHAIN: 2027e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = delete_chain(chain, options&OPT_VERBOSE, handle); 2028e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2029e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_RENAME_CHAIN: 2030e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = iptc_rename_chain(chain, newname, handle); 2031e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2032e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher case CMD_SET_POLICY: 2033e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher ret = iptc_set_policy(chain, policy, handle); 2034e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher break; 2035e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher default: 2036e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher /* We should never reach this... */ 2037e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher exit_tryhelp(2); 2038e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher } 2039e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 2040e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher if (verbose > 1) 2041e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher dump_entries(*handle); 2042e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher 2043e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher return ret; 2044e6869a8f59d779ff4d5a0984c86d80db7078496Marc Boucher} 2045