1 /* Code to take an iptables-style command line and do it. */
4 * Author: Paul.Russell@rustcorp.com.au and mneuling@radlogic.com.au
6 * (C) 2000-2002 by the netfilter coreteam <coreteam@netfilter.org>:
7 * Paul 'Rusty' Russell <rusty@rustcorp.com.au>
8 * Marc Boucher <marc+nf@mbsi.ca>
9 * James Morris <jmorris@intercode.com.au>
10 * Harald Welte <laforge@gnumonks.org>
11 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
44 static const char unsupported_rev
[] = " [unsupported revision]";
46 static struct option original_opts
[] = {
47 {.name
= "append", .has_arg
= 1, .val
= 'A'},
48 {.name
= "delete", .has_arg
= 1, .val
= 'D'},
49 {.name
= "check", .has_arg
= 1, .val
= 'C'},
50 {.name
= "insert", .has_arg
= 1, .val
= 'I'},
51 {.name
= "replace", .has_arg
= 1, .val
= 'R'},
52 {.name
= "list", .has_arg
= 2, .val
= 'L'},
53 {.name
= "list-rules", .has_arg
= 2, .val
= 'S'},
54 {.name
= "flush", .has_arg
= 2, .val
= 'F'},
55 {.name
= "zero", .has_arg
= 2, .val
= 'Z'},
56 {.name
= "new-chain", .has_arg
= 1, .val
= 'N'},
57 {.name
= "delete-chain", .has_arg
= 2, .val
= 'X'},
58 {.name
= "rename-chain", .has_arg
= 1, .val
= 'E'},
59 {.name
= "policy", .has_arg
= 1, .val
= 'P'},
60 {.name
= "source", .has_arg
= 1, .val
= 's'},
61 {.name
= "destination", .has_arg
= 1, .val
= 'd'},
62 {.name
= "src", .has_arg
= 1, .val
= 's'}, /* synonym */
63 {.name
= "dst", .has_arg
= 1, .val
= 'd'}, /* synonym */
64 {.name
= "protocol", .has_arg
= 1, .val
= 'p'},
65 {.name
= "in-interface", .has_arg
= 1, .val
= 'i'},
66 {.name
= "jump", .has_arg
= 1, .val
= 'j'},
67 {.name
= "table", .has_arg
= 1, .val
= 't'},
68 {.name
= "match", .has_arg
= 1, .val
= 'm'},
69 {.name
= "numeric", .has_arg
= 0, .val
= 'n'},
70 {.name
= "out-interface", .has_arg
= 1, .val
= 'o'},
71 {.name
= "verbose", .has_arg
= 0, .val
= 'v'},
72 {.name
= "wait", .has_arg
= 2, .val
= 'w'},
73 {.name
= "wait-interval", .has_arg
= 2, .val
= 'W'},
74 {.name
= "exact", .has_arg
= 0, .val
= 'x'},
75 {.name
= "fragments", .has_arg
= 0, .val
= 'f'},
76 {.name
= "version", .has_arg
= 0, .val
= 'V'},
77 {.name
= "help", .has_arg
= 2, .val
= 'h'},
78 {.name
= "line-numbers", .has_arg
= 0, .val
= '0'},
79 {.name
= "modprobe", .has_arg
= 1, .val
= 'M'},
80 {.name
= "set-counters", .has_arg
= 1, .val
= 'c'},
81 {.name
= "goto", .has_arg
= 1, .val
= 'g'},
82 {.name
= "ipv4", .has_arg
= 0, .val
= '4'},
83 {.name
= "ipv6", .has_arg
= 0, .val
= '6'},
87 struct xtables_globals iptables_globals
= {
89 .program_version
= PACKAGE_VERSION
" (legacy)",
90 .orig_opts
= original_opts
,
91 .compat_rev
= xtables_compatible_revision
,
95 * All functions starting with "parse" should succeed, otherwise
97 * Most routines return pointers to static data that may change
98 * between calls to the same or other routines with a few exceptions:
99 * "host_to_addr", "parse_hostnetwork", and "parse_hostnetworkmask"
100 * return global static data.
103 /* Christophe Burki wants `-p 6' to imply `-m tcp'. */
107 print_match(const struct xt_entry_match
*m
,
108 const struct ipt_ip
*ip
,
111 const char *name
= m
->u
.user
.name
;
112 const int revision
= m
->u
.user
.revision
;
113 struct xtables_match
*match
, *mt
;
115 match
= xtables_find_match(name
, XTF_TRY_LOAD
, NULL
);
117 mt
= xtables_find_match_revision(name
, XTF_TRY_LOAD
,
120 mt
->print(ip
, m
, numeric
);
121 else if (match
->print
)
122 printf("%s%s ", match
->name
, unsupported_rev
);
124 printf("%s ", match
->name
);
126 if (match
->next
== match
)
130 printf("UNKNOWN match `%s' ", name
);
132 /* Don't stop iterating. */
136 /* e is called `fw' here for historical reasons */
138 print_firewall(const struct ipt_entry
*fw
,
139 const char *targname
,
142 struct xtc_handle
*const handle
)
144 struct xtables_target
*target
, *tg
;
145 const struct xt_entry_target
*t
;
147 if (!iptc_is_chain(targname
, handle
))
148 target
= xtables_find_target(targname
, XTF_TRY_LOAD
);
150 target
= xtables_find_target(XT_STANDARD_TARGET
,
151 XTF_LOAD_MUST_SUCCEED
);
153 t
= ipt_get_target((struct ipt_entry
*)fw
);
155 print_rule_details(num
, &fw
->counters
, targname
, fw
->ip
.proto
,
156 fw
->ip
.flags
, fw
->ip
.invflags
, format
);
158 print_fragment(fw
->ip
.flags
, fw
->ip
.invflags
, format
, false);
160 print_ifaces(fw
->ip
.iniface
, fw
->ip
.outiface
, fw
->ip
.invflags
, format
);
162 print_ipv4_addresses(fw
, format
);
164 if (format
& FMT_NOTABLE
)
168 if(fw
->ip
.flags
& IPT_F_GOTO
)
172 IPT_MATCH_ITERATE(fw
, print_match
, &fw
->ip
, format
& FMT_NUMERIC
);
175 const int revision
= t
->u
.user
.revision
;
177 tg
= xtables_find_target_revision(targname
, XTF_TRY_LOAD
,
180 /* Print the target information. */
181 tg
->print(&fw
->ip
, t
, format
& FMT_NUMERIC
);
182 else if (target
->print
)
183 printf(" %s%s", target
->name
, unsupported_rev
);
185 if (target
->next
== target
)
187 } else if (t
->u
.target_size
!= sizeof(*t
))
188 printf("[%u bytes of unknown target data] ",
189 (unsigned int)(t
->u
.target_size
- sizeof(*t
)));
191 if (!(format
& FMT_NONEWLINE
))
196 print_firewall_line(const struct ipt_entry
*fw
,
197 struct xtc_handle
*const h
)
199 struct xt_entry_target
*t
;
201 t
= ipt_get_target((struct ipt_entry
*)fw
);
202 print_firewall(fw
, t
->u
.user
.name
, 0, FMT_PRINT_RULE
, h
);
206 append_entry(const xt_chainlabel chain
,
207 struct ipt_entry
*fw
,
208 unsigned int nsaddrs
,
209 const struct in_addr saddrs
[],
210 const struct in_addr smasks
[],
211 unsigned int ndaddrs
,
212 const struct in_addr daddrs
[],
213 const struct in_addr dmasks
[],
215 struct xtc_handle
*handle
)
220 for (i
= 0; i
< nsaddrs
; i
++) {
221 fw
->ip
.src
.s_addr
= saddrs
[i
].s_addr
;
222 fw
->ip
.smsk
.s_addr
= smasks
[i
].s_addr
;
223 for (j
= 0; j
< ndaddrs
; j
++) {
224 fw
->ip
.dst
.s_addr
= daddrs
[j
].s_addr
;
225 fw
->ip
.dmsk
.s_addr
= dmasks
[j
].s_addr
;
227 print_firewall_line(fw
, handle
);
228 ret
&= iptc_append_entry(chain
, fw
, handle
);
236 replace_entry(const xt_chainlabel chain
,
237 struct ipt_entry
*fw
,
238 unsigned int rulenum
,
239 const struct in_addr
*saddr
, const struct in_addr
*smask
,
240 const struct in_addr
*daddr
, const struct in_addr
*dmask
,
242 struct xtc_handle
*handle
)
244 fw
->ip
.src
.s_addr
= saddr
->s_addr
;
245 fw
->ip
.dst
.s_addr
= daddr
->s_addr
;
246 fw
->ip
.smsk
.s_addr
= smask
->s_addr
;
247 fw
->ip
.dmsk
.s_addr
= dmask
->s_addr
;
250 print_firewall_line(fw
, handle
);
251 return iptc_replace_entry(chain
, fw
, rulenum
, handle
);
255 insert_entry(const xt_chainlabel chain
,
256 struct ipt_entry
*fw
,
257 unsigned int rulenum
,
258 unsigned int nsaddrs
,
259 const struct in_addr saddrs
[],
260 const struct in_addr smasks
[],
261 unsigned int ndaddrs
,
262 const struct in_addr daddrs
[],
263 const struct in_addr dmasks
[],
265 struct xtc_handle
*handle
)
270 for (i
= 0; i
< nsaddrs
; i
++) {
271 fw
->ip
.src
.s_addr
= saddrs
[i
].s_addr
;
272 fw
->ip
.smsk
.s_addr
= smasks
[i
].s_addr
;
273 for (j
= 0; j
< ndaddrs
; j
++) {
274 fw
->ip
.dst
.s_addr
= daddrs
[j
].s_addr
;
275 fw
->ip
.dmsk
.s_addr
= dmasks
[j
].s_addr
;
277 print_firewall_line(fw
, handle
);
278 ret
&= iptc_insert_entry(chain
, fw
, rulenum
, handle
);
286 delete_entry(const xt_chainlabel chain
,
287 struct ipt_entry
*fw
,
288 unsigned int nsaddrs
,
289 const struct in_addr saddrs
[],
290 const struct in_addr smasks
[],
291 unsigned int ndaddrs
,
292 const struct in_addr daddrs
[],
293 const struct in_addr dmasks
[],
295 struct xtc_handle
*handle
,
296 struct xtables_rule_match
*matches
,
297 const struct xtables_target
*target
)
303 mask
= make_delete_mask(matches
, target
, sizeof(*fw
));
304 for (i
= 0; i
< nsaddrs
; i
++) {
305 fw
->ip
.src
.s_addr
= saddrs
[i
].s_addr
;
306 fw
->ip
.smsk
.s_addr
= smasks
[i
].s_addr
;
307 for (j
= 0; j
< ndaddrs
; j
++) {
308 fw
->ip
.dst
.s_addr
= daddrs
[j
].s_addr
;
309 fw
->ip
.dmsk
.s_addr
= dmasks
[j
].s_addr
;
311 print_firewall_line(fw
, handle
);
312 ret
&= iptc_delete_entry(chain
, fw
, mask
, handle
);
321 check_entry(const xt_chainlabel chain
, struct ipt_entry
*fw
,
322 unsigned int nsaddrs
, const struct in_addr
*saddrs
,
323 const struct in_addr
*smasks
, unsigned int ndaddrs
,
324 const struct in_addr
*daddrs
, const struct in_addr
*dmasks
,
325 bool verbose
, struct xtc_handle
*handle
,
326 struct xtables_rule_match
*matches
,
327 const struct xtables_target
*target
)
333 mask
= make_delete_mask(matches
, target
, sizeof(*fw
));
334 for (i
= 0; i
< nsaddrs
; i
++) {
335 fw
->ip
.src
.s_addr
= saddrs
[i
].s_addr
;
336 fw
->ip
.smsk
.s_addr
= smasks
[i
].s_addr
;
337 for (j
= 0; j
< ndaddrs
; j
++) {
338 fw
->ip
.dst
.s_addr
= daddrs
[j
].s_addr
;
339 fw
->ip
.dmsk
.s_addr
= dmasks
[j
].s_addr
;
341 print_firewall_line(fw
, handle
);
342 ret
&= iptc_check_entry(chain
, fw
, mask
, handle
);
351 for_each_chain4(int (*fn
)(const xt_chainlabel
, int, struct xtc_handle
*),
352 int verbose
, int builtinstoo
, struct xtc_handle
*handle
)
357 unsigned int i
, chaincount
= 0;
359 chain
= iptc_first_chain(handle
);
362 chain
= iptc_next_chain(handle
);
365 chains
= xtables_malloc(sizeof(xt_chainlabel
) * chaincount
);
367 chain
= iptc_first_chain(handle
);
369 strcpy(chains
+ i
*sizeof(xt_chainlabel
), chain
);
371 chain
= iptc_next_chain(handle
);
374 for (i
= 0; i
< chaincount
; i
++) {
376 && iptc_builtin(chains
+ i
*sizeof(xt_chainlabel
),
379 ret
&= fn(chains
+ i
*sizeof(xt_chainlabel
), verbose
, handle
);
387 flush_entries4(const xt_chainlabel chain
, int verbose
,
388 struct xtc_handle
*handle
)
391 return for_each_chain4(flush_entries4
, verbose
, 1, handle
);
394 fprintf(stdout
, "Flushing chain `%s'\n", chain
);
395 return iptc_flush_entries(chain
, handle
);
399 zero_entries(const xt_chainlabel chain
, int verbose
,
400 struct xtc_handle
*handle
)
403 return for_each_chain4(zero_entries
, verbose
, 1, handle
);
406 fprintf(stdout
, "Zeroing chain `%s'\n", chain
);
407 return iptc_zero_entries(chain
, handle
);
411 delete_chain4(const xt_chainlabel chain
, int verbose
,
412 struct xtc_handle
*handle
)
415 return for_each_chain4(delete_chain4
, verbose
, 0, handle
);
418 fprintf(stdout
, "Deleting chain `%s'\n", chain
);
419 return iptc_delete_chain(chain
, handle
);
423 list_entries(const xt_chainlabel chain
, int rulenum
, int verbose
, int numeric
,
424 int expanded
, int linenumbers
, struct xtc_handle
*handle
)
430 format
= FMT_OPTIONS
;
432 format
|= FMT_NOCOUNTS
;
437 format
|= FMT_NUMERIC
;
440 format
|= FMT_KILOMEGAGIGA
;
443 format
|= FMT_LINENUMBERS
;
445 for (this = iptc_first_chain(handle
);
447 this = iptc_next_chain(handle
)) {
448 const struct ipt_entry
*i
;
451 if (chain
&& strcmp(chain
, this) != 0)
454 if (found
) printf("\n");
457 struct xt_counters counters
;
462 pol
= iptc_get_policy(this, &counters
, handle
);
463 if (!pol
&& iptc_get_references(&urefs
, this, handle
))
466 print_header(format
, this, pol
, &counters
, refs
, 0);
468 i
= iptc_first_rule(this, handle
);
473 if (!rulenum
|| num
== rulenum
)
475 iptc_get_target(i
, handle
),
479 i
= iptc_next_rule(i
, handle
);
488 #define IP_PARTS_NATIVE(n) \
489 (unsigned int)((n)>>24)&0xFF, \
490 (unsigned int)((n)>>16)&0xFF, \
491 (unsigned int)((n)>>8)&0xFF, \
492 (unsigned int)((n)&0xFF)
494 #define IP_PARTS(n) IP_PARTS_NATIVE(ntohl(n))
496 /* We want this to be readable, so only print out necessary fields.
497 * Because that's the kind of world I want to live in.
499 void print_rule4(const struct ipt_entry
*e
,
500 struct xtc_handle
*h
, const char *chain
, int counters
)
502 const struct xt_entry_target
*t
;
503 const char *target_name
;
505 /* print counters for iptables-save */
507 printf("[%llu:%llu] ", (unsigned long long)e
->counters
.pcnt
, (unsigned long long)e
->counters
.bcnt
);
509 /* print chain name */
510 printf("-A %s", chain
);
513 save_ipv4_addr('s', &e
->ip
.src
, &e
->ip
.smsk
,
514 e
->ip
.invflags
& IPT_INV_SRCIP
);
516 save_ipv4_addr('d', &e
->ip
.dst
, &e
->ip
.dmsk
,
517 e
->ip
.invflags
& IPT_INV_DSTIP
);
519 save_rule_details(e
->ip
.iniface
, e
->ip
.outiface
,
520 e
->ip
.proto
, e
->ip
.flags
& IPT_F_FRAG
,
523 /* Print matchinfo part */
524 if (e
->target_offset
)
525 IPT_MATCH_ITERATE(e
, print_match_save
, &e
->ip
);
527 /* print counters for iptables -R */
529 printf(" -c %llu %llu", (unsigned long long)e
->counters
.pcnt
, (unsigned long long)e
->counters
.bcnt
);
531 /* Print target name and targinfo part */
532 target_name
= iptc_get_target(e
, h
);
533 t
= ipt_get_target((struct ipt_entry
*)e
);
534 if (t
->u
.user
.name
[0]) {
535 const char *name
= t
->u
.user
.name
;
536 const int revision
= t
->u
.user
.revision
;
537 struct xtables_target
*target
, *tg
, *tg2
;
539 target
= xtables_find_target(name
, XTF_TRY_LOAD
);
541 fprintf(stderr
, "Can't find library for target `%s'\n",
546 tg
= tg2
= xtables_find_target_revision(name
, XTF_TRY_LOAD
,
550 printf(" -j %s", tg2
->alias
? tg2
->alias(t
) : target_name
);
554 else if (target
->save
)
555 printf(unsupported_rev
);
557 /* If the target size is greater than xt_entry_target
558 * there is something to be saved, we just don't know
560 if (t
->u
.target_size
!=
561 sizeof(struct xt_entry_target
)) {
562 fprintf(stderr
, "Target `%s' is missing "
568 } else if (target_name
&& (*target_name
!= '\0'))
570 printf(" -%c %s", e
->ip
.flags
& IPT_F_GOTO
? 'g' : 'j', target_name
);
572 printf(" -j %s", target_name
);
579 list_rules(const xt_chainlabel chain
, int rulenum
, int counters
,
580 struct xtc_handle
*handle
)
582 const char *this = NULL
;
586 counters
= -1; /* iptables -c format */
588 /* Dump out chain names first,
589 * thereby preventing dependency conflicts */
590 if (!rulenum
) for (this = iptc_first_chain(handle
);
592 this = iptc_next_chain(handle
)) {
593 if (chain
&& strcmp(this, chain
) != 0)
596 if (iptc_builtin(this, handle
)) {
597 struct xt_counters count
;
598 printf("-P %s %s", this, iptc_get_policy(this, &count
, handle
));
600 printf(" -c %llu %llu", (unsigned long long)count
.pcnt
, (unsigned long long)count
.bcnt
);
603 printf("-N %s\n", this);
607 for (this = iptc_first_chain(handle
);
609 this = iptc_next_chain(handle
)) {
610 const struct ipt_entry
*e
;
613 if (chain
&& strcmp(this, chain
) != 0)
617 e
= iptc_first_rule(this, handle
);
620 if (!rulenum
|| num
== rulenum
)
621 print_rule4(e
, handle
, this, counters
);
622 e
= iptc_next_rule(e
, handle
);
631 static struct ipt_entry
*
632 generate_entry(const struct ipt_entry
*fw
,
633 struct xtables_rule_match
*matches
,
634 struct xt_entry_target
*target
)
637 struct xtables_rule_match
*matchp
;
640 size
= sizeof(struct ipt_entry
);
641 for (matchp
= matches
; matchp
; matchp
= matchp
->next
)
642 size
+= matchp
->match
->m
->u
.match_size
;
644 e
= xtables_malloc(size
+ target
->u
.target_size
);
646 e
->target_offset
= size
;
647 e
->next_offset
= size
+ target
->u
.target_size
;
650 for (matchp
= matches
; matchp
; matchp
= matchp
->next
) {
651 memcpy(e
->elems
+ size
, matchp
->match
->m
, matchp
->match
->m
->u
.match_size
);
652 size
+= matchp
->match
->m
->u
.match_size
;
654 memcpy(e
->elems
+ size
, target
, target
->u
.target_size
);
659 int do_command4(int argc
, char *argv
[], char **table
,
660 struct xtc_handle
**handle
, bool restore
)
662 struct xt_cmd_parse_ops cmd_parse_ops
= {
663 .proto_parse
= ipv4_proto_parse
,
664 .post_parse
= ipv4_post_parse
,
665 .option_name
= ip46t_option_name
,
666 .option_invert
= ip46t_option_invert
,
667 .command_default
= command_default
,
668 .print_help
= xtables_printhelp
,
670 struct xt_cmd_parse p
= {
674 .ops
= &cmd_parse_ops
,
676 struct iptables_command_state cs
= {
680 struct xtables_args args
= {
683 struct ipt_entry
*e
= NULL
;
684 unsigned int nsaddrs
= 0, ndaddrs
= 0;
685 struct in_addr
*saddrs
= NULL
, *smasks
= NULL
;
686 struct in_addr
*daddrs
= NULL
, *dmasks
= NULL
;
689 const char *chain
= NULL
;
690 const char *policy
= NULL
, *newname
= NULL
;
691 unsigned int rulenum
= 0, command
= 0;
694 do_parse(argc
, argv
, &p
, &cs
, &args
);
704 nsaddrs
= args
.s
.naddrs
;
705 ndaddrs
= args
.d
.naddrs
;
706 saddrs
= args
.s
.addr
.v4
;
707 daddrs
= args
.d
.addr
.v4
;
708 smasks
= args
.s
.mask
.v4
;
709 dmasks
= args
.d
.mask
.v4
;
711 iface_to_mask(cs
.fw
.ip
.iniface
, cs
.fw
.ip
.iniface_mask
);
712 iface_to_mask(cs
.fw
.ip
.outiface
, cs
.fw
.ip
.outiface_mask
);
714 /* Attempt to acquire the xtables lock */
716 xtables_lock_or_exit(wait
);
718 /* only allocate handle if we weren't called with a handle */
720 *handle
= iptc_init(*table
);
722 /* try to insmod the module if iptc_init failed */
723 if (!*handle
&& xtables_load_ko(xtables_modprobe_program
, false) != -1)
724 *handle
= iptc_init(*table
);
727 xtables_error(VERSION_PROBLEM
,
728 "can't initialize iptables table `%s': %s",
729 *table
, iptc_strerror(errno
));
731 if (command
== CMD_APPEND
732 || command
== CMD_DELETE
733 || command
== CMD_CHECK
734 || command
== CMD_INSERT
735 || command
== CMD_REPLACE
) {
736 if (cs
.target
&& iptc_is_chain(cs
.jumpto
, *handle
)) {
738 "Warning: using chain %s, not extension\n",
747 /* If they didn't specify a target, or it's a chain
748 name, use standard. */
750 && (strlen(cs
.jumpto
) == 0
751 || iptc_is_chain(cs
.jumpto
, *handle
))) {
754 cs
.target
= xtables_find_target(XT_STANDARD_TARGET
,
755 XTF_LOAD_MUST_SUCCEED
);
757 size
= sizeof(struct xt_entry_target
)
759 cs
.target
->t
= xtables_calloc(1, size
);
760 cs
.target
->t
->u
.target_size
= size
;
761 strcpy(cs
.target
->t
->u
.user
.name
, cs
.jumpto
);
762 if (!iptc_is_chain(cs
.jumpto
, *handle
))
763 cs
.target
->t
->u
.user
.revision
= cs
.target
->revision
;
764 xs_init_target(cs
.target
);
768 /* It is no chain, and we can't load a plugin.
769 * We cannot know if the plugin is corrupt, non
770 * existent OR if the user just misspelled a
774 if (cs
.fw
.ip
.flags
& IPT_F_GOTO
)
775 xtables_error(PARAMETER_PROBLEM
,
776 "goto '%s' is not a chain",
779 xtables_find_target(cs
.jumpto
, XTF_LOAD_MUST_SUCCEED
);
781 e
= generate_entry(&cs
.fw
, cs
.matches
, cs
.target
->t
);
787 ret
= append_entry(chain
, e
,
788 nsaddrs
, saddrs
, smasks
,
789 ndaddrs
, daddrs
, dmasks
,
790 cs
.options
&OPT_VERBOSE
,
794 ret
= delete_entry(chain
, e
,
795 nsaddrs
, saddrs
, smasks
,
796 ndaddrs
, daddrs
, dmasks
,
797 cs
.options
&OPT_VERBOSE
,
798 *handle
, cs
.matches
, cs
.target
);
801 ret
= iptc_delete_num_entry(chain
, rulenum
- 1, *handle
);
804 ret
= check_entry(chain
, e
,
805 nsaddrs
, saddrs
, smasks
,
806 ndaddrs
, daddrs
, dmasks
,
807 cs
.options
&OPT_VERBOSE
,
808 *handle
, cs
.matches
, cs
.target
);
811 ret
= replace_entry(chain
, e
, rulenum
- 1,
812 saddrs
, smasks
, daddrs
, dmasks
,
813 cs
.options
&OPT_VERBOSE
, *handle
);
816 ret
= insert_entry(chain
, e
, rulenum
- 1,
817 nsaddrs
, saddrs
, smasks
,
818 ndaddrs
, daddrs
, dmasks
,
819 cs
.options
&OPT_VERBOSE
,
823 ret
= flush_entries4(chain
, cs
.options
&OPT_VERBOSE
, *handle
);
826 ret
= zero_entries(chain
, cs
.options
&OPT_VERBOSE
, *handle
);
829 ret
= iptc_zero_counter(chain
, rulenum
, *handle
);
832 case CMD_LIST
|CMD_ZERO
:
833 case CMD_LIST
|CMD_ZERO_NUM
:
834 ret
= list_entries(chain
,
836 cs
.options
&OPT_VERBOSE
,
837 cs
.options
&OPT_NUMERIC
,
838 cs
.options
&OPT_EXPANDED
,
839 cs
.options
&OPT_LINENUMBERS
,
841 if (ret
&& (command
& CMD_ZERO
))
842 ret
= zero_entries(chain
,
843 cs
.options
&OPT_VERBOSE
, *handle
);
844 if (ret
&& (command
& CMD_ZERO_NUM
))
845 ret
= iptc_zero_counter(chain
, rulenum
, *handle
);
848 case CMD_LIST_RULES
|CMD_ZERO
:
849 case CMD_LIST_RULES
|CMD_ZERO_NUM
:
850 ret
= list_rules(chain
,
852 cs
.options
&OPT_VERBOSE
,
854 if (ret
&& (command
& CMD_ZERO
))
855 ret
= zero_entries(chain
,
856 cs
.options
&OPT_VERBOSE
, *handle
);
857 if (ret
&& (command
& CMD_ZERO_NUM
))
858 ret
= iptc_zero_counter(chain
, rulenum
, *handle
);
861 ret
= iptc_create_chain(chain
, *handle
);
863 case CMD_DELETE_CHAIN
:
864 ret
= delete_chain4(chain
, cs
.options
&OPT_VERBOSE
, *handle
);
866 case CMD_RENAME_CHAIN
:
867 ret
= iptc_rename_chain(chain
, newname
, *handle
);
870 ret
= iptc_set_policy(chain
, policy
, cs
.options
&OPT_COUNTERS
? &cs
.fw
.counters
: NULL
, *handle
);
873 /* do_parse ignored the line (eg: -4 with ip6tables-restore) */
876 /* We should never reach this... */
877 exit_tryhelp(2, line
);
881 dump_entries(*handle
);
883 xtables_clear_iptables_command_state(&cs
);
890 xtables_clear_args(&args
);
891 xtables_free_opts(1);