blob: c5a9015de8527648c43c695a1cd6479d6346209f [file] [log] [blame]
Jan Engelhardtf6992cb2011-02-07 03:05:49 +01001#include <netdb.h>
Jan Engelhardtacef6042011-02-07 03:18:53 +01002#include <stdbool.h>
Jan Engelhardtf6992cb2011-02-07 03:05:49 +01003#include <stdint.h>
Jan Engelhardtf89c1712009-06-12 20:48:52 +02004#include <stdio.h>
5#include <xtables.h>
6#include "xshared.h"
7
8/*
9 * Print out any special helps. A user might like to be able to add a --help
10 * to the commandline, and see expected results. So we call help for all
11 * specified matches and targets.
12 */
13void print_extension_helps(const struct xtables_target *t,
14 const struct xtables_rule_match *m)
15{
16 for (; t != NULL; t = t->next) {
17 if (t->used) {
18 printf("\n");
19 if (t->help == NULL)
20 printf("%s does not take any options\n",
21 t->name);
22 else
23 t->help();
24 }
25 }
26 for (; m != NULL; m = m->next) {
27 printf("\n");
28 if (m->match->help == NULL)
29 printf("%s does not take any options\n",
30 m->match->name);
31 else
32 m->match->help();
33 }
34}
Jan Engelhardtf6992cb2011-02-07 03:05:49 +010035
36const char *
37proto_to_name(uint8_t proto, int nolookup)
38{
39 unsigned int i;
40
41 if (proto && !nolookup) {
42 struct protoent *pent = getprotobynumber(proto);
43 if (pent)
44 return pent->p_name;
45 }
46
47 for (i = 0; xtables_chain_protos[i].name != NULL; ++i)
48 if (xtables_chain_protos[i].num == proto)
49 return xtables_chain_protos[i].name;
50
51 return NULL;
52}
53
Jan Engelhardtacef6042011-02-07 03:18:53 +010054static struct xtables_match *
Jan Engelhardtf6992cb2011-02-07 03:05:49 +010055find_proto(const char *pname, enum xtables_tryload tryload,
56 int nolookup, struct xtables_rule_match **matches)
57{
58 unsigned int proto;
59
60 if (xtables_strtoui(pname, NULL, &proto, 0, UINT8_MAX)) {
61 const char *protoname = proto_to_name(proto, nolookup);
62
63 if (protoname)
64 return xtables_find_match(protoname, tryload, matches);
65 } else
66 return xtables_find_match(pname, tryload, matches);
67
68 return NULL;
69}
Jan Engelhardtacef6042011-02-07 03:18:53 +010070
71/*
72 * Some explanations (after four different bugs in 3 different releases): If
73 * we encounter a parameter, that has not been parsed yet, it's not an option
74 * of an explicitly loaded match or a target. However, we support implicit
75 * loading of the protocol match extension. '-p tcp' means 'l4 proto 6' and at
76 * the same time 'load tcp protocol match on demand if we specify --dport'.
77 *
78 * To make this work, we need to make sure:
79 * - the parameter has not been parsed by a match (m above)
80 * - a protocol has been specified
81 * - the protocol extension has not been loaded yet, or is loaded and unused
82 * [think of ip6tables-restore!]
83 * - the protocol extension can be successively loaded
84 */
85static bool should_load_proto(struct iptables_command_state *cs)
86{
87 if (cs->protocol == NULL)
88 return false;
89 if (find_proto(cs->protocol, XTF_DONT_LOAD,
Jan Engelhardtee52e002011-03-01 02:45:34 +010090 cs->options & OPT_NUMERIC, NULL) == NULL)
Jan Engelhardtacef6042011-02-07 03:18:53 +010091 return true;
92 return cs->proto_used;
93}
94
95struct xtables_match *load_proto(struct iptables_command_state *cs)
96{
97 if (!should_load_proto(cs))
98 return NULL;
99 return find_proto(cs->protocol, XTF_TRY_LOAD,
100 cs->options & OPT_NUMERIC, &cs->matches);
101}