11b91e59339cf782a390329c4f664e3d441eaec6eJonas Berlin/* Code to take an ip6tables-style command line and do it. */
25eed48af2516ebce0412121713d285bc30edb10dRusty Russell
35eed48af2516ebce0412121713d285bc30edb10dRusty Russell/*
45eed48af2516ebce0412121713d285bc30edb10dRusty Russell * Author: Paul.Russell@rustcorp.com.au and mneuling@radlogic.com.au
55eed48af2516ebce0412121713d285bc30edb10dRusty Russell *
610a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte * (C) 2000-2002 by the netfilter coreteam <coreteam@netfilter.org>:
710a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte * 		    Paul 'Rusty' Russell <rusty@rustcorp.com.au>
810a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte * 		    Marc Boucher <marc+nf@mbsi.ca>
910a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte * 		    James Morris <jmorris@intercode.com.au>
1010a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte * 		    Harald Welte <laforge@gnumonks.org>
1110a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte * 		    Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
1210a907f6736864f3f60d36f78c78e655b6bb64eeHarald Welte *
135eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	This program is free software; you can redistribute it and/or modify
145eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	it under the terms of the GNU General Public License as published by
155eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	the Free Software Foundation; either version 2 of the License, or
165eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	(at your option) any later version.
175eed48af2516ebce0412121713d285bc30edb10dRusty Russell *
185eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	This program is distributed in the hope that it will be useful,
195eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	but WITHOUT ANY WARRANTY; without even the implied warranty of
205eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
215eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	GNU General Public License for more details.
225eed48af2516ebce0412121713d285bc30edb10dRusty Russell *
235eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	You should have received a copy of the GNU General Public License
245eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	along with this program; if not, write to the Free Software
255eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
265eed48af2516ebce0412121713d285bc30edb10dRusty Russell */
275eed48af2516ebce0412121713d285bc30edb10dRusty Russell
285eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <getopt.h>
295eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <string.h>
305eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <netdb.h>
315eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <errno.h>
325eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <stdio.h>
335eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <stdlib.h>
345eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <ctype.h>
355eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <stdarg.h>
36c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt#include <stdbool.h>
375eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <limits.h>
385eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <ip6tables.h>
393dfa4488b032fc32aaf2470f48ac1fc3a534794fYasuyuki KOZAKAI#include <xtables.h>
405eed48af2516ebce0412121713d285bc30edb10dRusty Russell#include <arpa/inet.h>
418a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE#include <unistd.h>
428a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE#include <fcntl.h>
438a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE#include <sys/types.h>
448a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE#include <sys/socket.h>
4533690a1aec0b6309ff90066ca56285b6e43013f2Jan Engelhardt#include "ip6tables-multi.h"
46f89c1716a7743ca6e2e6164d3b64c15b2e285e1eJan Engelhardt#include "xshared.h"
475eed48af2516ebce0412121713d285bc30edb10dRusty Russell
485eed48af2516ebce0412121713d285bc30edb10dRusty Russell#ifndef TRUE
495eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define TRUE 1
505eed48af2516ebce0412121713d285bc30edb10dRusty Russell#endif
515eed48af2516ebce0412121713d285bc30edb10dRusty Russell#ifndef FALSE
525eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define FALSE 0
535eed48af2516ebce0412121713d285bc30edb10dRusty Russell#endif
545eed48af2516ebce0412121713d285bc30edb10dRusty Russell
555eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_NONE		0x0000U
565eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_INSERT		0x0001U
575eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_DELETE		0x0002U
585eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_DELETE_NUM		0x0004U
595eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_REPLACE		0x0008U
605eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_APPEND		0x0010U
615eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_LIST		0x0020U
625eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_FLUSH		0x0040U
635eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_ZERO		0x0080U
645eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_NEW_CHAIN		0x0100U
655eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_DELETE_CHAIN	0x0200U
665eed48af2516ebce0412121713d285bc30edb10dRusty Russell#define CMD_SET_POLICY		0x0400U
670eca33f8a830d1aaca53b590abe791109a9524e3Harald Welte#define CMD_RENAME_CHAIN	0x0800U
6896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom#define CMD_LIST_RULES		0x1000U
69b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta#define CMD_ZERO_NUM		0x2000U
70d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek#define CMD_CHECK		0x4000U
71d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek#define NUMBER_OF_CMD	16
725eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic const char cmdflags[] = { 'I', 'D', 'D', 'R', 'A', 'L', 'F', 'Z',
73067a9baf6dc82babe466078ab3c05354c7741271Pablo Neira Ayuso				 'N', 'X', 'P', 'E', 'S', 'Z', 'C' };
745eed48af2516ebce0412121713d285bc30edb10dRusty Russell
75f4b6e5290e869fccb87c03da5603a38b7e55abc5Jan Engelhardt#define NUMBER_OF_OPT	ARRAY_SIZE(optflags)
76f4b6e5290e869fccb87c03da5603a38b7e55abc5Jan Engelhardtstatic const char optflags[]
774a06cf0bd2f5e18eb0149945724b0b4299eec5eaJonas Berlin= { 'n', 's', 'd', 'p', 'j', 'v', 'x', 'i', 'o', '0', 'c'};
785eed48af2516ebce0412121713d285bc30edb10dRusty Russell
795eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic struct option original_opts[] = {
807bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "append",        .has_arg = 1, .val = 'A'},
817bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "delete",        .has_arg = 1, .val = 'D'},
82d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	{.name = "check" ,        .has_arg = 1, .val = 'C'},
837bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "insert",        .has_arg = 1, .val = 'I'},
847bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "replace",       .has_arg = 1, .val = 'R'},
857bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "list",          .has_arg = 2, .val = 'L'},
8696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	{.name = "list-rules",    .has_arg = 2, .val = 'S'},
877bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "flush",         .has_arg = 2, .val = 'F'},
887bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "zero",          .has_arg = 2, .val = 'Z'},
897bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "new-chain",     .has_arg = 1, .val = 'N'},
907bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "delete-chain",  .has_arg = 2, .val = 'X'},
917bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "rename-chain",  .has_arg = 1, .val = 'E'},
927bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "policy",        .has_arg = 1, .val = 'P'},
937bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "source",        .has_arg = 1, .val = 's'},
947bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "destination",   .has_arg = 1, .val = 'd'},
957bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "src",           .has_arg = 1, .val = 's'}, /* synonym */
967bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "dst",           .has_arg = 1, .val = 'd'}, /* synonym */
977bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "protocol",      .has_arg = 1, .val = 'p'},
987bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "in-interface",  .has_arg = 1, .val = 'i'},
997bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "jump",          .has_arg = 1, .val = 'j'},
1007bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "table",         .has_arg = 1, .val = 't'},
1017bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "match",         .has_arg = 1, .val = 'm'},
1027bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "numeric",       .has_arg = 0, .val = 'n'},
1037bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "out-interface", .has_arg = 1, .val = 'o'},
1047bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "verbose",       .has_arg = 0, .val = 'v'},
10593587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester	{.name = "wait",          .has_arg = 0, .val = 'w'},
1067bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "exact",         .has_arg = 0, .val = 'x'},
1077bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "version",       .has_arg = 0, .val = 'V'},
1087bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "help",          .has_arg = 2, .val = 'h'},
1097bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "line-numbers",  .has_arg = 0, .val = '0'},
1107bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "modprobe",      .has_arg = 1, .val = 'M'},
1117bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{.name = "set-counters",  .has_arg = 1, .val = 'c'},
112eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob	{.name = "goto",          .has_arg = 1, .val = 'g'},
11357664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski	{.name = "ipv4",          .has_arg = 0, .val = '4'},
11457664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski	{.name = "ipv6",          .has_arg = 0, .val = '6'},
1157bc3cb7eec4c4db5edc4b503a5dfab799e0bce62Gáspár Lajos	{NULL},
1165eed48af2516ebce0412121713d285bc30edb10dRusty Russell};
1175eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1188b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salimvoid ip6tables_exit_error(enum xtables_exittype status, const char *msg, ...) __attribute__((noreturn, format(printf,2,3)));
1194dcdc9b3f8f42eb3b5a1d12e1b3d2fc1e2675725Jamal Hadi Salimstruct xtables_globals ip6tables_globals = {
1204dcdc9b3f8f42eb3b5a1d12e1b3d2fc1e2675725Jamal Hadi Salim	.option_offset = 0,
1214dcdc9b3f8f42eb3b5a1d12e1b3d2fc1e2675725Jamal Hadi Salim	.program_version = IPTABLES_VERSION,
122139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim	.orig_opts = original_opts,
1238b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salim	.exit_err = ip6tables_exit_error,
1244dcdc9b3f8f42eb3b5a1d12e1b3d2fc1e2675725Jamal Hadi Salim};
1255eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1265eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* Table of legal combinations of commands and options.  If any of the
1275eed48af2516ebce0412121713d285bc30edb10dRusty Russell * given commands make an option legal, that option is legal (applies to
1285eed48af2516ebce0412121713d285bc30edb10dRusty Russell * CMD_LIST and CMD_ZERO only).
1295eed48af2516ebce0412121713d285bc30edb10dRusty Russell * Key:
1305eed48af2516ebce0412121713d285bc30edb10dRusty Russell *  +  compulsory
1315eed48af2516ebce0412121713d285bc30edb10dRusty Russell *  x  illegal
1325eed48af2516ebce0412121713d285bc30edb10dRusty Russell *     optional
1335eed48af2516ebce0412121713d285bc30edb10dRusty Russell */
1345eed48af2516ebce0412121713d285bc30edb10dRusty Russell
135d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardtstatic const char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] =
1365eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* Well, it's better than "Re: Linux vs FreeBSD" */
1375eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
13896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/*     -n  -s  -d  -p  -j  -v  -x  -i  -o --line -c */
1392cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*INSERT*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
1402cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*DELETE*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
1412cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*DELETE_NUM*/{'x','x','x','x','x',' ','x','x','x','x','x'},
1422cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*REPLACE*/   {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
1432cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*APPEND*/    {'x',' ',' ',' ',' ',' ','x',' ',' ','x',' '},
1442cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*LIST*/      {' ','x','x','x','x',' ',' ','x','x',' ','x'},
1452cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*FLUSH*/     {'x','x','x','x','x',' ','x','x','x','x','x'},
1462cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*ZERO*/      {'x','x','x','x','x',' ','x','x','x','x','x'},
147b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta/*ZERO_NUM*/  {'x','x','x','x','x',' ','x','x','x','x','x'},
1482cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*NEW_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
1492cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*DEL_CHAIN*/ {'x','x','x','x','x',' ','x','x','x','x','x'},
15048c1bc6fa2f3aa755e89518054ef3f612d7b2c1fHenrik Nordstrom/*SET_POLICY*/{'x','x','x','x','x',' ','x','x','x','x',' '},
15196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom/*RENAME*/    {'x','x','x','x','x',' ','x','x','x','x','x'},
152d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek/*LIST_RULES*/{'x','x','x','x','x',' ','x','x','x','x','x'},
153d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek/*CHECK*/     {'x',' ',' ',' ',' ',' ','x',' ',' ','x','x'},
1545eed48af2516ebce0412121713d285bc30edb10dRusty Russell};
1555eed48af2516ebce0412121713d285bc30edb10dRusty Russell
156d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardtstatic const unsigned int inverse_for_options[NUMBER_OF_OPT] =
1575eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
1585eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -n */ 0,
1595eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -s */ IP6T_INV_SRCIP,
1605eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -d */ IP6T_INV_DSTIP,
16114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt/* -p */ XT_INV_PROTO,
1625eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -j */ 0,
1635eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -v */ 0,
1645eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -x */ 0,
1655eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -i */ IP6T_INV_VIA_IN,
1665eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* -o */ IP6T_INV_VIA_OUT,
1672cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/*--line*/ 0,
1682cfbd9f565e91356679bdee3f1e9b3133a9d14adPatrick McHardyHarald Welte/* -c */ 0,
1695eed48af2516ebce0412121713d285bc30edb10dRusty Russell};
1705eed48af2516ebce0412121713d285bc30edb10dRusty Russell
171f503cb8ad6360ca646e985f02c2eb0c4bfe8a2c8Pablo Neira Ayuso#define opts ip6tables_globals.opts
1725dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim#define prog_name ip6tables_globals.program_name
1735dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim#define prog_vers ip6tables_globals.program_version
1745eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* A few hardcoded protocols for 'all' and in case the user has no
1755eed48af2516ebce0412121713d285bc30edb10dRusty Russell   /etc/protocols */
1765eed48af2516ebce0412121713d285bc30edb10dRusty Russellstruct pprot {
177d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt	const char *name;
1787ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardt	uint8_t num;
1795eed48af2516ebce0412121713d285bc30edb10dRusty Russell};
1805eed48af2516ebce0412121713d285bc30edb10dRusty Russell
18124bb07802df1608319f40f77c606d45c14d59231Dmitry V. Levinstatic void __attribute__((noreturn))
1825eed48af2516ebce0412121713d285bc30edb10dRusty Russellexit_tryhelp(int status)
1835eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
184a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte	if (line != -1)
185a8658ca43fba82f7761f774f4daeb29b3e335053Harald Welte		fprintf(stderr, "Error occurred at line: %d\n", line);
1865eed48af2516ebce0412121713d285bc30edb10dRusty Russell	fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n",
1875dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim			prog_name, prog_name);
188139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim	xtables_free_opts(1);
1895eed48af2516ebce0412121713d285bc30edb10dRusty Russell	exit(status);
1905eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
1915eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1920b63936140032deac44072951451bdf47b54296aPatrick McHardystatic void
193d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardtexit_printhelp(const struct xtables_rule_match *matches)
1945eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
1955eed48af2516ebce0412121713d285bc30edb10dRusty Russell	printf("%s v%s\n\n"
196d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek"Usage: %s -[ACD] chain rule-specification [options]\n"
1971791a45b279db742d6de35ea8dc1ad9dda4acb73Jan Engelhardt"       %s -I chain [rulenum] rule-specification [options]\n"
1981791a45b279db742d6de35ea8dc1ad9dda4acb73Jan Engelhardt"       %s -R chain rulenum rule-specification [options]\n"
1995eed48af2516ebce0412121713d285bc30edb10dRusty Russell"       %s -D chain rulenum [options]\n"
200bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom"       %s -[LS] [chain [rulenum]] [options]\n"
201bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom"       %s -[FZ] [chain] [options]\n"
2025eed48af2516ebce0412121713d285bc30edb10dRusty Russell"       %s -[NX] chain\n"
2035eed48af2516ebce0412121713d285bc30edb10dRusty Russell"       %s -E old-chain-name new-chain-name\n"
2045eed48af2516ebce0412121713d285bc30edb10dRusty Russell"       %s -P chain target [options]\n"
2055eed48af2516ebce0412121713d285bc30edb10dRusty Russell"       %s -h (print this help information)\n\n",
2065dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim	       prog_name, prog_vers, prog_name, prog_name,
2075dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim	       prog_name, prog_name, prog_name, prog_name,
2081791a45b279db742d6de35ea8dc1ad9dda4acb73Jan Engelhardt	       prog_name, prog_name, prog_name, prog_name);
2095eed48af2516ebce0412121713d285bc30edb10dRusty Russell
2105eed48af2516ebce0412121713d285bc30edb10dRusty Russell	printf(
2115eed48af2516ebce0412121713d285bc30edb10dRusty Russell"Commands:\n"
2125eed48af2516ebce0412121713d285bc30edb10dRusty Russell"Either long or short options are allowed.\n"
2135eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --append  -A chain		Append to chain\n"
214d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek"  --check   -C chain		Check for the existence of a rule\n"
2155eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --delete  -D chain		Delete matching rule from chain\n"
2165eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --delete  -D chain rulenum\n"
2175eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				Delete rule rulenum (1 = first) from chain\n"
2185eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --insert  -I chain [rulenum]\n"
2195eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				Insert in chain as rulenum (default 1=first)\n"
2205eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --replace -R chain rulenum\n"
2215eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				Replace rule rulenum (1 = first) in chain\n"
222bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom"  --list    -L [chain [rulenum]]\n"
223bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom"				List the rules in a chain or all chains\n"
224bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom"  --list-rules -S [chain [rulenum]]\n"
225bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom"				Print the rules in a chain or all chains\n"
2265eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --flush   -F [chain]		Delete all rules in  chain or all chains\n"
227b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta"  --zero    -Z [chain [rulenum]]\n"
228b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta"				Zero counters in chain or all chains\n"
2295eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --new     -N chain		Create a new user-defined chain\n"
2305eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --delete-chain\n"
2315eed48af2516ebce0412121713d285bc30edb10dRusty Russell"            -X [chain]		Delete a user-defined chain\n"
2325eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --policy  -P chain target\n"
2335eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				Change policy on chain to target\n"
2345eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --rename-chain\n"
2355eed48af2516ebce0412121713d285bc30edb10dRusty Russell"            -E old-chain new-chain\n"
2365eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				Change chain name, (moving any references)\n"
2375eed48af2516ebce0412121713d285bc30edb10dRusty Russell
2385eed48af2516ebce0412121713d285bc30edb10dRusty Russell"Options:\n"
23957664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski"    --ipv4	-4		Error (line is ignored by ip6tables-restore)\n"
24057664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski"    --ipv6	-6		Nothing (line is ignored by iptables-restore)\n"
241bf75fc041b35c75c2c592e01f1906771e00ce4ebMart Frauenlob"[!] --protocol	-p proto	protocol: by number or name, eg. `tcp'\n"
242332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow"[!] --source	-s address[/mask][,...]\n"
2435eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				source specification\n"
244332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow"[!] --destination -d address[/mask][,...]\n"
2455eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				destination specification\n"
246967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --in-interface -i input name[+]\n"
2475eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				network interface name ([+] for wildcard)\n"
2485eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --jump	-j target\n"
24943ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte"				target for rule (may load target extension)\n"
250eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#ifdef IP6T_F_GOTO
251eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob"  --goto	-g chain\n"
252eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob"				jump to chain with no return\n"
253eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#endif
25443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte"  --match	-m match\n"
25543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte"				extended match (may load extension)\n"
2565eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --numeric	-n		numeric output of addresses and ports\n"
257967279231a9ecfa99f26694a954afc535c63db1dJan Engelhardt"[!] --out-interface -o output name[+]\n"
2585eed48af2516ebce0412121713d285bc30edb10dRusty Russell"				network interface name ([+] for wildcard)\n"
2595eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --table	-t table	table to manipulate (default: `filter')\n"
2605eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --verbose	-v		verbose mode\n"
26193587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester"  --wait	-w		wait for the xtables lock\n"
26243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte"  --line-numbers		print line numbers when listing\n"
2635eed48af2516ebce0412121713d285bc30edb10dRusty Russell"  --exact	-x		expand numbers (display exact values)\n"
264058eaad25715db2a1915bef283705b7d14868a67András Kis-Szabó/*"[!] --fragment	-f		match second or further fragments only\n"*/
26543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte"  --modprobe=<command>		try to insert modules using this command\n"
26643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte"  --set-counters PKTS BYTES	set the counter during insert/append\n"
2675eed48af2516ebce0412121713d285bc30edb10dRusty Russell"[!] --version	-V		print package version.\n");
2685eed48af2516ebce0412121713d285bc30edb10dRusty Russell
269f89c1716a7743ca6e2e6164d3b64c15b2e285e1eJan Engelhardt	print_extension_helps(xtables_targets, matches);
2705eed48af2516ebce0412121713d285bc30edb10dRusty Russell	exit(0);
2715eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
2725eed48af2516ebce0412121713d285bc30edb10dRusty Russell
2730b63936140032deac44072951451bdf47b54296aPatrick McHardyvoid
2748b7baebc93989106fd5d26b262d0ce191f8ef7c0Jamal Hadi Salimip6tables_exit_error(enum xtables_exittype status, const char *msg, ...)
2750b63936140032deac44072951451bdf47b54296aPatrick McHardy{
2760b63936140032deac44072951451bdf47b54296aPatrick McHardy	va_list args;
2770b63936140032deac44072951451bdf47b54296aPatrick McHardy
2780b63936140032deac44072951451bdf47b54296aPatrick McHardy	va_start(args, msg);
2795dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim	fprintf(stderr, "%s v%s: ", prog_name, prog_vers);
2800b63936140032deac44072951451bdf47b54296aPatrick McHardy	vfprintf(stderr, msg, args);
2810b63936140032deac44072951451bdf47b54296aPatrick McHardy	va_end(args);
2820b63936140032deac44072951451bdf47b54296aPatrick McHardy	fprintf(stderr, "\n");
2830b63936140032deac44072951451bdf47b54296aPatrick McHardy	if (status == PARAMETER_PROBLEM)
2840b63936140032deac44072951451bdf47b54296aPatrick McHardy		exit_tryhelp(status);
2850b63936140032deac44072951451bdf47b54296aPatrick McHardy	if (status == VERSION_PROBLEM)
2860b63936140032deac44072951451bdf47b54296aPatrick McHardy		fprintf(stderr,
2870b63936140032deac44072951451bdf47b54296aPatrick McHardy			"Perhaps ip6tables or your kernel needs to be upgraded.\n");
2880b63936140032deac44072951451bdf47b54296aPatrick McHardy	/* On error paths, make sure that we don't leak memory */
289139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim	xtables_free_opts(1);
2900b63936140032deac44072951451bdf47b54296aPatrick McHardy	exit(status);
2910b63936140032deac44072951451bdf47b54296aPatrick McHardy}
2920b63936140032deac44072951451bdf47b54296aPatrick McHardy
2935eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic void
2945eed48af2516ebce0412121713d285bc30edb10dRusty Russellgeneric_opt_check(int command, int options)
2955eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
2965eed48af2516ebce0412121713d285bc30edb10dRusty Russell	int i, j, legal = 0;
2975eed48af2516ebce0412121713d285bc30edb10dRusty Russell
2985eed48af2516ebce0412121713d285bc30edb10dRusty Russell	/* Check that commands are valid with options.  Complicated by the
2995eed48af2516ebce0412121713d285bc30edb10dRusty Russell	 * fact that if an option is legal with *any* command given, it is
3005eed48af2516ebce0412121713d285bc30edb10dRusty Russell	 * legal overall (ie. -z and -l).
3015eed48af2516ebce0412121713d285bc30edb10dRusty Russell	 */
3025eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (i = 0; i < NUMBER_OF_OPT; i++) {
3035eed48af2516ebce0412121713d285bc30edb10dRusty Russell		legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */
3045eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3055eed48af2516ebce0412121713d285bc30edb10dRusty Russell		for (j = 0; j < NUMBER_OF_CMD; j++) {
3065eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (!(command & (1<<j)))
3075eed48af2516ebce0412121713d285bc30edb10dRusty Russell				continue;
3085eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3095eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (!(options & (1<<i))) {
3105eed48af2516ebce0412121713d285bc30edb10dRusty Russell				if (commands_v_options[j][i] == '+')
3111829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt					xtables_error(PARAMETER_PROBLEM,
3125eed48af2516ebce0412121713d285bc30edb10dRusty Russell						   "You need to supply the `-%c' "
3135eed48af2516ebce0412121713d285bc30edb10dRusty Russell						   "option for this command\n",
3145eed48af2516ebce0412121713d285bc30edb10dRusty Russell						   optflags[i]);
3155eed48af2516ebce0412121713d285bc30edb10dRusty Russell			} else {
3165eed48af2516ebce0412121713d285bc30edb10dRusty Russell				if (commands_v_options[j][i] != 'x')
3175eed48af2516ebce0412121713d285bc30edb10dRusty Russell					legal = 1;
3185eed48af2516ebce0412121713d285bc30edb10dRusty Russell				else if (legal == 0)
3195eed48af2516ebce0412121713d285bc30edb10dRusty Russell					legal = -1;
3205eed48af2516ebce0412121713d285bc30edb10dRusty Russell			}
3215eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
3225eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (legal == -1)
3231829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
3245eed48af2516ebce0412121713d285bc30edb10dRusty Russell				   "Illegal option `-%c' with this command\n",
3255eed48af2516ebce0412121713d285bc30edb10dRusty Russell				   optflags[i]);
3265eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
3275eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
3285eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3295eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic char
3305eed48af2516ebce0412121713d285bc30edb10dRusty Russellopt2char(int option)
3315eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
3325eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *ptr;
3335eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (ptr = optflags; option > 1; option >>= 1, ptr++);
3345eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3355eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return *ptr;
3365eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
3375eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3385eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic char
3395eed48af2516ebce0412121713d285bc30edb10dRusty Russellcmd2char(int option)
3405eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
3415eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *ptr;
3425eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (ptr = cmdflags; option > 1; option >>= 1, ptr++);
3435eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3445eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return *ptr;
3455eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
3465eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3475eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic void
348efa8fc2123a2a9fc229ab471edd2b2688ce1da3aHarald Welteadd_command(unsigned int *cmd, const int newcmd, const int othercmds,
349efa8fc2123a2a9fc229ab471edd2b2688ce1da3aHarald Welte	    int invert)
3505eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
3515eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (invert)
3521829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "unexpected '!' flag");
3535eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (*cmd & (~othercmds))
3541829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "Cannot use -%c with -%c\n",
3555eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   cmd2char(newcmd), cmd2char(*cmd & (~othercmds)));
3565eed48af2516ebce0412121713d285bc30edb10dRusty Russell	*cmd |= newcmd;
3575eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
3585eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3595eed48af2516ebce0412121713d285bc30edb10dRusty Russell/*
3605eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	All functions starting with "parse" should succeed, otherwise
3615eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	the program fails.
3625eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	Most routines return pointers to static data that may change
3635eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	between calls to the same or other routines with a few exceptions:
3645eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	"host_to_addr", "parse_hostnetwork", and "parse_hostnetworkmask"
3655eed48af2516ebce0412121713d285bc30edb10dRusty Russell *	return global static data.
3665eed48af2516ebce0412121713d285bc30edb10dRusty Russell*/
3675eed48af2516ebce0412121713d285bc30edb10dRusty Russell
368f69e30c0107ceff61296045cfd36ea0506d54186Yasuyuki KOZAKAI/* These are invalid numbers as upper layer protocol */
3697ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtstatic int is_exthdr(uint16_t proto)
37078716a9a8c039b18e2f8e476b2a4c76ec17437b2Yasuyuki KOZAKAI{
371f69e30c0107ceff61296045cfd36ea0506d54186Yasuyuki KOZAKAI	return (proto == IPPROTO_ROUTING ||
37278716a9a8c039b18e2f8e476b2a4c76ec17437b2Yasuyuki KOZAKAI		proto == IPPROTO_FRAGMENT ||
37378716a9a8c039b18e2f8e476b2a4c76ec17437b2Yasuyuki KOZAKAI		proto == IPPROTO_AH ||
37478716a9a8c039b18e2f8e476b2a4c76ec17437b2Yasuyuki KOZAKAI		proto == IPPROTO_DSTOPTS);
37578716a9a8c039b18e2f8e476b2a4c76ec17437b2Yasuyuki KOZAKAI}
37678716a9a8c039b18e2f8e476b2a4c76ec17437b2Yasuyuki KOZAKAI
3775eed48af2516ebce0412121713d285bc30edb10dRusty Russell/* Can't be zero. */
3785eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
3795eed48af2516ebce0412121713d285bc30edb10dRusty Russellparse_rulenumber(const char *rule)
3805eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
38143ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte	unsigned int rulenum;
3825eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3835f2922cfc0bbfbeb878f5c12e9fb3eb602ae5507Jan Engelhardt	if (!xtables_strtoui(rule, NULL, &rulenum, 1, INT_MAX))
3841829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
3855eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   "Invalid rule number `%s'", rule);
3865eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3875eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return rulenum;
3885eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
3895eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3905eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic const char *
3915eed48af2516ebce0412121713d285bc30edb10dRusty Russellparse_target(const char *targetname)
3925eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
3935eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *ptr;
3945eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3955eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (strlen(targetname) < 1)
3961829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
3975eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   "Invalid target name (too short)");
3985eed48af2516ebce0412121713d285bc30edb10dRusty Russell
3990cb675b8f18c4b074d4c69461638820708e98100Jan Engelhardt	if (strlen(targetname) >= XT_EXTENSION_MAXNAMELEN)
4001829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
401a28d495285ad7dd9f286d63958cf20d74eec6bcbMartin Josefsson			   "Invalid target name `%s' (%u chars max)",
4020cb675b8f18c4b074d4c69461638820708e98100Jan Engelhardt			   targetname, XT_EXTENSION_MAXNAMELEN - 1);
4035eed48af2516ebce0412121713d285bc30edb10dRusty Russell
4045eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (ptr = targetname; *ptr; ptr++)
4055eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (isspace(*ptr))
4061829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
4075eed48af2516ebce0412121713d285bc30edb10dRusty Russell				   "Invalid target name `%s'", targetname);
4085eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return targetname;
4095eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
4105eed48af2516ebce0412121713d285bc30edb10dRusty Russell
4115eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic void
4127ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtset_option(unsigned int *options, unsigned int option, uint8_t *invflg,
4135eed48af2516ebce0412121713d285bc30edb10dRusty Russell	   int invert)
4145eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
4155eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (*options & option)
4161829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "multiple -%c flags not allowed",
4175eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   opt2char(option));
4185eed48af2516ebce0412121713d285bc30edb10dRusty Russell	*options |= option;
4195eed48af2516ebce0412121713d285bc30edb10dRusty Russell
4205eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (invert) {
4215eed48af2516ebce0412121713d285bc30edb10dRusty Russell		unsigned int i;
4225eed48af2516ebce0412121713d285bc30edb10dRusty Russell		for (i = 0; 1 << i != option; i++);
4235eed48af2516ebce0412121713d285bc30edb10dRusty Russell
4245eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (!inverse_for_options[i])
4251829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt			xtables_error(PARAMETER_PROBLEM,
4265eed48af2516ebce0412121713d285bc30edb10dRusty Russell				   "cannot have ! before -%c",
4275eed48af2516ebce0412121713d285bc30edb10dRusty Russell				   opt2char(option));
4285eed48af2516ebce0412121713d285bc30edb10dRusty Russell		*invflg |= inverse_for_options[i];
4295eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
4305eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
4315eed48af2516ebce0412121713d285bc30edb10dRusty Russell
43243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
4335eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic void
4341639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardtprint_header(unsigned int format, const char *chain, struct xtc_handle *handle)
4355eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
43614da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	struct xt_counters counters;
4375eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *pol = ip6tc_get_policy(chain, &counters, handle);
4385eed48af2516ebce0412121713d285bc30edb10dRusty Russell	printf("Chain %s", chain);
4395eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (pol) {
4405eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(" (policy %s", pol);
4418a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE		if (!(format & FMT_NOCOUNTS)) {
44243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			fputc(' ', stdout);
4432f655ede64e07a861e3ec50150f572ed98755013Pablo Neira Ayuso			xtables_print_num(counters.pcnt, (format|FMT_NOTABLE));
44443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			fputs("packets, ", stdout);
4452f655ede64e07a861e3ec50150f572ed98755013Pablo Neira Ayuso			xtables_print_num(counters.bcnt, (format|FMT_NOTABLE));
44643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			fputs("bytes", stdout);
4478a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE		}
4485eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(")\n");
4495eed48af2516ebce0412121713d285bc30edb10dRusty Russell	} else {
4505eed48af2516ebce0412121713d285bc30edb10dRusty Russell		unsigned int refs;
4515eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (!ip6tc_get_references(&refs, chain, handle))
4525eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(" (ERROR obtaining refs)\n");
4535eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else
4545eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(" (%u references)\n", refs);
4555eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
4565eed48af2516ebce0412121713d285bc30edb10dRusty Russell
4575eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_LINENUMBERS)
4585eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-4s ", "%s "), "num");
4595eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!(format & FMT_NOCOUNTS)) {
4605eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (format & FMT_KILOMEGAGIGA) {
4615eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(FMT("%5s ","%s "), "pkts");
4625eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(FMT("%5s ","%s "), "bytes");
4635eed48af2516ebce0412121713d285bc30edb10dRusty Russell		} else {
4645eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(FMT("%8s ","%s "), "pkts");
4655eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(FMT("%10s ","%s "), "bytes");
4665eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
4675eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
4685eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!(format & FMT_NOTARGET))
4695eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-9s ","%s "), "target");
4705eed48af2516ebce0412121713d285bc30edb10dRusty Russell	fputs(" prot ", stdout);
4715eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_OPTIONS)
4725eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fputs("opt", stdout);
4735eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_VIA) {
4745eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT(" %-6s ","%s "), "in");
4755eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-6s ","%s "), "out");
4765eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
4775eed48af2516ebce0412121713d285bc30edb10dRusty Russell	printf(FMT(" %-19s ","%s "), "source");
4785eed48af2516ebce0412121713d285bc30edb10dRusty Russell	printf(FMT(" %-19s "," %s "), "destination");
4795eed48af2516ebce0412121713d285bc30edb10dRusty Russell	printf("\n");
4805eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
4815eed48af2516ebce0412121713d285bc30edb10dRusty Russell
48243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
4835eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
48414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardtprint_match(const struct xt_entry_match *m,
4855eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    const struct ip6t_ip6 *ip,
4865eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    int numeric)
4875eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
488d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt	const struct xtables_match *match =
4892338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt		xtables_find_match(m->u.user.name, XTF_TRY_LOAD, NULL);
4905eed48af2516ebce0412121713d285bc30edb10dRusty Russell
4915eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (match) {
4925eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (match->print)
4935eed48af2516ebce0412121713d285bc30edb10dRusty Russell			match->print(ip, m, numeric);
49443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		else
49543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			printf("%s ", match->name);
4965eed48af2516ebce0412121713d285bc30edb10dRusty Russell	} else {
4975eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (m->u.user.name[0])
4985eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf("UNKNOWN match `%s' ", m->u.user.name);
4995eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
5005eed48af2516ebce0412121713d285bc30edb10dRusty Russell	/* Don't stop iterating. */
5015eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return 0;
5025eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
5035eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5046cf172ed4064df729ca83eb71133741dfbd6c6e7Jan Engelhardt/* e is called `fw' here for historical reasons */
5055eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic void
5065eed48af2516ebce0412121713d285bc30edb10dRusty Russellprint_firewall(const struct ip6t_entry *fw,
5075eed48af2516ebce0412121713d285bc30edb10dRusty Russell	       const char *targname,
5085eed48af2516ebce0412121713d285bc30edb10dRusty Russell	       unsigned int num,
5095eed48af2516ebce0412121713d285bc30edb10dRusty Russell	       unsigned int format,
5101639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	       struct xtc_handle *const handle)
5115eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
512d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt	const struct xtables_target *target = NULL;
51314da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	const struct xt_entry_target *t;
5145eed48af2516ebce0412121713d285bc30edb10dRusty Russell	char buf[BUFSIZ];
5155eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5165eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!ip6tc_is_chain(targname, handle))
5172338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt		target = xtables_find_target(targname, XTF_TRY_LOAD);
5185eed48af2516ebce0412121713d285bc30edb10dRusty Russell	else
51914da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt		target = xtables_find_target(XT_STANDARD_TARGET,
5202338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt		         XTF_LOAD_MUST_SUCCEED);
5215eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5225eed48af2516ebce0412121713d285bc30edb10dRusty Russell	t = ip6t_get_target((struct ip6t_entry *)fw);
5235eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5245eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_LINENUMBERS)
5251564189568fb63292c7f586563d4fda430a40de3Henrik Nordstrom		printf(FMT("%-4u ", "%u "), num);
5265eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5275eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!(format & FMT_NOCOUNTS)) {
5282f655ede64e07a861e3ec50150f572ed98755013Pablo Neira Ayuso		xtables_print_num(fw->counters.pcnt, format);
5292f655ede64e07a861e3ec50150f572ed98755013Pablo Neira Ayuso		xtables_print_num(fw->counters.bcnt, format);
5305eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
5315eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5325eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!(format & FMT_NOTARGET))
5335eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-9s ", "%s "), targname);
5345eed48af2516ebce0412121713d285bc30edb10dRusty Russell
53514da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	fputc(fw->ipv6.invflags & XT_INV_PROTO ? '!' : ' ', stdout);
5365eed48af2516ebce0412121713d285bc30edb10dRusty Russell	{
5371de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt		const char *pname = proto_to_name(fw->ipv6.proto, format&FMT_NUMERIC);
5385eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (pname)
5395eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(FMT("%-5s", "%s "), pname);
5405eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else
5415eed48af2516ebce0412121713d285bc30edb10dRusty Russell			printf(FMT("%-5hu", "%hu "), fw->ipv6.proto);
5425eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
5435eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5445eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_OPTIONS) {
5455eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (format & FMT_NOTABLE)
5465eed48af2516ebce0412121713d285bc30edb10dRusty Russell			fputs("opt ", stdout);
54743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		fputc(' ', stdout); /* Invert flag of FRAG */
54843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		fputc(' ', stdout); /* -f */
5495eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fputc(' ', stdout);
5505eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
5515eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5525eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_VIA) {
5535eed48af2516ebce0412121713d285bc30edb10dRusty Russell		char iface[IFNAMSIZ+2];
5545eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5555eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (fw->ipv6.invflags & IP6T_INV_VIA_IN) {
5565eed48af2516ebce0412121713d285bc30edb10dRusty Russell			iface[0] = '!';
5575eed48af2516ebce0412121713d285bc30edb10dRusty Russell			iface[1] = '\0';
5585eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
5595eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else iface[0] = '\0';
5605eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5615eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (fw->ipv6.iniface[0] != '\0') {
5625eed48af2516ebce0412121713d285bc30edb10dRusty Russell			strcat(iface, fw->ipv6.iniface);
5635eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
5645eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else if (format & FMT_NUMERIC) strcat(iface, "*");
5655eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else strcat(iface, "any");
5665eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT(" %-6s ","in %s "), iface);
5675eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5685eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (fw->ipv6.invflags & IP6T_INV_VIA_OUT) {
5695eed48af2516ebce0412121713d285bc30edb10dRusty Russell			iface[0] = '!';
5705eed48af2516ebce0412121713d285bc30edb10dRusty Russell			iface[1] = '\0';
5715eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
5725eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else iface[0] = '\0';
5735eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5745eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (fw->ipv6.outiface[0] != '\0') {
5755eed48af2516ebce0412121713d285bc30edb10dRusty Russell			strcat(iface, fw->ipv6.outiface);
5765eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
5775eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else if (format & FMT_NUMERIC) strcat(iface, "*");
5785eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else strcat(iface, "any");
5795eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-6s ","out %s "), iface);
5805eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
5815eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5825eed48af2516ebce0412121713d285bc30edb10dRusty Russell	fputc(fw->ipv6.invflags & IP6T_INV_SRCIP ? '!' : ' ', stdout);
5835b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	if (!memcmp(&fw->ipv6.smsk, &in6addr_any, sizeof in6addr_any)
5845eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    && !(format & FMT_NUMERIC))
5855eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-19s ","%s "), "anywhere");
5865eed48af2516ebce0412121713d285bc30edb10dRusty Russell	else {
5875eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (format & FMT_NUMERIC)
588e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt			strcpy(buf, xtables_ip6addr_to_numeric(&fw->ipv6.src));
5895eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else
590e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt			strcpy(buf, xtables_ip6addr_to_anyname(&fw->ipv6.src));
591e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt		strcat(buf, xtables_ip6mask_to_numeric(&fw->ipv6.smsk));
5925eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf(FMT("%-19s ","%s "), buf);
5935eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
5945eed48af2516ebce0412121713d285bc30edb10dRusty Russell
5955eed48af2516ebce0412121713d285bc30edb10dRusty Russell	fputc(fw->ipv6.invflags & IP6T_INV_DSTIP ? '!' : ' ', stdout);
5965eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!memcmp(&fw->ipv6.dmsk, &in6addr_any, sizeof in6addr_any)
5975eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    && !(format & FMT_NUMERIC))
59869ceee5ebe1a57b274cbadbe918d9763c5bd85b3Jamie Strandboge		printf(FMT("%-19s ","-> %s"), "anywhere");
5995eed48af2516ebce0412121713d285bc30edb10dRusty Russell	else {
6005eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (format & FMT_NUMERIC)
601e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt			strcpy(buf, xtables_ip6addr_to_numeric(&fw->ipv6.dst));
6025eed48af2516ebce0412121713d285bc30edb10dRusty Russell		else
603e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt			strcpy(buf, xtables_ip6addr_to_anyname(&fw->ipv6.dst));
604e44ea7faa17c10c68f14f5338a7cc6e3291a0ce7Jan Engelhardt		strcat(buf, xtables_ip6mask_to_numeric(&fw->ipv6.dmsk));
60569ceee5ebe1a57b274cbadbe918d9763c5bd85b3Jamie Strandboge		printf(FMT("%-19s ","-> %s"), buf);
6065eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
6075eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6085eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (format & FMT_NOTABLE)
6095eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fputs("  ", stdout);
6105eed48af2516ebce0412121713d285bc30edb10dRusty Russell
611eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#ifdef IP6T_F_GOTO
612eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob	if(fw->ipv6.flags & IP6T_F_GOTO)
613eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob		printf("[goto] ");
614eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#endif
615eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob
6165eed48af2516ebce0412121713d285bc30edb10dRusty Russell	IP6T_MATCH_ITERATE(fw, print_match, &fw->ipv6, format & FMT_NUMERIC);
6175eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6185eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (target) {
6195eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (target->print)
6205eed48af2516ebce0412121713d285bc30edb10dRusty Russell			/* Print the target information. */
6215eed48af2516ebce0412121713d285bc30edb10dRusty Russell			target->print(&fw->ipv6, t, format & FMT_NUMERIC);
6225eed48af2516ebce0412121713d285bc30edb10dRusty Russell	} else if (t->u.target_size != sizeof(*t))
6235eed48af2516ebce0412121713d285bc30edb10dRusty Russell		printf("[%u bytes of unknown target data] ",
624a28d495285ad7dd9f286d63958cf20d74eec6bcbMartin Josefsson		       (unsigned int)(t->u.target_size - sizeof(*t)));
6255eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6265eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!(format & FMT_NONEWLINE))
6275eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fputc('\n', stdout);
6285eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
6295eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6305eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic void
6315eed48af2516ebce0412121713d285bc30edb10dRusty Russellprint_firewall_line(const struct ip6t_entry *fw,
6321639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt		    struct xtc_handle *const h)
6335eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
63414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	struct xt_entry_target *t;
6355eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6365eed48af2516ebce0412121713d285bc30edb10dRusty Russell	t = ip6t_get_target((struct ip6t_entry *)fw);
6375eed48af2516ebce0412121713d285bc30edb10dRusty Russell	print_firewall(fw, t->u.user.name, 0, FMT_PRINT_RULE, h);
6385eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
6395eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6405eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
6417e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtappend_entry(const xt_chainlabel chain,
6425eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     struct ip6t_entry *fw,
6435eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int nsaddrs,
6445eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     const struct in6_addr saddrs[],
645332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	     const struct in6_addr smasks[],
6465eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int ndaddrs,
6475eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     const struct in6_addr daddrs[],
648332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	     const struct in6_addr dmasks[],
6495eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     int verbose,
6501639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     struct xtc_handle *handle)
6515eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
6525eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int i, j;
6535eed48af2516ebce0412121713d285bc30edb10dRusty Russell	int ret = 1;
6545eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6555eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (i = 0; i < nsaddrs; i++) {
6565eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fw->ipv6.src = saddrs[i];
657332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow		fw->ipv6.smsk = smasks[i];
6585eed48af2516ebce0412121713d285bc30edb10dRusty Russell		for (j = 0; j < ndaddrs; j++) {
6595eed48af2516ebce0412121713d285bc30edb10dRusty Russell			fw->ipv6.dst = daddrs[j];
660332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow			fw->ipv6.dmsk = dmasks[j];
6615eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (verbose)
6621c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				print_firewall_line(fw, handle);
6635eed48af2516ebce0412121713d285bc30edb10dRusty Russell			ret &= ip6tc_append_entry(chain, fw, handle);
6645eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
6655eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
6665eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6675eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ret;
6685eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
6695eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6705eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
6717e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtreplace_entry(const xt_chainlabel chain,
6725eed48af2516ebce0412121713d285bc30edb10dRusty Russell	      struct ip6t_entry *fw,
6735eed48af2516ebce0412121713d285bc30edb10dRusty Russell	      unsigned int rulenum,
67475cb763b54a89bf9b9c61740c760abce89df06f3Jan Engelhardt	      const struct in6_addr *saddr, const struct in6_addr *smask,
67575cb763b54a89bf9b9c61740c760abce89df06f3Jan Engelhardt	      const struct in6_addr *daddr, const struct in6_addr *dmask,
6765eed48af2516ebce0412121713d285bc30edb10dRusty Russell	      int verbose,
6771639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	      struct xtc_handle *handle)
6785eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
6795eed48af2516ebce0412121713d285bc30edb10dRusty Russell	fw->ipv6.src = *saddr;
6805eed48af2516ebce0412121713d285bc30edb10dRusty Russell	fw->ipv6.dst = *daddr;
68175cb763b54a89bf9b9c61740c760abce89df06f3Jan Engelhardt	fw->ipv6.smsk = *smask;
68275cb763b54a89bf9b9c61740c760abce89df06f3Jan Engelhardt	fw->ipv6.dmsk = *dmask;
6835eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6845eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (verbose)
6851c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt		print_firewall_line(fw, handle);
6865eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ip6tc_replace_entry(chain, fw, rulenum, handle);
6875eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
6885eed48af2516ebce0412121713d285bc30edb10dRusty Russell
6895eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
6907e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtinsert_entry(const xt_chainlabel chain,
6915eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     struct ip6t_entry *fw,
6925eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int rulenum,
6935eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int nsaddrs,
6945eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     const struct in6_addr saddrs[],
695332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	     const struct in6_addr smasks[],
6965eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int ndaddrs,
6975eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     const struct in6_addr daddrs[],
698332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	     const struct in6_addr dmasks[],
6995eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     int verbose,
7001639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     struct xtc_handle *handle)
7015eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
7025eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int i, j;
7035eed48af2516ebce0412121713d285bc30edb10dRusty Russell	int ret = 1;
7045eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7055eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (i = 0; i < nsaddrs; i++) {
7065eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fw->ipv6.src = saddrs[i];
707332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow		fw->ipv6.smsk = smasks[i];
7085eed48af2516ebce0412121713d285bc30edb10dRusty Russell		for (j = 0; j < ndaddrs; j++) {
7095eed48af2516ebce0412121713d285bc30edb10dRusty Russell			fw->ipv6.dst = daddrs[j];
710332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow			fw->ipv6.dmsk = dmasks[j];
7115eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (verbose)
7121c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				print_firewall_line(fw, handle);
7135eed48af2516ebce0412121713d285bc30edb10dRusty Russell			ret &= ip6tc_insert_entry(chain, fw, rulenum, handle);
7145eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
7155eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
7165eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7175eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ret;
7185eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
7195eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7205eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic unsigned char *
721d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardtmake_delete_mask(const struct xtables_rule_match *matches,
7224f0d7b660e0ae8f678142fd2a1722b27ad472169Jan Engelhardt		 const struct xtables_target *target)
7235eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
7245eed48af2516ebce0412121713d285bc30edb10dRusty Russell	/* Establish mask for comparison */
7255eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int size;
726d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt	const struct xtables_rule_match *matchp;
7275eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned char *mask, *mptr;
7285eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7295eed48af2516ebce0412121713d285bc30edb10dRusty Russell	size = sizeof(struct ip6t_entry);
73069ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson	for (matchp = matches; matchp; matchp = matchp->next)
73114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt		size += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
7325eed48af2516ebce0412121713d285bc30edb10dRusty Russell
733630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt	mask = xtables_calloc(1, size
73414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			 + XT_ALIGN(sizeof(struct xt_entry_target))
7354f0d7b660e0ae8f678142fd2a1722b27ad472169Jan Engelhardt			 + target->size);
7365eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7375eed48af2516ebce0412121713d285bc30edb10dRusty Russell	memset(mask, 0xFF, sizeof(struct ip6t_entry));
7385eed48af2516ebce0412121713d285bc30edb10dRusty Russell	mptr = mask + sizeof(struct ip6t_entry);
7395eed48af2516ebce0412121713d285bc30edb10dRusty Russell
74069ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson	for (matchp = matches; matchp; matchp = matchp->next) {
7415eed48af2516ebce0412121713d285bc30edb10dRusty Russell		memset(mptr, 0xFF,
74214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt		       XT_ALIGN(sizeof(struct xt_entry_match))
74369ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson		       + matchp->match->userspacesize);
74414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt		mptr += XT_ALIGN(sizeof(struct xt_entry_match)) + matchp->match->size;
7455eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
7465eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7475b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	memset(mptr, 0xFF,
74814da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	       XT_ALIGN(sizeof(struct xt_entry_target))
7494f0d7b660e0ae8f678142fd2a1722b27ad472169Jan Engelhardt	       + target->userspacesize);
7505eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7515eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return mask;
7525eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
7535eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7545eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
7557e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtdelete_entry(const xt_chainlabel chain,
7565eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     struct ip6t_entry *fw,
7575eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int nsaddrs,
7585eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     const struct in6_addr saddrs[],
759332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	     const struct in6_addr smasks[],
7605eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     unsigned int ndaddrs,
7615eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     const struct in6_addr daddrs[],
762332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	     const struct in6_addr dmasks[],
7635eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     int verbose,
7641639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     struct xtc_handle *handle,
7654f0d7b660e0ae8f678142fd2a1722b27ad472169Jan Engelhardt	     struct xtables_rule_match *matches,
7664f0d7b660e0ae8f678142fd2a1722b27ad472169Jan Engelhardt	     const struct xtables_target *target)
7675eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
7685eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int i, j;
7695eed48af2516ebce0412121713d285bc30edb10dRusty Russell	int ret = 1;
7705eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned char *mask;
7715eed48af2516ebce0412121713d285bc30edb10dRusty Russell
7724f0d7b660e0ae8f678142fd2a1722b27ad472169Jan Engelhardt	mask = make_delete_mask(matches, target);
7735eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (i = 0; i < nsaddrs; i++) {
77457e07af96a28d81281a20ad7a0e9dc189caf4861Philip Blundell		fw->ipv6.src = saddrs[i];
775332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow		fw->ipv6.smsk = smasks[i];
7765eed48af2516ebce0412121713d285bc30edb10dRusty Russell		for (j = 0; j < ndaddrs; j++) {
77757e07af96a28d81281a20ad7a0e9dc189caf4861Philip Blundell			fw->ipv6.dst = daddrs[j];
778332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow			fw->ipv6.dmsk = dmasks[j];
7795eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (verbose)
7801c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				print_firewall_line(fw, handle);
78157e07af96a28d81281a20ad7a0e9dc189caf4861Philip Blundell			ret &= ip6tc_delete_entry(chain, fw, mask, handle);
7825eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
7835eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
7844dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson	free(mask);
7854dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson
7865eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ret;
7875eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
7885eed48af2516ebce0412121713d285bc30edb10dRusty Russell
789d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanekstatic int
7907e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtcheck_entry(const xt_chainlabel chain, struct ip6t_entry *fw,
791d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	    unsigned int nsaddrs, const struct in6_addr *saddrs,
792d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	    const struct in6_addr *smasks, unsigned int ndaddrs,
793d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	    const struct in6_addr *daddrs, const struct in6_addr *dmasks,
7941639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	    bool verbose, struct xtc_handle *handle,
795d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	    struct xtables_rule_match *matches,
796d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	    const struct xtables_target *target)
797d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek{
798d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	unsigned int i, j;
799d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	int ret = 1;
800d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	unsigned char *mask;
801d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek
802d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	mask = make_delete_mask(matches, target);
803d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	for (i = 0; i < nsaddrs; i++) {
804d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		fw->ipv6.src = saddrs[i];
805d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		fw->ipv6.smsk = smasks[i];
806d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		for (j = 0; j < ndaddrs; j++) {
807d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			fw->ipv6.dst = daddrs[j];
808d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			fw->ipv6.dmsk = dmasks[j];
809d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			if (verbose)
810d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek				print_firewall_line(fw, handle);
811d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			ret &= ip6tc_check_entry(chain, fw, mask, handle);
812d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		}
813d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	}
814d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek
815d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	free(mask);
816d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	return ret;
817d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek}
818d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek
819764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabóint
8201639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardtfor_each_chain6(int (*fn)(const xt_chainlabel, int, struct xtc_handle *),
8211639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	       int verbose, int builtinstoo, struct xtc_handle *handle)
8225eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
8235b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	int ret = 1;
8245eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *chain;
8255eed48af2516ebce0412121713d285bc30edb10dRusty Russell	char *chains;
8265eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int i, chaincount = 0;
8275eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8285eed48af2516ebce0412121713d285bc30edb10dRusty Russell	chain = ip6tc_first_chain(handle);
8295eed48af2516ebce0412121713d285bc30edb10dRusty Russell	while (chain) {
8305eed48af2516ebce0412121713d285bc30edb10dRusty Russell		chaincount++;
8315eed48af2516ebce0412121713d285bc30edb10dRusty Russell		chain = ip6tc_next_chain(handle);
8325b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	}
8335eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8347e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardt	chains = xtables_malloc(sizeof(xt_chainlabel) * chaincount);
8355eed48af2516ebce0412121713d285bc30edb10dRusty Russell	i = 0;
8365eed48af2516ebce0412121713d285bc30edb10dRusty Russell	chain = ip6tc_first_chain(handle);
8375eed48af2516ebce0412121713d285bc30edb10dRusty Russell	while (chain) {
8387e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardt		strcpy(chains + i*sizeof(xt_chainlabel), chain);
8395eed48af2516ebce0412121713d285bc30edb10dRusty Russell		i++;
8405eed48af2516ebce0412121713d285bc30edb10dRusty Russell		chain = ip6tc_next_chain(handle);
8415b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	}
8425eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8435eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (i = 0; i < chaincount; i++) {
8445eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (!builtinstoo
8457e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardt		    && ip6tc_builtin(chains + i*sizeof(xt_chainlabel),
8461c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				    handle) == 1)
8475eed48af2516ebce0412121713d285bc30edb10dRusty Russell			continue;
8487e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardt		ret &= fn(chains + i*sizeof(xt_chainlabel), verbose, handle);
8495eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
8505eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8515eed48af2516ebce0412121713d285bc30edb10dRusty Russell	free(chains);
8525b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann	return ret;
8535eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
8545eed48af2516ebce0412121713d285bc30edb10dRusty Russell
855764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabóint
8567e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtflush_entries6(const xt_chainlabel chain, int verbose,
8571639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	      struct xtc_handle *handle)
8585eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
8595eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!chain)
86074ace0a46048d01611a44c24f6fe5f59d936231bMaciej Zenczykowski		return for_each_chain6(flush_entries6, verbose, 1, handle);
8615eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8625eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (verbose)
8635eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fprintf(stdout, "Flushing chain `%s'\n", chain);
8645eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ip6tc_flush_entries(chain, handle);
8655eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
8665eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8675eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
8687e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtzero_entries(const xt_chainlabel chain, int verbose,
8691639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     struct xtc_handle *handle)
8705eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
8715eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!chain)
872241e73594f6d75e32a7e89ebdb6b7f7917a48df0Maciej Zenczykowski		return for_each_chain6(zero_entries, verbose, 1, handle);
8735eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8745eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (verbose)
8755eed48af2516ebce0412121713d285bc30edb10dRusty Russell		fprintf(stdout, "Zeroing chain `%s'\n", chain);
8765eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ip6tc_zero_entries(chain, handle);
8775eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
8785eed48af2516ebce0412121713d285bc30edb10dRusty Russell
879764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabóint
8807e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtdelete_chain6(const xt_chainlabel chain, int verbose,
8811639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     struct xtc_handle *handle)
8825eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
8835eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!chain)
88485aae15567b8ae1eaedf9f011ba7aef80dfca208Maciej Zenczykowski		return for_each_chain6(delete_chain6, verbose, 0, handle);
8855eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8865eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (verbose)
8875b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann		fprintf(stdout, "Deleting chain `%s'\n", chain);
8885eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ip6tc_delete_chain(chain, handle);
8895eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
8905eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8915eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic int
8927e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtlist_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric,
8931639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     int expanded, int linenumbers, struct xtc_handle *handle)
8945eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
8955eed48af2516ebce0412121713d285bc30edb10dRusty Russell	int found = 0;
8965eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int format;
8975eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *this;
8985eed48af2516ebce0412121713d285bc30edb10dRusty Russell
8995eed48af2516ebce0412121713d285bc30edb10dRusty Russell	format = FMT_OPTIONS;
9005eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!verbose)
9015eed48af2516ebce0412121713d285bc30edb10dRusty Russell		format |= FMT_NOCOUNTS;
9025eed48af2516ebce0412121713d285bc30edb10dRusty Russell	else
9035eed48af2516ebce0412121713d285bc30edb10dRusty Russell		format |= FMT_VIA;
9045eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9055eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (numeric)
9065eed48af2516ebce0412121713d285bc30edb10dRusty Russell		format |= FMT_NUMERIC;
9075eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9085eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!expanded)
9095eed48af2516ebce0412121713d285bc30edb10dRusty Russell		format |= FMT_KILOMEGAGIGA;
9105eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9115eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (linenumbers)
9125eed48af2516ebce0412121713d285bc30edb10dRusty Russell		format |= FMT_LINENUMBERS;
9135eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9145eed48af2516ebce0412121713d285bc30edb10dRusty Russell	for (this = ip6tc_first_chain(handle);
9155eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     this;
9165eed48af2516ebce0412121713d285bc30edb10dRusty Russell	     this = ip6tc_next_chain(handle)) {
9175eed48af2516ebce0412121713d285bc30edb10dRusty Russell		const struct ip6t_entry *i;
9185eed48af2516ebce0412121713d285bc30edb10dRusty Russell		unsigned int num;
9195eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9205eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (chain && strcmp(chain, this) != 0)
9215eed48af2516ebce0412121713d285bc30edb10dRusty Russell			continue;
9225eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9235eed48af2516ebce0412121713d285bc30edb10dRusty Russell		if (found) printf("\n");
9245eed48af2516ebce0412121713d285bc30edb10dRusty Russell
925bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom		if (!rulenum)
926bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom		    print_header(format, this, handle);
9275eed48af2516ebce0412121713d285bc30edb10dRusty Russell		i = ip6tc_first_rule(this, handle);
9285eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9295eed48af2516ebce0412121713d285bc30edb10dRusty Russell		num = 0;
9305eed48af2516ebce0412121713d285bc30edb10dRusty Russell		while (i) {
931bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			num++;
932bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			if (!rulenum || num == rulenum)
933bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom				print_firewall(i,
934bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom					       ip6tc_get_target(i, handle),
935bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom					       num,
936bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom					       format,
9371c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt					       handle);
9385eed48af2516ebce0412121713d285bc30edb10dRusty Russell			i = ip6tc_next_rule(i, handle);
9395eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
9405eed48af2516ebce0412121713d285bc30edb10dRusty Russell		found = 1;
9415eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
9425eed48af2516ebce0412121713d285bc30edb10dRusty Russell
9435eed48af2516ebce0412121713d285bc30edb10dRusty Russell	errno = ENOENT;
9445eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return found;
9455eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
9465eed48af2516ebce0412121713d285bc30edb10dRusty Russell
94796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom/* This assumes that mask is contiguous, and byte-bounded. */
94896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstromstatic void
94996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstromprint_iface(char letter, const char *iface, const unsigned char *mask,
95096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	    int invert)
95196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom{
95296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	unsigned int i;
95396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
95496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (mask[0] == 0)
95596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		return;
95696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
957aa66aeda34bea5a8d05717899a229e57aa3237d5Jan Engelhardt	printf("%s -%c ", invert ? " !" : "", letter);
95896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
95996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	for (i = 0; i < IFNAMSIZ; i++) {
96096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (mask[i] != 0) {
96196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			if (iface[i] != '\0')
96296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				printf("%c", iface[i]);
96396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		} else {
96496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			/* we can access iface[i-1] here, because
96596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			 * a few lines above we make sure that mask[0] != 0 */
96696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			if (iface[i-1] != '\0')
96796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				printf("+");
96896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			break;
96996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
97096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	}
97196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom}
97296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
97396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom/* The ip6tables looks up the /etc/protocols. */
9747ac405297ec38449b30e3b05fd6bf2082fd3d803Jan Engelhardtstatic void print_proto(uint16_t proto, int invert)
97596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom{
97696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (proto) {
97796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		unsigned int i;
97873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		const char *invertstr = invert ? " !" : "";
97996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
980d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt		const struct protoent *pent = getprotobynumber(proto);
98196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (pent) {
98273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt			printf("%s -p %s",
98396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			       invertstr, pent->p_name);
98496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			return;
98596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
98696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
9871de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt		for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
9881de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt			if (xtables_chain_protos[i].num == proto) {
98973866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt				printf("%s -p %s",
9901de7edffc9085c0f41c261dca995e28ae4126c29Jan Engelhardt				       invertstr, xtables_chain_protos[i].name);
99196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				return;
99296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			}
99396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
99473866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%s -p %u", invertstr, proto);
99596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	}
99696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom}
99796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
99814da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardtstatic int print_match_save(const struct xt_entry_match *e,
99996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			const struct ip6t_ip6 *ip)
100096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom{
1001d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt	const struct xtables_match *match =
10022338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt		xtables_find_match(e->u.user.name, XTF_TRY_LOAD, NULL);
100396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
100496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (match) {
1005efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik		printf(" -m %s",
1006efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik			match->alias ? match->alias(e) : e->u.user.name);
100796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
100896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		/* some matches don't provide a save function */
100996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (match->save)
101096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			match->save(ip, e);
101196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	} else {
101296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (e->u.match_size) {
101396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			fprintf(stderr,
101496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				"Can't find library for match `%s'\n",
101596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				e->u.user.name);
101696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			exit(1);
101796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
101896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	}
101996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	return 0;
102096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom}
102196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
102296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom/* print a given ip including mask if neccessary */
1023d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardtstatic void print_ip(const char *prefix, const struct in6_addr *ip,
1024d1435e0772e40c310dff35abe7bf1e7de5b18ee4Jan Engelhardt		     const struct in6_addr *mask, int invert)
102596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom{
102696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	char buf[51];
1027cccfff9309743f173c504dd265fae173caa5b47fPablo Neira Ayuso	int l = xtables_ip6mask_to_cidr(mask);
102896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
102996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (l == 0 && !invert)
103096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		return;
103196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
103273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf("%s %s %s",
103373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		invert ? " !" : "",
1034b1d968c30dde563c2738fdacb723c18232fb5ccbJan Engelhardt		prefix,
103596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		inet_ntop(AF_INET6, ip, buf, sizeof buf));
103696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
103796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (l == -1)
103873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("/%s", inet_ntop(AF_INET6, mask, buf, sizeof buf));
103996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	else
104073866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("/%d", l);
104196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom}
104296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
104396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom/* We want this to be readable, so only print out neccessary fields.
104496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom * Because that's the kind of world I want to live in.  */
10459680f2ecbdb7e5c61ab60e7399e9ca9f1013fd8dMaciej Zenczykowskivoid print_rule6(const struct ip6t_entry *e,
10461639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt		       struct xtc_handle *h, const char *chain, int counters)
104796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom{
104814da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	const struct xt_entry_target *t;
104996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	const char *target_name;
105096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
105196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* print counters for iptables-save */
105296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (counters > 0)
105396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		printf("[%llu:%llu] ", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt);
105496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
105596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* print chain name */
105673866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt	printf("-A %s", chain);
105796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
105896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* Print IP part. */
105996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	print_ip("-s", &(e->ipv6.src), &(e->ipv6.smsk),
106096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			e->ipv6.invflags & IP6T_INV_SRCIP);
106196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
106296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	print_ip("-d", &(e->ipv6.dst), &(e->ipv6.dmsk),
106396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			e->ipv6.invflags & IP6T_INV_DSTIP);
106496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
106596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	print_iface('i', e->ipv6.iniface, e->ipv6.iniface_mask,
106696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		    e->ipv6.invflags & IP6T_INV_VIA_IN);
106796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
106896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	print_iface('o', e->ipv6.outiface, e->ipv6.outiface_mask,
106996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		    e->ipv6.invflags & IP6T_INV_VIA_OUT);
107096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
107114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	print_proto(e->ipv6.proto, e->ipv6.invflags & XT_INV_PROTO);
107296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
107396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom#if 0
107496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* not definied in ipv6
107596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	 * FIXME: linux/netfilter_ipv6/ip6_tables: IP6T_INV_FRAG why definied? */
107696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (e->ipv6.flags & IPT_F_FRAG)
107773866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%s -f",
107873866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		       e->ipv6.invflags & IP6T_INV_FRAG ? " !" : "");
107996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom#endif
108096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
108196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (e->ipv6.flags & IP6T_F_TOS)
108273866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf("%s -? %d",
108373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		       e->ipv6.invflags & IP6T_INV_TOS ? " !" : "",
108496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		       e->ipv6.tos);
108596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
108696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* Print matchinfo part */
108796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (e->target_offset) {
108896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		IP6T_MATCH_ITERATE(e, print_match_save, &e->ipv6);
108996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	}
109096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
109196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* print counters for iptables -R */
109296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (counters < 0)
109373866357e4a7a0fdc1b293bf8863fee2bd56da9eJan Engelhardt		printf(" -c %llu %llu", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt);
109496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
1095efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik	/* Print target name and targinfo part */
109696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	target_name = ip6tc_get_target(e, h);
109796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	t = ip6t_get_target((struct ip6t_entry *)e);
109896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (t->u.user.name[0]) {
10992338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt		struct xtables_target *target =
11002338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt			xtables_find_target(t->u.user.name, XTF_TRY_LOAD);
110196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
110296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (!target) {
110396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			fprintf(stderr, "Can't find library for target `%s'\n",
110496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				t->u.user.name);
110596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			exit(1);
110696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
110796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
1108efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik		printf(" -j %s", target->alias ? target->alias(t) : target_name);
110996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (target->save)
111096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			target->save(&e->ipv6, t);
111196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		else {
111214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			/* If the target size is greater than xt_entry_target
111396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			 * there is something to be saved, we just don't know
111496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			 * how to print it */
111596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			if (t->u.target_size !=
111614da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			    sizeof(struct xt_entry_target)) {
111796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				fprintf(stderr, "Target `%s' is missing "
111896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom						"save function\n",
111996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom					t->u.user.name);
112096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				exit(1);
112196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			}
112296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
1123efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik	} else if (target_name && (*target_name != '\0'))
1124efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik#ifdef IP6T_F_GOTO
1125efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik		printf(" -%c %s", e->ipv6.flags & IP6T_F_GOTO ? 'g' : 'j', target_name);
1126efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik#else
1127efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik		printf(" -j %s", target_name);
1128efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik#endif
1129efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik
113096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	printf("\n");
113196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom}
113296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
113396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstromstatic int
11347e5e866a36a76c153e5903b8251f90cfe07a1d34Jan Engelhardtlist_rules(const xt_chainlabel chain, int rulenum, int counters,
11351639fe86579f86f5f6a954a9b0adde2e16ad1980Jan Engelhardt	     struct xtc_handle *handle)
113696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom{
113796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	const char *this = NULL;
113896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	int found = 0;
113996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
114096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	if (counters)
114196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	    counters = -1;		/* iptables -c format */
114296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
114396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	/* Dump out chain names first,
114496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	 * thereby preventing dependency conflicts */
1145bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom	if (!rulenum) for (this = ip6tc_first_chain(handle);
114696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	     this;
114796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	     this = ip6tc_next_chain(handle)) {
114896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (chain && strcmp(this, chain) != 0)
114996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			continue;
115096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
11511c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt		if (ip6tc_builtin(this, handle)) {
115214da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			struct xt_counters count;
115396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			printf("-P %s %s", this, ip6tc_get_policy(this, &count, handle));
115496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			if (counters)
115596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			    printf(" -c %llu %llu", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt);
115696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			printf("\n");
115796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		} else {
115896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			printf("-N %s\n", this);
115996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
116096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	}
116196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
116296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	for (this = ip6tc_first_chain(handle);
116396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	     this;
116496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	     this = ip6tc_next_chain(handle)) {
116596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		const struct ip6t_entry *e;
1166bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom		int num = 0;
116796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
116896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (chain && strcmp(this, chain) != 0)
116996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			continue;
117096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
117196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		/* Dump out rules */
117296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		e = ip6tc_first_rule(this, handle);
117396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		while(e) {
1174bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			num++;
1175bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			if (!rulenum || num == rulenum)
11769680f2ecbdb7e5c61ab60e7399e9ca9f1013fd8dMaciej Zenczykowski			    print_rule6(e, handle, this, counters);
117796296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			e = ip6tc_next_rule(e, handle);
117896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		}
117996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		found = 1;
118096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	}
118196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
118296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	errno = ENOENT;
118396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	return found;
118496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom}
118596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
11865eed48af2516ebce0412121713d285bc30edb10dRusty Russellstatic struct ip6t_entry *
11875eed48af2516ebce0412121713d285bc30edb10dRusty Russellgenerate_entry(const struct ip6t_entry *fw,
1188395e441e20ea9ab7f37122bcfd76fec527fa447bJan Engelhardt	       struct xtables_rule_match *matches,
118914da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	       struct xt_entry_target *target)
11905eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
11915eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int size;
1192395e441e20ea9ab7f37122bcfd76fec527fa447bJan Engelhardt	struct xtables_rule_match *matchp;
11935eed48af2516ebce0412121713d285bc30edb10dRusty Russell	struct ip6t_entry *e;
11945eed48af2516ebce0412121713d285bc30edb10dRusty Russell
11955eed48af2516ebce0412121713d285bc30edb10dRusty Russell	size = sizeof(struct ip6t_entry);
119669ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson	for (matchp = matches; matchp; matchp = matchp->next)
119769ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson		size += matchp->match->m->u.match_size;
11985eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1199630ef48037f3602333addfdb53789c9c6a4bb4c8Jan Engelhardt	e = xtables_malloc(size + target->u.target_size);
12005eed48af2516ebce0412121713d285bc30edb10dRusty Russell	*e = *fw;
12015eed48af2516ebce0412121713d285bc30edb10dRusty Russell	e->target_offset = size;
12025eed48af2516ebce0412121713d285bc30edb10dRusty Russell	e->next_offset = size + target->u.target_size;
12035eed48af2516ebce0412121713d285bc30edb10dRusty Russell
12045eed48af2516ebce0412121713d285bc30edb10dRusty Russell	size = 0;
120569ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson	for (matchp = matches; matchp; matchp = matchp->next) {
120669ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson		memcpy(e->elems + size, matchp->match->m, matchp->match->m->u.match_size);
120769ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson		size += matchp->match->m->u.match_size;
12085eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
12095eed48af2516ebce0412121713d285bc30edb10dRusty Russell	memcpy(e->elems + size, target, target->u.target_size);
12105eed48af2516ebce0412121713d285bc30edb10dRusty Russell
12115eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return e;
12125eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
12135eed48af2516ebce0412121713d285bc30edb10dRusty Russell
12149bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardtstatic void command_jump(struct iptables_command_state *cs)
12159bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt{
12169bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	size_t size;
12179bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt
12189bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	set_option(&cs->options, OPT_JUMP, &cs->fw6.ipv6.invflags, cs->invert);
12199bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	cs->jumpto = parse_target(optarg);
12209bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	/* TRY_LOAD (may be chain name) */
12219bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	cs->target = xtables_find_target(cs->jumpto, XTF_TRY_LOAD);
12229bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt
12239bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	if (cs->target == NULL)
12249bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt		return;
12259bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt
122614da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	size = XT_ALIGN(sizeof(struct xt_entry_target)) + cs->target->size;
12279bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt
12289bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	cs->target->t = xtables_calloc(1, size);
12299bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	cs->target->t->u.target_size = size;
1230dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	if (cs->target->real_name == NULL) {
12312aaa7ec29059027756f076c4767b4fa034ebd166Pablo Neira Ayuso		strcpy(cs->target->t->u.user.name, cs->jumpto);
1232dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	} else {
12332aaa7ec29059027756f076c4767b4fa034ebd166Pablo Neira Ayuso		strcpy(cs->target->t->u.user.name, cs->target->real_name);
1234efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik		if (!(cs->target->ext_flags & XTABLES_EXT_ALIAS))
1235efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik			fprintf(stderr, "Notice: The %s target is converted into %s target "
1236efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik			        "in rule listing and saving.\n",
1237efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik			        cs->jumpto, cs->target->real_name);
1238dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	}
1239dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	cs->target->t->u.user.revision = cs->target->revision;
1240cd2f9bdbb7f9b737e5d640aafeb78bcd8e3a7adfJan Engelhardt
124114190986f87301b18bcc473c842bd82d778d87a2Jan Engelhardt	xs_init_target(cs->target);
1242aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt	if (cs->target->x6_options != NULL)
1243aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt		opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
1244aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt					    cs->target->x6_options,
1245aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt					    &cs->target->option_offset);
1246aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt	else
1247aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt		opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
1248aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt					     cs->target->extra_opts,
1249aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt					     &cs->target->option_offset);
12509bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	if (opts == NULL)
12519bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt		xtables_error(OTHER_PROBLEM, "can't alloc memory!");
12529bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt}
12539bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt
125417e310b2610448605567644f667c79f41d76f51eJan Engelhardtstatic void command_match(struct iptables_command_state *cs)
125517e310b2610448605567644f667c79f41d76f51eJan Engelhardt{
125617e310b2610448605567644f667c79f41d76f51eJan Engelhardt	struct xtables_match *m;
125717e310b2610448605567644f667c79f41d76f51eJan Engelhardt	size_t size;
125817e310b2610448605567644f667c79f41d76f51eJan Engelhardt
125917e310b2610448605567644f667c79f41d76f51eJan Engelhardt	if (cs->invert)
126017e310b2610448605567644f667c79f41d76f51eJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
126117e310b2610448605567644f667c79f41d76f51eJan Engelhardt			   "unexpected ! flag before --match");
126217e310b2610448605567644f667c79f41d76f51eJan Engelhardt
126317e310b2610448605567644f667c79f41d76f51eJan Engelhardt	m = xtables_find_match(optarg, XTF_LOAD_MUST_SUCCEED, &cs->matches);
126414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt	size = XT_ALIGN(sizeof(struct xt_entry_match)) + m->size;
126517e310b2610448605567644f667c79f41d76f51eJan Engelhardt	m->m = xtables_calloc(1, size);
126617e310b2610448605567644f667c79f41d76f51eJan Engelhardt	m->m->u.match_size = size;
1267dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	if (m->real_name == NULL) {
1268dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt		strcpy(m->m->u.user.name, m->name);
1269dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	} else {
1270dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt		strcpy(m->m->u.user.name, m->real_name);
1271efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik		if (!(m->ext_flags & XTABLES_EXT_ALIAS))
1272efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik			fprintf(stderr, "Notice: The %s match is converted into %s match "
1273efcdba41ca6bde51c8753cb30c869c370f0a3b93Jozsef Kadlecsik			        "in rule listing and saving.\n", m->name, m->real_name);
1274dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	}
1275dd43527cb6bdf3d469100850ca10dcd2fb761304Jan Engelhardt	m->m->u.user.revision = m->revision;
1276c436dad7cfdd80ca4a05ceed556c39babc266f55Jan Engelhardt
127714190986f87301b18bcc473c842bd82d778d87a2Jan Engelhardt	xs_init_match(m);
1278aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt	if (m == m->next)
1279aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt		return;
1280aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt	/* Merge options for non-cloned matches */
1281aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt	if (m->x6_options != NULL)
1282aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt		opts = xtables_options_xfrm(ip6tables_globals.orig_opts, opts,
1283aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt					    m->x6_options, &m->option_offset);
1284aa37acc1423126f555135935c687eb91995b9440Jan Engelhardt	else if (m->extra_opts != NULL)
128517e310b2610448605567644f667c79f41d76f51eJan Engelhardt		opts = xtables_merge_options(ip6tables_globals.orig_opts, opts,
128617e310b2610448605567644f667c79f41d76f51eJan Engelhardt					     m->extra_opts, &m->option_offset);
128717e310b2610448605567644f667c79f41d76f51eJan Engelhardt}
128817e310b2610448605567644f667c79f41d76f51eJan Engelhardt
1289d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayusoint do_command6(int argc, char *argv[], char **table,
1290d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso		struct xtc_handle **handle, bool restore)
12915eed48af2516ebce0412121713d285bc30edb10dRusty Russell{
12923a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	struct iptables_command_state cs;
12933a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	struct ip6t_entry *e = NULL;
12945eed48af2516ebce0412121713d285bc30edb10dRusty Russell	unsigned int nsaddrs = 0, ndaddrs = 0;
12955eed48af2516ebce0412121713d285bc30edb10dRusty Russell	struct in6_addr *saddrs = NULL, *daddrs = NULL;
1296332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	struct in6_addr *smasks = NULL, *dmasks = NULL;
12975eed48af2516ebce0412121713d285bc30edb10dRusty Russell
12983a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	int verbose = 0;
129993587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester	bool wait = false;
13005eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *chain = NULL;
13015eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *shostnetworkmask = NULL, *dhostnetworkmask = NULL;
13025eed48af2516ebce0412121713d285bc30edb10dRusty Russell	const char *policy = NULL, *newname = NULL;
13033a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	unsigned int rulenum = 0, command = 0;
130443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte	const char *pcnt = NULL, *bcnt = NULL;
13055eed48af2516ebce0412121713d285bc30edb10dRusty Russell	int ret = 1;
13068b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	struct xtables_match *m;
1307395e441e20ea9ab7f37122bcfd76fec527fa447bJan Engelhardt	struct xtables_rule_match *matchp;
13088b7c64d6ba156a99008fcd810cba874c73294333Jan Engelhardt	struct xtables_target *t;
1309875441ea60d9fd9378475526f2f632b932790553Patrick McHardy	unsigned long long cnt;
13105eed48af2516ebce0412121713d285bc30edb10dRusty Russell
13113a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	memset(&cs, 0, sizeof(cs));
13129bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt	cs.jumpto = "";
1313f935ae05040d2d790433abee49ef79f4a8ed393cJan Engelhardt	cs.argv = argv;
13145eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1315742e9a43c314b45a76acdac8f53d36f1337154bfMaciej Zenczykowski	/* re-set optind to 0 in case do_command6 gets called
13163aa6287c97ec8c2d706c498a793942161ac4ccd3András Kis-Szabó	 * a second time */
13173aa6287c97ec8c2d706c498a793942161ac4ccd3András Kis-Szabó	optind = 0;
13183aa6287c97ec8c2d706c498a793942161ac4ccd3András Kis-Szabó
1319742e9a43c314b45a76acdac8f53d36f1337154bfMaciej Zenczykowski	/* clear mflags in case do_command6 gets called a second time
132043ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte	 * (we clear the global list of all matches for security)*/
13210d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI	for (m = xtables_matches; m; m = m->next)
132243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		m->mflags = 0;
13233aa6287c97ec8c2d706c498a793942161ac4ccd3András Kis-Szabó
13240d502bcdbc97ed359e84f6a21dfa0049b3b60a6cYasuyuki KOZAKAI	for (t = xtables_targets; t; t = t->next) {
132543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		t->tflags = 0;
132643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		t->used = 0;
132743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte	}
13283aa6287c97ec8c2d706c498a793942161ac4ccd3András Kis-Szabó
13295eed48af2516ebce0412121713d285bc30edb10dRusty Russell	/* Suppress error messages: we may add new options if we
13305eed48af2516ebce0412121713d285bc30edb10dRusty Russell           demand-load a protocol. */
13315eed48af2516ebce0412121713d285bc30edb10dRusty Russell	opterr = 0;
13325eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1333d3b2e391e3b944581e20e216af76339cc87d0590Jan Engelhardt	opts = xt_params->orig_opts;
13343a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	while ((cs.c = getopt_long(argc, argv,
133593587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester	   "-:A:C:D:R:I:L::S::M:F::Z::N:X::E:P:Vh::o:p:s:d:j:i:bvwnt:m:xc:g:46",
13365eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   opts, NULL)) != -1) {
13373a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		switch (cs.c) {
13385eed48af2516ebce0412121713d285bc30edb10dRusty Russell			/*
13395eed48af2516ebce0412121713d285bc30edb10dRusty Russell			 * Command selection
13405eed48af2516ebce0412121713d285bc30edb10dRusty Russell			 */
13415eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'A':
13425eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_APPEND, CMD_NONE,
13433a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
13445eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
13455eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
13465eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1347d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		case 'C':
1348d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			add_command(&command, CMD_CHECK, CMD_NONE,
1349d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			            cs.invert);
1350d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			chain = optarg;
1351d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek			break;
1352d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek
13535eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'D':
13545eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_DELETE, CMD_NONE,
13553a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
13565eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
13575eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optind < argc && argv[optind][0] != '-'
13585eed48af2516ebce0412121713d285bc30edb10dRusty Russell			    && argv[optind][0] != '!') {
13595eed48af2516ebce0412121713d285bc30edb10dRusty Russell				rulenum = parse_rulenumber(argv[optind++]);
13605eed48af2516ebce0412121713d285bc30edb10dRusty Russell				command = CMD_DELETE_NUM;
13615eed48af2516ebce0412121713d285bc30edb10dRusty Russell			}
13625eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
13635eed48af2516ebce0412121713d285bc30edb10dRusty Russell
13645eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'R':
13655eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_REPLACE, CMD_NONE,
13663a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
13675eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
13685eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optind < argc && argv[optind][0] != '-'
13695eed48af2516ebce0412121713d285bc30edb10dRusty Russell			    && argv[optind][0] != '!')
13705eed48af2516ebce0412121713d285bc30edb10dRusty Russell				rulenum = parse_rulenumber(argv[optind++]);
13715eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else
13721829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
13735eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   "-%c requires a rule number",
13745eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   cmd2char(CMD_REPLACE));
13755eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
13765eed48af2516ebce0412121713d285bc30edb10dRusty Russell
13775eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'I':
13785eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_INSERT, CMD_NONE,
13793a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
13805eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
13815eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optind < argc && argv[optind][0] != '-'
13825eed48af2516ebce0412121713d285bc30edb10dRusty Russell			    && argv[optind][0] != '!')
13835eed48af2516ebce0412121713d285bc30edb10dRusty Russell				rulenum = parse_rulenumber(argv[optind++]);
13845eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else rulenum = 1;
13855eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
13865eed48af2516ebce0412121713d285bc30edb10dRusty Russell
13875eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'L':
1388b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta			add_command(&command, CMD_LIST,
13893a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    CMD_ZERO | CMD_ZERO_NUM, cs.invert);
13905eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optarg) chain = optarg;
13915eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else if (optind < argc && argv[optind][0] != '-'
13925eed48af2516ebce0412121713d285bc30edb10dRusty Russell				 && argv[optind][0] != '!')
13935eed48af2516ebce0412121713d285bc30edb10dRusty Russell				chain = argv[optind++];
1394bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			if (optind < argc && argv[optind][0] != '-'
1395bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			    && argv[optind][0] != '!')
1396bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom				rulenum = parse_rulenumber(argv[optind++]);
13975eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
13985eed48af2516ebce0412121713d285bc30edb10dRusty Russell
139996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		case 'S':
1400b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta			add_command(&command, CMD_LIST_RULES,
14013a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    CMD_ZERO | CMD_ZERO_NUM, cs.invert);
140296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			if (optarg) chain = optarg;
140396296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			else if (optind < argc && argv[optind][0] != '-'
140496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				 && argv[optind][0] != '!')
140596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom				chain = argv[optind++];
1406bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			if (optind < argc && argv[optind][0] != '-'
1407bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom			    && argv[optind][0] != '!')
1408bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom				rulenum = parse_rulenumber(argv[optind++]);
140996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			break;
141096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom
14115eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'F':
14125eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_FLUSH, CMD_NONE,
14133a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
14145eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optarg) chain = optarg;
14155eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else if (optind < argc && argv[optind][0] != '-'
14165eed48af2516ebce0412121713d285bc30edb10dRusty Russell				 && argv[optind][0] != '!')
14175eed48af2516ebce0412121713d285bc30edb10dRusty Russell				chain = argv[optind++];
14185eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
14195eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14205eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'Z':
142196296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			add_command(&command, CMD_ZERO, CMD_LIST|CMD_LIST_RULES,
14223a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
14235eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optarg) chain = optarg;
14245eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else if (optind < argc && argv[optind][0] != '-'
14255eed48af2516ebce0412121713d285bc30edb10dRusty Russell				&& argv[optind][0] != '!')
14265eed48af2516ebce0412121713d285bc30edb10dRusty Russell				chain = argv[optind++];
1427b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta			if (optind < argc && argv[optind][0] != '-'
1428b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta				&& argv[optind][0] != '!') {
1429b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta				rulenum = parse_rulenumber(argv[optind++]);
1430b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta				command = CMD_ZERO_NUM;
1431b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta			}
14325eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
14335eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14345eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'N':
14358d8c8ea5a6150694e7d6fdabd094de15d01bd74bYasuyuki KOZAKAI			if (optarg && (*optarg == '-' || *optarg == '!'))
14361829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
143708f1527fbcebc85f7149e551c9b26f526954b3c2Joszef Kadlecsik					   "chain name not allowed to start "
14388d8c8ea5a6150694e7d6fdabd094de15d01bd74bYasuyuki KOZAKAI					   "with `%c'\n", *optarg);
14392338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt			if (xtables_find_target(optarg, XTF_TRY_LOAD))
14401829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
144108f1527fbcebc85f7149e551c9b26f526954b3c2Joszef Kadlecsik					   "chain name may not clash "
144208f1527fbcebc85f7149e551c9b26f526954b3c2Joszef Kadlecsik					   "with target name\n");
14435eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_NEW_CHAIN, CMD_NONE,
14443a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
14455eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
14465eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
14475eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14485eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'X':
14495eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_DELETE_CHAIN, CMD_NONE,
14503a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
14515eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optarg) chain = optarg;
14525eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else if (optind < argc && argv[optind][0] != '-'
14535eed48af2516ebce0412121713d285bc30edb10dRusty Russell				 && argv[optind][0] != '!')
14545eed48af2516ebce0412121713d285bc30edb10dRusty Russell				chain = argv[optind++];
14555eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
14565eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14575eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'E':
14585eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_RENAME_CHAIN, CMD_NONE,
14593a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
14605eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
14615eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optind < argc && argv[optind][0] != '-'
14625eed48af2516ebce0412121713d285bc30edb10dRusty Russell			    && argv[optind][0] != '!')
14635eed48af2516ebce0412121713d285bc30edb10dRusty Russell				newname = argv[optind++];
1464c9f20d3e25a09bee55f32733e9150316f5d5e89fM.P.Anand Babu			else
14651829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
1466950ddc67d1455f908651f53b7df80ed81bee402bYasuyuki KOZAKAI					   "-%c requires old-chain-name and "
1467c9f20d3e25a09bee55f32733e9150316f5d5e89fM.P.Anand Babu					   "new-chain-name",
146843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					    cmd2char(CMD_RENAME_CHAIN));
14695eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
14705eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14715eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'P':
14725eed48af2516ebce0412121713d285bc30edb10dRusty Russell			add_command(&command, CMD_SET_POLICY, CMD_NONE,
14733a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.invert);
14745eed48af2516ebce0412121713d285bc30edb10dRusty Russell			chain = optarg;
14755eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optind < argc && argv[optind][0] != '-'
14765eed48af2516ebce0412121713d285bc30edb10dRusty Russell			    && argv[optind][0] != '!')
14775eed48af2516ebce0412121713d285bc30edb10dRusty Russell				policy = argv[optind++];
14785eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else
14791829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
14805eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   "-%c requires a chain and a policy",
14815eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   cmd2char(CMD_SET_POLICY));
14825eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
14835eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14845eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'h':
14855eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (!optarg)
14865eed48af2516ebce0412121713d285bc30edb10dRusty Russell				optarg = argv[optind];
14875eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14881b91e59339cf782a390329c4f664e3d441eaec6eJonas Berlin			/* ip6tables -p icmp -h */
14893a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			if (!cs.matches && cs.protocol)
14903a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				xtables_find_match(cs.protocol, XTF_TRY_LOAD,
14913a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt					&cs.matches);
14925eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14933a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			exit_printhelp(cs.matches);
14945eed48af2516ebce0412121713d285bc30edb10dRusty Russell
14955eed48af2516ebce0412121713d285bc30edb10dRusty Russell			/*
14965eed48af2516ebce0412121713d285bc30edb10dRusty Russell			 * Option selection
14975eed48af2516ebce0412121713d285bc30edb10dRusty Russell			 */
14985eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'p':
14997a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_PROTOCOL, &cs.fw6.ipv6.invflags,
15003a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
15015eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15025eed48af2516ebce0412121713d285bc30edb10dRusty Russell			/* Canonicalize into lower case */
15033a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			for (cs.protocol = optarg; *cs.protocol; cs.protocol++)
15043a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				*cs.protocol = tolower(*cs.protocol);
15055eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15063a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			cs.protocol = optarg;
15077a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			cs.fw6.ipv6.proto = xtables_parse_protocol(cs.protocol);
15087a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			cs.fw6.ipv6.flags |= IP6T_F_PROTO;
15095eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15107a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			if (cs.fw6.ipv6.proto == 0
151114da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			    && (cs.fw6.ipv6.invflags & XT_INV_PROTO))
15121829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
15135eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   "rule would never match protocol");
15145b76f682f722bebc2f0616fca4600eee2c08dfe2Max Kellermann
15157a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			if (is_exthdr(cs.fw6.ipv6.proto)
151614da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			    && (cs.fw6.ipv6.invflags & XT_INV_PROTO) == 0)
1517aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann				fprintf(stderr,
1518aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann					"Warning: never matched protocol: %s. "
1519aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann					"use extension match instead.\n",
15203a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt					cs.protocol);
15215eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15225eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15235eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 's':
15247a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_SOURCE, &cs.fw6.ipv6.invflags,
15253a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
1526bbe83862a5e1baf15f7c923352d4afdf59bc70e2Jan Engelhardt			shostnetworkmask = optarg;
15275eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15285eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15295eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'd':
15307a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_DESTINATION, &cs.fw6.ipv6.invflags,
15313a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
1532bbe83862a5e1baf15f7c923352d4afdf59bc70e2Jan Engelhardt			dhostnetworkmask = optarg;
15335eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15345eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1535eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#ifdef IP6T_F_GOTO
1536eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob		case 'g':
15377a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_JUMP, &cs.fw6.ipv6.invflags,
15383a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt					cs.invert);
15397a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			cs.fw6.ipv6.flags |= IP6T_F_GOTO;
15409bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt			cs.jumpto = parse_target(optarg);
1541eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob			break;
1542eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#endif
1543eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob
15445eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'j':
15459bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt			command_jump(&cs);
15465eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15475eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15485eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15495eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'i':
15505b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt			if (*optarg == '\0')
15515b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt				xtables_error(PARAMETER_PROBLEM,
15525b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt					"Empty interface is likely to be "
15535b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt					"undesired");
15547a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_VIANAMEIN, &cs.fw6.ipv6.invflags,
15553a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
1556bbe83862a5e1baf15f7c923352d4afdf59bc70e2Jan Engelhardt			xtables_parse_interface(optarg,
15577a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt					cs.fw6.ipv6.iniface,
15587a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt					cs.fw6.ipv6.iniface_mask);
15595eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15605eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15615eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'o':
15625b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt			if (*optarg == '\0')
15635b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt				xtables_error(PARAMETER_PROBLEM,
15645b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt					"Empty interface is likely to be "
15655b1fecc7d017df093db7c667bcd1718e45b1df67Jan Engelhardt					"undesired");
15667a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_VIANAMEOUT, &cs.fw6.ipv6.invflags,
15673a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
1568bbe83862a5e1baf15f7c923352d4afdf59bc70e2Jan Engelhardt			xtables_parse_interface(optarg,
15697a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt					cs.fw6.ipv6.outiface,
15707a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt					cs.fw6.ipv6.outiface_mask);
15715eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15725eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15735eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'v':
15745eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (!verbose)
15753a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				set_option(&cs.options, OPT_VERBOSE,
15767a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt					   &cs.fw6.ipv6.invflags, cs.invert);
15775eed48af2516ebce0412121713d285bc30edb10dRusty Russell			verbose++;
15785eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15795eed48af2516ebce0412121713d285bc30edb10dRusty Russell
158093587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester		case 'w':
1581d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso			if (restore) {
1582d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso				xtables_error(PARAMETER_PROBLEM,
1583d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso					      "You cannot use `-w' from "
1584d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso					      "ip6tables-restore");
1585d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso			}
158693587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester			wait = true;
158793587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester			break;
158893587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester
158917e310b2610448605567644f667c79f41d76f51eJan Engelhardt		case 'm':
159017e310b2610448605567644f667c79f41d76f51eJan Engelhardt			command_match(&cs);
159117e310b2610448605567644f667c79f41d76f51eJan Engelhardt			break;
15925eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15935eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'n':
15947a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_NUMERIC, &cs.fw6.ipv6.invflags,
15953a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
15965eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
15975eed48af2516ebce0412121713d285bc30edb10dRusty Russell
15985eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 't':
15993a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			if (cs.invert)
16001829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
16015eed48af2516ebce0412121713d285bc30edb10dRusty Russell					   "unexpected ! flag before --table");
1602d0cbf5f34d3421064eb0fbbcdc6b90cda4e81f2dJan Engelhardt			*table = optarg;
16035eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
16045eed48af2516ebce0412121713d285bc30edb10dRusty Russell
16055eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'x':
16067a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_EXPANDED, &cs.fw6.ipv6.invflags,
16073a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
16085eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
16095eed48af2516ebce0412121713d285bc30edb10dRusty Russell
16105eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 'V':
16113a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			if (cs.invert)
16125dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim				printf("Not %s ;-)\n", prog_vers);
16135eed48af2516ebce0412121713d285bc30edb10dRusty Russell			else
16145eed48af2516ebce0412121713d285bc30edb10dRusty Russell				printf("%s v%s\n",
16155dd19de34380c91ad07bbe79a34726e59891cf54Jamal Hadi Salim				       prog_name, prog_vers);
16165eed48af2516ebce0412121713d285bc30edb10dRusty Russell			exit(0);
16175eed48af2516ebce0412121713d285bc30edb10dRusty Russell
16185eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case '0':
16197a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_LINENUMBERS, &cs.fw6.ipv6.invflags,
16203a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
16215eed48af2516ebce0412121713d285bc30edb10dRusty Russell			break;
16225eed48af2516ebce0412121713d285bc30edb10dRusty Russell
162343ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		case 'M':
1624c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt			xtables_modprobe_program = optarg;
162543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			break;
162643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
162743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		case 'c':
162843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
16297a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			set_option(&cs.options, OPT_COUNTERS, &cs.fw6.ipv6.invflags,
16303a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.invert);
163143ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			pcnt = optarg;
163260a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			bcnt = strchr(pcnt + 1, ',');
163360a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			if (bcnt)
163460a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			    bcnt++;
163560a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			if (!bcnt && optind < argc && argv[optind][0] != '-'
163643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			    && argv[optind][0] != '!')
163743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte				bcnt = argv[optind++];
163860a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			if (!bcnt)
16391829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
164043ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					"-%c requires packet and byte counter",
164143ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					opt2char(OPT_COUNTERS));
164243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
164360a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			if (sscanf(pcnt, "%llu", &cnt) != 1)
16441829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
164543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					"-%c packet counter not numeric",
164643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					opt2char(OPT_COUNTERS));
16477a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			cs.fw6.counters.pcnt = cnt;
164843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
164960a6073690a456770bf18d190beb57e8f2c8759fHenrik Nordstrom			if (sscanf(bcnt, "%llu", &cnt) != 1)
16501829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
165143ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					"-%c byte counter not numeric",
165243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					opt2char(OPT_COUNTERS));
16537a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			cs.fw6.counters.bcnt = cnt;
165443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			break;
165543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
165657664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski		case '4':
165757664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski			/* This is not the IPv4 iptables */
165857664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski			if (line != -1)
165957664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski				return 1; /* success: line ignored */
166057664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski			fprintf(stderr, "This is the IPv6 version of ip6tables.\n");
166157664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski			exit_tryhelp(2);
166257664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski
166357664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski		case '6':
166457664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski			/* This is indeed the IPv6 ip6tables */
166557664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski			break;
166657664121bce6d3ae05a186c7627c919fb0799649Maciej Żenczykowski
16675eed48af2516ebce0412121713d285bc30edb10dRusty Russell		case 1: /* non option */
16685eed48af2516ebce0412121713d285bc30edb10dRusty Russell			if (optarg[0] == '!' && optarg[1] == '\0') {
16693a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				if (cs.invert)
16701829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt					xtables_error(PARAMETER_PROBLEM,
16715eed48af2516ebce0412121713d285bc30edb10dRusty Russell						   "multiple consecutive ! not"
16725eed48af2516ebce0412121713d285bc30edb10dRusty Russell						   " allowed");
16733a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				cs.invert = TRUE;
16745eed48af2516ebce0412121713d285bc30edb10dRusty Russell				optarg[0] = '\0';
16755eed48af2516ebce0412121713d285bc30edb10dRusty Russell				continue;
16765eed48af2516ebce0412121713d285bc30edb10dRusty Russell			}
1677aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann			fprintf(stderr, "Bad argument `%s'\n", optarg);
16785eed48af2516ebce0412121713d285bc30edb10dRusty Russell			exit_tryhelp(2);
16795eed48af2516ebce0412121713d285bc30edb10dRusty Russell
16805eed48af2516ebce0412121713d285bc30edb10dRusty Russell		default:
1681780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt			if (command_default(&cs, &ip6tables_globals) == 1)
1682780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt				/*
1683780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt				 * If new options were loaded, we must retry
1684780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt				 * getopt immediately and not allow
1685780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt				 * cs.invert=FALSE to be executed.
1686780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt				 */
1687780607f8b040a47cd2d4775376e2d30f567dc049Jan Engelhardt				continue;
1688f935ae05040d2d790433abee49ef79f4a8ed393cJan Engelhardt			break;
16895eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
16903a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		cs.invert = FALSE;
16915eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
16925eed48af2516ebce0412121713d285bc30edb10dRusty Russell
16933a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	for (matchp = cs.matches; matchp; matchp = matchp->next)
16943af739b0e7c3b6dcc986645c57c982d0add5006bJan Engelhardt		xtables_option_mfcall(matchp->match);
16953af739b0e7c3b6dcc986645c57c982d0add5006bJan Engelhardt	if (cs.target != NULL)
16963af739b0e7c3b6dcc986645c57c982d0add5006bJan Engelhardt		xtables_option_tfcall(cs.target);
16975eed48af2516ebce0412121713d285bc30edb10dRusty Russell
16985eed48af2516ebce0412121713d285bc30edb10dRusty Russell	/* Fix me: must put inverse options checking here --MN */
16995eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17005eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (optind < argc)
17011829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
17025eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   "unknown arguments found on commandline");
17035eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (!command)
17041829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "no command specified");
17053a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	if (cs.invert)
17061829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
17075eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   "nothing appropriate following !");
17085eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1709d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	if (command & (CMD_REPLACE | CMD_INSERT | CMD_DELETE | CMD_APPEND | CMD_CHECK)) {
17103a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		if (!(cs.options & OPT_DESTINATION))
1711764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó			dhostnetworkmask = "::0/0";
17123a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		if (!(cs.options & OPT_SOURCE))
1713764316a133db8e5e2d1f2a9d941ffae993d7c9d9András Kis-Szabó			shostnetworkmask = "::0/0";
17145eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
17155eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17165eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (shostnetworkmask)
1717332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow		xtables_ip6parse_multiple(shostnetworkmask, &saddrs,
1718332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow					  &smasks, &nsaddrs);
17195eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17205eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (dhostnetworkmask)
1721332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow		xtables_ip6parse_multiple(dhostnetworkmask, &daddrs,
1722332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow					  &dmasks, &ndaddrs);
17235eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17245eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if ((nsaddrs > 1 || ndaddrs > 1) &&
17257a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt	    (cs.fw6.ipv6.invflags & (IP6T_INV_SRCIP | IP6T_INV_DSTIP)))
17261829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "! not allowed with multiple"
17275eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   " source or destination IP addresses");
17285eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17295eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (command == CMD_REPLACE && (nsaddrs != 1 || ndaddrs != 1))
17301829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM, "Replacement rule does not "
17315eed48af2516ebce0412121713d285bc30edb10dRusty Russell			   "specify a unique address");
17325eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17333a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt	generic_opt_check(command, cs.options);
17345eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17355429b41c2bb4ac8fe672a1513a041c0ed0c241f6Jan Engelhardt	if (chain != NULL && strlen(chain) >= XT_EXTENSION_MAXNAMELEN)
17361829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(PARAMETER_PROBLEM,
17375429b41c2bb4ac8fe672a1513a041c0ed0c241f6Jan Engelhardt			   "chain name `%s' too long (must be under %u chars)",
17385429b41c2bb4ac8fe672a1513a041c0ed0c241f6Jan Engelhardt			   chain, XT_EXTENSION_MAXNAMELEN);
17395eed48af2516ebce0412121713d285bc30edb10dRusty Russell
174093587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester	/* Attempt to acquire the xtables lock */
1741d7aeda5ed45ac7ca959f12180690caa371b5b14bPablo Neira Ayuso	if (!restore && !xtables_lock(wait)) {
174293587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester		fprintf(stderr, "Another app is currently holding the xtables lock. "
174393587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester			"Perhaps you want to use the -w option?\n");
174493587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester		xtables_free_opts(1);
174593587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester		exit(RESOURCE_PROBLEM);
174693587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester	}
174793587a04d0f2511e108bbc4d87a8b9d28a5c5dd8Phil Oester
174843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte	/* only allocate handle if we weren't called with a handle */
17498371e15a49d422755fbd185ab8415b9b12ec9d9aMartin Josefsson	if (!*handle)
175043ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		*handle = ip6tc_init(*table);
17513aa6287c97ec8c2d706c498a793942161ac4ccd3András Kis-Szabó
17528beb0492c84dbec73febce36559ff244f77ec08eRusty Russell	/* try to insmod the module if iptc_init failed */
1753c021c3ce7b1583eb5dd71b10ac3d8ab3cd36beaaJan Engelhardt	if (!*handle && xtables_load_ko(xtables_modprobe_program, false) != -1)
175443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		*handle = ip6tc_init(*table);
17558a5eb6dd67e5fac875da51742d9a954c0ff5d92fFabrice MARIE
175643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte	if (!*handle)
17571829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt		xtables_error(VERSION_PROBLEM,
175843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			"can't initialize ip6tables table `%s': %s",
175943ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			*table, ip6tc_strerror(errno));
17605eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17610c4188f446e7c0ed07076c69d1d7f336a92efc8bAndrás Kis-Szabó	if (command == CMD_APPEND
17625eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    || command == CMD_DELETE
1763d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	    || command == CMD_CHECK
17645eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    || command == CMD_INSERT
17655eed48af2516ebce0412121713d285bc30edb10dRusty Russell	    || command == CMD_REPLACE) {
176643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		if (strcmp(chain, "PREROUTING") == 0
176743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		    || strcmp(chain, "INPUT") == 0) {
176843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			/* -o not valid with incoming packets. */
17693a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			if (cs.options & OPT_VIANAMEOUT)
17701829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
177143ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					   "Can't use -%c with %s\n",
177243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					   opt2char(OPT_VIANAMEOUT),
177343ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					   chain);
177443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		}
177543ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte
177643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		if (strcmp(chain, "POSTROUTING") == 0
177743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		    || strcmp(chain, "OUTPUT") == 0) {
177843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			/* -i not valid with outgoing packets */
17793a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			if (cs.options & OPT_VIANAMEIN)
17801829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
178143ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					   "Can't use -%c with %s\n",
178243ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					   opt2char(OPT_VIANAMEIN),
178343ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte					   chain);
178443ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte		}
17855eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17869bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt		if (cs.target && ip6tc_is_chain(cs.jumpto, *handle)) {
1787aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann			fprintf(stderr,
1788aae4f82eb83d923f59a328d6e13396f424be28f9Max Kellermann				"Warning: using chain %s, not extension\n",
17899bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt				cs.jumpto);
17905eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17913a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			if (cs.target->t)
17923a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				free(cs.target->t);
17934dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson
17943a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			cs.target = NULL;
17955eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
17965eed48af2516ebce0412121713d285bc30edb10dRusty Russell
17975eed48af2516ebce0412121713d285bc30edb10dRusty Russell		/* If they didn't specify a target, or it's a chain
17985eed48af2516ebce0412121713d285bc30edb10dRusty Russell		   name, use standard. */
17993a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		if (!cs.target
18009bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt		    && (strlen(cs.jumpto) == 0
18019bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt			|| ip6tc_is_chain(cs.jumpto, *handle))) {
18025eed48af2516ebce0412121713d285bc30edb10dRusty Russell			size_t size;
18035eed48af2516ebce0412121713d285bc30edb10dRusty Russell
180414da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			cs.target = xtables_find_target(XT_STANDARD_TARGET,
18052338efd8f799d8373dc196c797bda9690283b698Jan Engelhardt					XTF_LOAD_MUST_SUCCEED);
18065eed48af2516ebce0412121713d285bc30edb10dRusty Russell
180714da56743c6cdf25da35b7b5ca7a5d201771990dJan Engelhardt			size = sizeof(struct xt_entry_target)
18083a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				+ cs.target->size;
18093a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			cs.target->t = xtables_calloc(1, size);
18103a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			cs.target->t->u.target_size = size;
18119bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt			strcpy(cs.target->t->u.user.name, cs.jumpto);
181214190986f87301b18bcc473c842bd82d778d87a2Jan Engelhardt			xs_init_target(cs.target);
18135eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
18145eed48af2516ebce0412121713d285bc30edb10dRusty Russell
18153a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		if (!cs.target) {
181643ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			/* it is no chain, and we can't load a plugin.
181743ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			 * We cannot know if the plugin is corrupt, non
181843ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			 * existant OR if the user just misspelled a
181943ac191de3ef1451b05ebe8e2339f3226ee88bf5Harald Welte			 * chain. */
1820eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#ifdef IP6T_F_GOTO
18217a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			if (cs.fw6.ipv6.flags & IP6T_F_GOTO)
18221829ed482efbc8b390cc760d012b3a4450494e1aJan Engelhardt				xtables_error(PARAMETER_PROBLEM,
18239bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt						"goto '%s' is not a chain\n",
18249bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt						cs.jumpto);
1825eaf831efecf936cab9a30f67284de7def4325545Thomas Jacob#endif
18269bb76094b26d22c7a85d98a075640f054b7910f4Jan Engelhardt			xtables_find_target(cs.jumpto, XTF_LOAD_MUST_SUCCEED);
18275eed48af2516ebce0412121713d285bc30edb10dRusty Russell		} else {
18287a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt			e = generate_entry(&cs.fw6, cs.matches, cs.target->t);
18293a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt			free(cs.target->t);
18305eed48af2516ebce0412121713d285bc30edb10dRusty Russell		}
18315eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
18325eed48af2516ebce0412121713d285bc30edb10dRusty Russell
18335eed48af2516ebce0412121713d285bc30edb10dRusty Russell	switch (command) {
18345eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_APPEND:
18355eed48af2516ebce0412121713d285bc30edb10dRusty Russell		ret = append_entry(chain, e,
1836332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow				   nsaddrs, saddrs, smasks,
1837332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow				   ndaddrs, daddrs, dmasks,
18383a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_VERBOSE,
18391c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				   *handle);
18405eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
18415eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_DELETE:
18425eed48af2516ebce0412121713d285bc30edb10dRusty Russell		ret = delete_entry(chain, e,
1843332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow				   nsaddrs, saddrs, smasks,
1844332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow				   ndaddrs, daddrs, dmasks,
18453a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_VERBOSE,
18463a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   *handle, cs.matches, cs.target);
18475eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
18485eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_DELETE_NUM:
18491c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt		ret = ip6tc_delete_num_entry(chain, rulenum - 1, *handle);
18505eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
1851d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek	case CMD_CHECK:
1852d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		ret = check_entry(chain, e,
1853d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek				   nsaddrs, saddrs, smasks,
1854d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek				   ndaddrs, daddrs, dmasks,
1855d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek				   cs.options&OPT_VERBOSE,
1856d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek				   *handle, cs.matches, cs.target);
1857d59b9db031abee37a9aa9776662dd15370faabf4Stefan Tomanek		break;
18585eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_REPLACE:
18595eed48af2516ebce0412121713d285bc30edb10dRusty Russell		ret = replace_entry(chain, e, rulenum - 1,
186075cb763b54a89bf9b9c61740c760abce89df06f3Jan Engelhardt				    saddrs, smasks, daddrs, dmasks,
18613a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				    cs.options&OPT_VERBOSE, *handle);
18625eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
18635eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_INSERT:
18645eed48af2516ebce0412121713d285bc30edb10dRusty Russell		ret = insert_entry(chain, e, rulenum - 1,
1865332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow				   nsaddrs, saddrs, smasks,
1866332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow				   ndaddrs, daddrs, dmasks,
18673a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_VERBOSE,
18681c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				   *handle);
18695eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
18705eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_FLUSH:
187174ace0a46048d01611a44c24f6fe5f59d936231bMaciej Zenczykowski		ret = flush_entries6(chain, cs.options&OPT_VERBOSE, *handle);
18725eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
18735eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_ZERO:
18743a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt		ret = zero_entries(chain, cs.options&OPT_VERBOSE, *handle);
18755eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
1876b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta	case CMD_ZERO_NUM:
1877b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta		ret = ip6tc_zero_counter(chain, rulenum, *handle);
1878b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta		break;
187996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	case CMD_LIST:
18805eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_LIST|CMD_ZERO:
1881b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta	case CMD_LIST|CMD_ZERO_NUM:
18825eed48af2516ebce0412121713d285bc30edb10dRusty Russell		ret = list_entries(chain,
1883bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom				   rulenum,
18843a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_VERBOSE,
18853a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_NUMERIC,
18863a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_EXPANDED,
18873a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_LINENUMBERS,
18881c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				   *handle);
188996296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (ret && (command & CMD_ZERO))
189096296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom			ret = zero_entries(chain,
18913a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt					   cs.options&OPT_VERBOSE, *handle);
1892b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta		if (ret && (command & CMD_ZERO_NUM))
1893b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta			ret = ip6tc_zero_counter(chain, rulenum, *handle);
189496296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		break;
189596296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	case CMD_LIST_RULES:
189696296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom	case CMD_LIST_RULES|CMD_ZERO:
1897b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta	case CMD_LIST_RULES|CMD_ZERO_NUM:
189896296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		ret = list_rules(chain,
1899bb34082de25ec7fb6bffe5702062f087ca887466Henrik Nordstrom				   rulenum,
19003a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt				   cs.options&OPT_VERBOSE,
19011c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt				   *handle);
190296296cfb7e01298234c7fa9403619f50391620d1Henrik Nordstrom		if (ret && (command & CMD_ZERO))
19035eed48af2516ebce0412121713d285bc30edb10dRusty Russell			ret = zero_entries(chain,
19043a9d8b0bcaeeb7f260c881fbaaea62f705d0d47eJan Engelhardt					   cs.options&OPT_VERBOSE, *handle);
1905b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta		if (ret && (command & CMD_ZERO_NUM))
1906b34199ee303d98ba00ed5ee19d4d5b19dd4cf563Mohit Mehta			ret = ip6tc_zero_counter(chain, rulenum, *handle);
19075eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
19085eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_NEW_CHAIN:
19091c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt		ret = ip6tc_create_chain(chain, *handle);
19105eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
19115eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_DELETE_CHAIN:
191285aae15567b8ae1eaedf9f011ba7aef80dfca208Maciej Zenczykowski		ret = delete_chain6(chain, cs.options&OPT_VERBOSE, *handle);
19135eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
19145eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_RENAME_CHAIN:
19151c9015b2cb483678f153121255e10ec0bbfde3e6Jan Engelhardt		ret = ip6tc_rename_chain(chain, newname,	*handle);
19165eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
19175eed48af2516ebce0412121713d285bc30edb10dRusty Russell	case CMD_SET_POLICY:
19187a548b32d9ad8d6e4a8398573d4fa8c4e4a1f9e0Jan Engelhardt		ret = ip6tc_set_policy(chain, policy, cs.options&OPT_COUNTERS ? &cs.fw6.counters : NULL, *handle);
19195eed48af2516ebce0412121713d285bc30edb10dRusty Russell		break;
19205eed48af2516ebce0412121713d285bc30edb10dRusty Russell	default:
19215eed48af2516ebce0412121713d285bc30edb10dRusty Russell		/* We should never reach this... */
19225eed48af2516ebce0412121713d285bc30edb10dRusty Russell		exit_tryhelp(2);
19235eed48af2516ebce0412121713d285bc30edb10dRusty Russell	}
19245eed48af2516ebce0412121713d285bc30edb10dRusty Russell
19255eed48af2516ebce0412121713d285bc30edb10dRusty Russell	if (verbose > 1)
19265eed48af2516ebce0412121713d285bc30edb10dRusty Russell		dump_entries6(*handle);
19275eed48af2516ebce0412121713d285bc30edb10dRusty Russell
1928d1e7922a587a239e16e0dbe654e63f76e1375e49Pablo Neira Ayuso	xtables_rule_matches_free(&cs.matches);
192969ac0e086c7b90e82cec369570ca363201023bdeMartin Josefsson
19304dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson	if (e != NULL) {
19314dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson		free(e);
19324dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson		e = NULL;
19334dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson	}
19344dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson
1935332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	free(saddrs);
1936332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	free(smasks);
1937332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	free(daddrs);
1938332e4acc574e3a348fe611d55bf642de0d50fbdaMichael Granzow	free(dmasks);
1939139b3fe4bd5121501e60fe07963ea527d7f0bd36Jamal Hadi Salim	xtables_free_opts(1);
19404dd5fedadee415a646bc0e70d0b17668897ede63Martin Josefsson
19415eed48af2516ebce0412121713d285bc30edb10dRusty Russell	return ret;
19425eed48af2516ebce0412121713d285bc30edb10dRusty Russell}
1943