diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-09-30 16:31:03 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-09-30 18:22:15 +0200 |
commit | 5c0d2ffd9cc954b94344795deaaadb1a8fd68b59 (patch) | |
tree | dd883f0d27a81edd48e7a61b650e3c46d7466813 /src | |
parent | b495e1d22faff636589a9646fbd4bb30902d3542 (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.c | 123 |
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, |