From 36a36fc3c41b8b868e8fbd181c50e1ca3ac6d4c5 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Patrick McHardy/emailAddress=kaber@trash.net" Date: Tue, 13 May 2008 11:08:26 +0000 Subject: [patch 3/4] iptables --list-rules command Adds iptables --list-rules (-S) command, acting as a combination of iptables --list and iptables-save. The primary motivation behind this patch is to get iptables-save like output capabilities in iptables-restore, allowing "iptables-restore -n" to be used as a consistent API to iptables for all kind of operations, not only blind updates.. As a bonus iptables also gets the capability of printing the rules as-is. This completely replaces the earlier patch which added the --rules option. Henrik Nordstrom --- ip6tables-save.c | 193 ------------------------------------------------------- 1 file changed, 193 deletions(-) (limited to 'ip6tables-save.c') diff --git a/ip6tables-save.c b/ip6tables-save.c index bd4ccbf..7b03d7c 100644 --- a/ip6tables-save.c +++ b/ip6tables-save.c @@ -33,199 +33,6 @@ static const struct option options[] = { }; -/* This assumes that mask is contiguous, and byte-bounded. */ -static void -print_iface(char letter, const char *iface, const unsigned char *mask, - int invert) -{ - unsigned int i; - - if (mask[0] == 0) - return; - - printf("-%c %s", letter, invert ? "! " : ""); - - for (i = 0; i < IFNAMSIZ; i++) { - if (mask[i] != 0) { - if (iface[i] != '\0') - printf("%c", iface[i]); - } else { - /* we can access iface[i-1] here, because - * a few lines above we make sure that mask[0] != 0 */ - if (iface[i-1] != '\0') - printf("+"); - break; - } - } - - printf(" "); -} - -/* These are hardcoded backups in ip6tables.c, so they are safe */ -struct pprot { - char *name; - u_int8_t num; -}; - -static const struct pprot chain_protos[] = { - { "tcp", IPPROTO_TCP }, - { "udp", IPPROTO_UDP }, - { "icmpv6", IPPROTO_ICMPV6 }, - { "esp", IPPROTO_ESP }, - { "ah", IPPROTO_AH }, -}; - -/* The ip6tables looks up the /etc/protocols. */ -static void print_proto(u_int16_t proto, int invert) -{ - if (proto) { - unsigned int i; - const char *invertstr = invert ? "! " : ""; - - struct protoent *pent = getprotobynumber(proto); - if (pent) { - printf("-p %s%s ", - invertstr, pent->p_name); - return; - } - - for (i = 0; i < sizeof(chain_protos)/sizeof(struct pprot); i++) - if (chain_protos[i].num == proto) { - printf("-p %s%s ", - invertstr, chain_protos[i].name); - return; - } - - printf("-p %s%u ", invertstr, proto); - } -} - -static int print_match(const struct ip6t_entry_match *e, - const struct ip6t_ip6 *ip) -{ - struct xtables_match *match - = find_match(e->u.user.name, TRY_LOAD, NULL); - - if (match) { - printf("-m %s ", e->u.user.name); - - /* some matches don't provide a save function */ - if (match->save) - match->save(ip, e); - } else { - if (e->u.match_size) { - fprintf(stderr, - "Can't find library for match `%s'\n", - e->u.user.name); - exit(1); - } - } - return 0; -} - -/* print a given ip including mask if neccessary */ -static void print_ip(char *prefix, const struct in6_addr *ip, const struct in6_addr *mask, int invert) -{ - char buf[51]; - int l = ipv6_prefix_length(mask); - - if (l == 0 && !invert) - return; - - printf("%s %s%s", - prefix, - invert ? "! " : "", - inet_ntop(AF_INET6, ip, buf, sizeof buf)); - - if (l == -1) - printf("/%s ", inet_ntop(AF_INET6, mask, buf, sizeof buf)); - else - printf("/%d ", l); -} - -/* We want this to be readable, so only print out neccessary fields. - * Because that's the kind of world I want to live in. */ -static void print_rule(const struct ip6t_entry *e, - ip6tc_handle_t *h, const char *chain, int counters) -{ - struct ip6t_entry_target *t; - const char *target_name; - - /* print counters */ - if (counters) - printf("[%llu:%llu] ", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt); - - /* print chain name */ - printf("-A %s ", chain); - - /* Print IP part. */ - print_ip("-s", &(e->ipv6.src), &(e->ipv6.smsk), - e->ipv6.invflags & IP6T_INV_SRCIP); - - print_ip("-d", &(e->ipv6.dst), &(e->ipv6.dmsk), - e->ipv6.invflags & IP6T_INV_DSTIP); - - print_iface('i', e->ipv6.iniface, e->ipv6.iniface_mask, - e->ipv6.invflags & IP6T_INV_VIA_IN); - - print_iface('o', e->ipv6.outiface, e->ipv6.outiface_mask, - e->ipv6.invflags & IP6T_INV_VIA_OUT); - - print_proto(e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO); - -#if 0 - /* not definied in ipv6 - * FIXME: linux/netfilter_ipv6/ip6_tables: IP6T_INV_FRAG why definied? */ - if (e->ipv6.flags & IPT_F_FRAG) - printf("%s-f ", - e->ipv6.invflags & IP6T_INV_FRAG ? "! " : ""); -#endif - - if (e->ipv6.flags & IP6T_F_TOS) - printf("%s-? %d ", - e->ipv6.invflags & IP6T_INV_TOS ? "! " : "", - e->ipv6.tos); - - /* Print matchinfo part */ - if (e->target_offset) { - IP6T_MATCH_ITERATE(e, print_match, &e->ipv6); - } - - /* Print target name */ - target_name = ip6tc_get_target(e, h); - if (target_name && (*target_name != '\0')) - printf("-j %s ", target_name); - - /* Print targinfo part */ - t = ip6t_get_target((struct ip6t_entry *)e); - if (t->u.user.name[0]) { - struct xtables_target *target - = find_target(t->u.user.name, TRY_LOAD); - - if (!target) { - fprintf(stderr, "Can't find library for target `%s'\n", - t->u.user.name); - exit(1); - } - - if (target->save) - target->save(&e->ipv6, t); - else { - /* If the target size is greater than ip6t_entry_target - * there is something to be saved, we just don't know - * how to print it */ - if (t->u.target_size != - sizeof(struct ip6t_entry_target)) { - fprintf(stderr, "Target `%s' is missing " - "save function\n", - t->u.user.name); - exit(1); - } - } - } - printf("\n"); -} - /* Debugging prototype. */ static int for_each_table(int (*func)(const char *tablename)) { -- cgit v1.2.3