summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-09-30 16:31:03 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2013-09-30 18:22:15 +0200
commit5c0d2ffd9cc954b94344795deaaadb1a8fd68b59 (patch)
treedd883f0d27a81edd48e7a61b650e3c46d7466813 /src
parentb495e1d22faff636589a9646fbd4bb30902d3542 (diff)
nfct: timeout: split nfct_cmd_timeout_add in several functions
This patch is a cleanup to split this function in smaller chunks. It is required to prepare default protocol timeout tuning via netlink.
Diffstat (limited to 'src')
-rw-r--r--src/nfct-extensions/timeout.c123
1 files changed, 80 insertions, 43 deletions
diff --git a/src/nfct-extensions/timeout.c b/src/nfct-extensions/timeout.c
index 7811bb2..0cf92bb 100644
--- a/src/nfct-extensions/timeout.c
+++ b/src/nfct-extensions/timeout.c
@@ -1,5 +1,5 @@
/*
- * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2012-2013 by Pablo Neira Ayuso <pablo@netfilter.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
@@ -174,53 +174,34 @@ static uint32_t nfct_timeout_attr_max[IPPROTO_MAX] = {
[IPPROTO_RAW] = NFCT_TIMEOUT_ATTR_GENERIC_MAX,
};
-int nfct_cmd_timeout_add(int argc, char *argv[])
+static int nfct_cmd_get_l3proto(char *argv[])
{
- struct mnl_socket *nl;
- char buf[MNL_SOCKET_BUFFER_SIZE];
- struct nlmsghdr *nlh;
- uint32_t portid, seq;
- struct nfct_timeout *t;
- uint16_t l3proto;
- uint8_t l4proto;
- int ret, i;
- unsigned int j;
- struct protoent *pent;
-
- if (argc < 6) {
- nfct_perror("missing parameters\n"
- "syntax: nfct timeout add name "
- "family protocol state1 "
- "timeout1 state2 timeout2...");
- return -1;
- }
-
- t = nfct_timeout_alloc();
- if (t == NULL) {
- nfct_perror("OOM");
- return -1;
- }
-
- nfct_timeout_attr_set(t, NFCT_TIMEOUT_ATTR_NAME, argv[3]);
+ int l3proto;
- if (strcmp(argv[4], "inet") == 0)
+ if (strcmp(*argv, "inet") == 0)
l3proto = AF_INET;
- else if (strcmp(argv[4], "inet6") == 0)
+ else if (strcmp(*argv, "inet6") == 0)
l3proto = AF_INET6;
else {
nfct_perror("unknown layer 3 protocol");
return -1;
}
- nfct_timeout_attr_set_u16(t, NFCT_TIMEOUT_ATTR_L3PROTO, l3proto);
+ return l3proto;
+}
+
+static int nfct_cmd_get_l4proto(char *argv[])
+{
+ int l4proto;
+ struct protoent *pent;
- pent = getprotobyname(argv[5]);
+ pent = getprotobyname(*argv);
if (!pent) {
/* In Debian, /etc/protocols says ipv6-icmp. Support icmpv6
* as well not to break backward compatibility.
*/
- if (strcmp(argv[5], "icmpv6") == 0)
+ if (strcmp(*argv, "icmpv6") == 0)
l4proto = IPPROTO_ICMPV6;
- else if (strcmp(argv[5], "generic") == 0)
+ else if (strcmp(*argv, "generic") == 0)
l4proto = IPPROTO_RAW;
else {
nfct_perror("unknown layer 4 protocol");
@@ -229,9 +210,35 @@ int nfct_cmd_timeout_add(int argc, char *argv[])
} else
l4proto = pent->p_proto;
+ return l4proto;
+}
+
+static int
+nfct_cmd_timeout_parse(struct nfct_timeout *t, int argc, char *argv[])
+{
+ int l3proto, l4proto;
+ unsigned int j;
+ const char *proto_name;
+
+ l3proto = nfct_cmd_get_l3proto(argv);
+ if (l3proto < 0)
+ return -1;
+
+ nfct_timeout_attr_set_u16(t, NFCT_TIMEOUT_ATTR_L3PROTO, l3proto);
+
+ argc--;
+ argv++;
+ proto_name = *argv;
+
+ l4proto = nfct_cmd_get_l4proto(argv);
+ if (l4proto < 0)
+ return -1;
+
nfct_timeout_attr_set_u8(t, NFCT_TIMEOUT_ATTR_L4PROTO, l4proto);
+ argc--;
+ argv++;
- for (i=6; i<argc; i+=2) {
+ for (; argc>1; argc-=2, argv+=2) {
int matching = -1;
for (j=0; j<nfct_timeout_attr_max[l4proto]; j++) {
@@ -243,27 +250,57 @@ int nfct_cmd_timeout_add(int argc, char *argv[])
nfct_perror("state name is NULL");
return -1;
}
- if (strcasecmp(argv[i], state_name) != 0)
+ if (strcasecmp(*argv, state_name) != 0)
continue;
matching = j;
break;
}
if (matching != -1) {
- if (i+1 >= argc) {
- nfct_perror("missing value for this timeout");
- return -1;
- }
nfct_timeout_policy_attr_set_u32(t, matching,
- atoi(argv[i+1]));
- matching = -1;
+ atoi(*(argv+1)));
} else {
fprintf(stderr, "nfct v%s: Wrong state name: `%s' "
"for protocol `%s'\n",
- VERSION, argv[i], argv[5]);
+ VERSION, *argv, proto_name);
return -1;
}
}
+ if (argc > 0) {
+ nfct_perror("missing value for this timeout");
+ return -1;
+ }
+
+ return 0;
+}
+
+int nfct_cmd_timeout_add(int argc, char *argv[])
+{
+ struct mnl_socket *nl;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ uint32_t portid, seq;
+ struct nfct_timeout *t;
+ int ret;
+
+ if (argc < 6) {
+ nfct_perror("missing parameters\n"
+ "syntax: nfct timeout add name "
+ "family protocol state1 "
+ "timeout1 state2 timeout2...");
+ return -1;
+ }
+
+ t = nfct_timeout_alloc();
+ if (t == NULL) {
+ nfct_perror("OOM");
+ return -1;
+ }
+
+ nfct_timeout_attr_set(t, NFCT_TIMEOUT_ATTR_NAME, argv[3]);
+
+ if (nfct_cmd_timeout_parse(t, argc-4, &argv[4]) < 0)
+ return -1;
seq = time(NULL);
nlh = nfct_timeout_nlmsg_build_hdr(buf, IPCTNL_MSG_TIMEOUT_NEW,