diff options
author | /C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org> | 2007-07-18 20:04:00 +0000 |
---|---|---|
committer | /C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org </C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org> | 2007-07-18 20:04:00 +0000 |
commit | 18bbf19becaab7dc4137406928f96ad089192f69 (patch) | |
tree | c6d75df8591e20083044cbf07d73e8f6738fd1fd | |
parent | 96084e1a1f2e0a49c961bbddb9fffd2e03bfae3f (diff) | |
download | conntrack-tools-18bbf19becaab7dc4137406928f96ad089192f69.tar.gz conntrack-tools-18bbf19becaab7dc4137406928f96ad089192f69.zip |
conntrackd:
- use buffer of MTU size
conntrack:
- better protocol argument checkings
- fix per-protocol filtering, eg. conntrack -[L|E] -p tcp now works
- show per-protocol help, ie. conntrack -h -p tcp
- add alias --src for --orig-src and alias --dst for --orig-dst
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | examples/sync/nack/node1/conntrackd.conf | 1 | ||||
-rw-r--r-- | examples/sync/nack/node2/conntrackd.conf | 1 | ||||
-rw-r--r-- | examples/sync/persistent/node1/conntrackd.conf | 1 | ||||
-rw-r--r-- | examples/sync/persistent/node2/conntrackd.conf | 1 | ||||
-rw-r--r-- | extensions/libct_proto_icmp.c | 45 | ||||
-rw-r--r-- | extensions/libct_proto_tcp.c | 63 | ||||
-rw-r--r-- | extensions/libct_proto_udp.c | 50 | ||||
-rw-r--r-- | include/conntrack.h | 28 | ||||
-rw-r--r-- | include/mcast.h | 3 | ||||
-rw-r--r-- | include/network.h | 7 | ||||
-rw-r--r-- | src/conntrack.c | 108 | ||||
-rw-r--r-- | src/mcast.c | 14 | ||||
-rw-r--r-- | src/network.c | 32 | ||||
-rw-r--r-- | src/read_config_lex.l | 3 | ||||
-rw-r--r-- | src/read_config_yy.y | 9 | ||||
-rw-r--r-- | src/sync-mode.c | 9 |
17 files changed, 266 insertions, 116 deletions
@@ -5,6 +5,7 @@ version 0.9.5 (yet unreleased) o conntrack-tools requires libnetfilter_conntrack >= 0.0.81 o add len field to nethdr o implement buffered send/recv to batch messages +o use buffer of MTU size o stop using netlink format for network messages: use similar TLV-based format o reduce synchronization messages size up to 60% o introduce periodic alive messages for sync-nack protocol @@ -14,6 +15,12 @@ o remove major use of libnfnetlink functions: use libnetfilter_conntrack API o deprecate conntrackd -F, use conntrack -F instead o major rework of the network infrastructure: much simple, less messy += conntrack = +o better protocol argument checkings +o fix per-protocol filtering, eg. conntrack -L -p tcp +o show per-protocol help, ie. conntrack -h -p tcp +o add alias --src for --orig-src and alias --dst for --orig-dst + version 0.9.4 (2007/07/02) ------------------------------ diff --git a/examples/sync/nack/node1/conntrackd.conf b/examples/sync/nack/node1/conntrackd.conf index edec9cf..9a7d55f 100644 --- a/examples/sync/nack/node1/conntrackd.conf +++ b/examples/sync/nack/node1/conntrackd.conf @@ -32,6 +32,7 @@ Sync { Multicast { IPv4_address 225.0.0.50 IPv4_interface 192.168.100.100 # IP of dedicated link + Interface eth2 Group 3780 } diff --git a/examples/sync/nack/node2/conntrackd.conf b/examples/sync/nack/node2/conntrackd.conf index de5f4d2..cee16c8 100644 --- a/examples/sync/nack/node2/conntrackd.conf +++ b/examples/sync/nack/node2/conntrackd.conf @@ -31,6 +31,7 @@ Sync { Multicast { IPv4_address 225.0.0.50 IPv4_interface 192.168.100.200 # IP of dedicated link + Interface eth2 Group 3780 } diff --git a/examples/sync/persistent/node1/conntrackd.conf b/examples/sync/persistent/node1/conntrackd.conf index 60f264b..e80921b 100644 --- a/examples/sync/persistent/node1/conntrackd.conf +++ b/examples/sync/persistent/node1/conntrackd.conf @@ -37,6 +37,7 @@ Sync { Multicast { IPv4_address 225.0.0.50 IPv4_interface 192.168.100.100 # IP of dedicated link + Interface eth2 Group 3780 } diff --git a/examples/sync/persistent/node2/conntrackd.conf b/examples/sync/persistent/node2/conntrackd.conf index 6a1806b..ad4b040 100644 --- a/examples/sync/persistent/node2/conntrackd.conf +++ b/examples/sync/persistent/node2/conntrackd.conf @@ -37,6 +37,7 @@ Sync { Multicast { IPv4_address 225.0.0.50 IPv4_interface 192.168.100.200 # IP of dedicated link + Interface eth2 Group 3780 } diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c index 765ced4..09fd8da 100644 --- a/extensions/libct_proto_icmp.c +++ b/extensions/libct_proto_icmp.c @@ -24,6 +24,33 @@ static struct option opts[] = { {0, 0, 0, 0} }; +#define ICMP_NUMBER_OF_OPT 4 + +static const char *icmp_optflags[ICMP_NUMBER_OF_OPT] = { +"icmp-type", "icmp-code", "icmp-id" +}; + +static char icmp_commands_v_options[NUMBER_OF_CMD][ICMP_NUMBER_OF_OPT] = +/* Well, it's better than "Re: Maradona vs Pele" */ +{ + /* 1 2 3 */ +/*CT_LIST*/ {2,2,2}, +/*CT_CREATE*/ {1,1,2}, +/*CT_UPDATE*/ {1,1,2}, +/*CT_DELETE*/ {1,1,2}, +/*CT_GET*/ {1,1,2}, +/*CT_FLUSH*/ {0,0,0}, +/*CT_EVENT*/ {2,2,2}, +/*CT_VERSION*/ {0,0,0}, +/*CT_HELP*/ {0,0,0}, +/*EXP_LIST*/ {0,0,0}, +/*EXP_CREATE*/ {0,0,0}, +/*EXP_DELETE*/ {0,0,0}, +/*EXP_GET*/ {0,0,0}, +/*EXP_FLUSH*/ {0,0,0}, +/*EXP_EVENT*/ {0,0,0}, +}; + static void help() { fprintf(stdout, " --icmp-type\t\t\ticmp type\n"); @@ -31,7 +58,7 @@ static void help() fprintf(stdout, " --icmp-id\t\t\ticmp id\n"); } -static int parse(char c, char *argv[], +static int parse(char c, struct nf_conntrack *ct, struct nf_conntrack *exptuple, struct nf_conntrack *mask, @@ -69,16 +96,14 @@ static int parse(char c, char *argv[], return 1; } -static int final_check(unsigned int flags, - unsigned int command, - struct nf_conntrack *ct) +static void final_check(unsigned int flags, + unsigned int cmd, + struct nf_conntrack *ct) { - if (!(flags & ICMP_TYPE)) - return 0; - else if (!(flags & ICMP_CODE)) - return 0; - - return 1; + generic_opt_check(flags, + ICMP_NUMBER_OF_OPT, + icmp_commands_v_options[cmd], + icmp_optflags); } static struct ctproto_handler icmp = { diff --git a/extensions/libct_proto_tcp.c b/extensions/libct_proto_tcp.c index 5a40cef..1f630b3 100644 --- a/extensions/libct_proto_tcp.c +++ b/extensions/libct_proto_tcp.c @@ -32,6 +32,34 @@ static struct option opts[] = { {0, 0, 0, 0} }; +#define TCP_NUMBER_OF_OPT 10 + +static const char *tcp_optflags[TCP_NUMBER_OF_OPT] = { +"sport", "dport", "reply-port-src", "reply-port-dst", "mask-port-src", +"mask-port-dst", "state", "tuple-port-src", "tuple-port-dst" +}; + +static char tcp_commands_v_options[NUMBER_OF_CMD][TCP_NUMBER_OF_OPT] = +/* Well, it's better than "Re: Sevilla vs Betis" */ +{ + /* 1 2 3 4 5 6 7 8 9 */ +/*CT_LIST*/ {2,2,2,2,0,0,2,0,0}, +/*CT_CREATE*/ {1,1,1,1,0,0,1,0,0}, +/*CT_UPDATE*/ {1,1,1,1,0,0,2,0,0}, +/*CT_DELETE*/ {1,1,1,1,0,0,0,0,0}, +/*CT_GET*/ {1,1,1,1,0,0,2,0,0}, +/*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0}, +/*CT_EVENT*/ {2,2,2,2,0,0,2,0,0}, +/*CT_VERSION*/ {0,0,0,0,0,0,0,0,0}, +/*CT_HELP*/ {0,0,0,0,0,0,0,0,0}, +/*EXP_LIST*/ {0,0,0,0,0,0,0,0,0}, +/*EXP_CREATE*/ {1,1,1,1,1,1,0,1,1}, +/*EXP_DELETE*/ {1,1,1,1,0,0,0,0,0}, +/*EXP_GET*/ {1,1,1,1,0,0,0,0,0}, +/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0,0}, +/*EXP_EVENT*/ {0,0,0,0,0,0,0,0,0}, +}; + static const char *states[] = { "NONE", "SYN_SENT", @@ -58,7 +86,7 @@ static void help() fprintf(stdout, " --state\t\t\tTCP state, fe. ESTABLISHED\n"); } -static int parse_options(char c, char *argv[], +static int parse_options(char c, struct nf_conntrack *ct, struct nf_conntrack *exptuple, struct nf_conntrack *mask, @@ -139,10 +167,9 @@ static int parse_options(char c, char *argv[], break; } } - if (i == 10) { - printf("doh?\n"); - return 0; - } + if (i == 10) + exit_error(PARAMETER_PROBLEM, + "Unknown TCP state %s\n", optarg); *flags |= TCP_STATE; break; case '8': @@ -169,12 +196,10 @@ static int parse_options(char c, char *argv[], return 1; } -static int final_check(unsigned int flags, - unsigned int command, - struct nf_conntrack *ct) +static void final_check(unsigned int flags, + unsigned int cmd, + struct nf_conntrack *ct) { - int ret = 0; - if ((flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) && !(flags & (TCP_REPL_SPORT|TCP_REPL_DPORT))) { nfct_set_attr_u16(ct, @@ -183,7 +208,8 @@ static int final_check(unsigned int flags, nfct_set_attr_u16(ct, ATTR_REPL_PORT_DST, nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC)); - ret = 1; + flags |= TCP_REPL_SPORT; + flags |= TCP_REPL_DPORT; } else if (!(flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) && (flags & (TCP_REPL_SPORT|TCP_REPL_DPORT))) { nfct_set_attr_u16(ct, @@ -192,17 +218,14 @@ static int final_check(unsigned int flags, nfct_set_attr_u16(ct, ATTR_ORIG_PORT_DST, nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC)); - ret = 1; + flags |= TCP_ORIG_SPORT; + flags |= TCP_ORIG_DPORT; } - if ((flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) - && ((flags & (TCP_REPL_SPORT|TCP_REPL_DPORT)))) - ret = 1; - - /* --state is missing and we are trying to create a conntrack */ - if (ret && (command & CT_CREATE) && (!(flags & TCP_STATE))) - ret = 0; - return ret; + generic_opt_check(flags, + TCP_NUMBER_OF_OPT, + tcp_commands_v_options[cmd], + tcp_optflags); } static struct ctproto_handler tcp = { diff --git a/extensions/libct_proto_udp.c b/extensions/libct_proto_udp.c index cb131d6..2216b71 100644 --- a/extensions/libct_proto_udp.c +++ b/extensions/libct_proto_udp.c @@ -31,6 +31,13 @@ static struct option opts[] = { {0, 0, 0, 0} }; +#define UDP_NUMBER_OF_OPT 9 + +static const char *udp_optflags[UDP_NUMBER_OF_OPT] = { +"sport", "dport", "reply-port-src", "reply-port-dst", "mask-port-src", +"mask-port-dst", "tuple-port-src", "tuple-port-dst" +}; + static void help() { fprintf(stdout, " --orig-port-src\t\toriginal source port\n"); @@ -43,7 +50,28 @@ static void help() fprintf(stdout, " --tuple-port-src\t\texpectation tuple dst port\n"); } -static int parse_options(char c, char *argv[], +static char udp_commands_v_options[NUMBER_OF_CMD][UDP_NUMBER_OF_OPT] = +/* Well, it's better than "Re: Galeano vs Vargas Llosa" */ +{ + /* 1 2 3 4 5 6 7 8 */ +/*CT_LIST*/ {2,2,2,2,0,0,0,0}, +/*CT_CREATE*/ {1,1,1,1,0,0,0,0}, +/*CT_UPDATE*/ {1,1,1,1,0,0,0,0}, +/*CT_DELETE*/ {1,1,1,1,0,0,0,0}, +/*CT_GET*/ {1,1,1,1,0,0,0,0}, +/*CT_FLUSH*/ {0,0,0,0,0,0,0,0}, +/*CT_EVENT*/ {2,2,2,2,0,0,0,0}, +/*CT_VERSION*/ {0,0,0,0,0,0,0,0}, +/*CT_HELP*/ {0,0,0,0,0,0,0,0}, +/*EXP_LIST*/ {0,0,0,0,0,0,0,0}, +/*EXP_CREATE*/ {1,1,1,1,1,1,1,1}, +/*EXP_DELETE*/ {1,1,1,1,0,0,0,0}, +/*EXP_GET*/ {1,1,1,1,0,0,0,0}, +/*EXP_FLUSH*/ {0,0,0,0,0,0,0,0}, +/*EXP_EVENT*/ {0,0,0,0,0,0,0,0}, +}; + +static int parse_options(char c, struct nf_conntrack *ct, struct nf_conntrack *exptuple, struct nf_conntrack *mask, @@ -134,9 +162,9 @@ static int parse_options(char c, char *argv[], return 1; } -static int final_check(unsigned int flags, - unsigned int command, - struct nf_conntrack *ct) +static void final_check(unsigned int flags, + unsigned int cmd, + struct nf_conntrack *ct) { int ret = 0; @@ -148,7 +176,8 @@ static int final_check(unsigned int flags, nfct_set_attr_u16(ct, ATTR_REPL_PORT_DST, nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC)); - ret = 1; + flags |= UDP_REPL_SPORT; + flags |= UDP_REPL_DPORT; } else if (!(flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) && (flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))) { nfct_set_attr_u16(ct, @@ -157,13 +186,14 @@ static int final_check(unsigned int flags, nfct_set_attr_u16(ct, ATTR_ORIG_PORT_DST, nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC)); - ret = 1; + flags |= UDP_ORIG_SPORT; + flags |= UDP_ORIG_DPORT; } - if ((flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) - && ((flags & (UDP_REPL_SPORT|UDP_REPL_DPORT)))) - ret = 1; - return ret; + generic_opt_check(flags, + UDP_NUMBER_OF_OPT, + udp_commands_v_options[cmd], + udp_optflags); } static struct ctproto_handler udp = { diff --git a/include/conntrack.h b/include/conntrack.h index f344d72..5edc0e9 100644 --- a/include/conntrack.h +++ b/include/conntrack.h @@ -151,15 +151,15 @@ struct ctproto_handler { enum ctattr_protoinfo protoinfo_attr; - int (*parse_opts)(char c, char *argv[], - struct nf_conntrack *ct, - struct nf_conntrack *exptuple, - struct nf_conntrack *mask, - unsigned int *flags); + int (*parse_opts)(char c, + struct nf_conntrack *ct, + struct nf_conntrack *exptuple, + struct nf_conntrack *mask, + unsigned int *flags); - int (*final_check)(unsigned int flags, - unsigned int command, - struct nf_conntrack *ct); + void (*final_check)(unsigned int flags, + unsigned int command, + struct nf_conntrack *ct); void (*help)(); @@ -168,6 +168,18 @@ struct ctproto_handler { unsigned int option_offset; }; +enum exittype { + OTHER_PROBLEM = 1, + PARAMETER_PROBLEM, + VERSION_PROBLEM +}; + +void generic_opt_check(int options, + int nops, + char *optset, + const char *optflg[]); +void exit_error(enum exittype status, char *msg, ...); + extern void register_proto(struct ctproto_handler *h); extern void register_tcp(void); diff --git a/include/mcast.h b/include/mcast.h index 66676dc..d4fd335 100644 --- a/include/mcast.h +++ b/include/mcast.h @@ -2,6 +2,7 @@ #define _MCAST_H_ #include <netinet/in.h> +#include <net/if.h> struct mcast_conf { int ipproto; @@ -16,6 +17,8 @@ struct mcast_conf { struct in_addr interface_addr; struct in6_addr interface_addr6; } ifa; + int mtu; + char iface[IFNAMSIZ]; }; struct mcast_stats { diff --git a/include/network.h b/include/network.h index bc9431d..f8fdd0d 100644 --- a/include/network.h +++ b/include/network.h @@ -55,6 +55,13 @@ int prepare_send_netmsg(struct mcast_sock *m, void *data); int mcast_send_netmsg(struct mcast_sock *m, void *data); int mcast_recv_netmsg(struct mcast_sock *m, void *data, int len); +struct mcast_conf; + +int mcast_buffered_init(struct mcast_conf *conf); +void mcast_buffered_destroy(); +int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, int len); +int mcast_buffered_pending_netmsg(struct mcast_sock *m); + #define IS_DATA(x) ((x->flags & ~NET_F_HELLO) == 0) #define IS_ACK(x) (x->flags & NET_F_ACK) #define IS_NACK(x) (x->flags & NET_F_NACK) diff --git a/src/conntrack.c b/src/conntrack.c index eece45b..165809b 100644 --- a/src/conntrack.c +++ b/src/conntrack.c @@ -64,8 +64,10 @@ static const char cmdflags[NUMBER_OF_CMD] static const char cmd_need_param[NUMBER_OF_CMD] = { 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 2, 2 }; -static const char optflags[NUMBER_OF_OPT] -= {'s','d','r','q','p','t','u','z','e','[',']','{','}','a','m','i','f','n','g','x'}; +static const char *optflags[NUMBER_OF_OPT] = { +"src","dst","reply-src","reply-dst","protonum","timeout","status","zero", +"event-mask","tuple-src","tuple-dst","mask-src","mask-dst","nat-range","mark", +"id","family","src-nat","dst-nat","output" }; static struct option original_opts[] = { {"dump", 2, 0, 'L'}, @@ -78,7 +80,9 @@ static struct option original_opts[] = { {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, {"orig-src", 1, 0, 's'}, + {"src", 1, 0, 's'}, {"orig-dst", 1, 0, 'd'}, + {"dst", 1, 0, 'd'}, {"reply-src", 1, 0, 'r'}, {"reply-dst", 1, 0, 'q'}, {"protonum", 1, 0, 'p'}, @@ -127,7 +131,7 @@ static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = /*CT_FLUSH*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*CT_EVENT*/ {2,2,2,2,2,0,0,0,2,0,0,0,0,0,2,0,0,2,2,2}, /*VERSION*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, -/*HELP*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +/*HELP*/ {0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, /*EXP_LIST*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0}, /*EXP_CREATE*/{1,1,2,2,1,1,2,0,0,1,1,1,1,0,0,0,0,0,0,0}, /*EXP_DELETE*/{1,1,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, @@ -172,12 +176,6 @@ static struct ctproto_handler *findproto(char *name) return handler; } -enum exittype { - OTHER_PROBLEM = 1, - PARAMETER_PROBLEM, - VERSION_PROBLEM -}; - void extension_help(struct ctproto_handler *h) { fprintf(stdout, "\n"); @@ -193,8 +191,7 @@ exit_tryhelp(int status) exit(status); } -static void -exit_error(enum exittype status, char *msg, ...) +void exit_error(enum exittype status, char *msg, ...) { va_list args; @@ -218,51 +215,43 @@ exit_error(enum exittype status, char *msg, ...) static void generic_cmd_check(int command, int options) { - int i; - - for (i = 0; i < NUMBER_OF_CMD; i++) { - if (!(command & (1<<i))) - continue; - - if (cmd_need_param[i] == 0 && !options) - exit_error(PARAMETER_PROBLEM, - "You need to supply parameters to `-%c'\n", - cmdflags[i]); - } + if (cmd_need_param[command] == 0 && !options) + exit_error(PARAMETER_PROBLEM, + "You need to supply parameters to `-%c'\n", + cmdflags[command]); } -static void -generic_opt_check(int command, int options) +static int bit2cmd(int command) { - int i, j, legal = 0; + int i; - /* Check that commands are valid with options. Complicated by the - * fact that if an option is legal with *any* command given, it is - * legal overall (ie. -z and -l). - */ - for (i = 0; i < NUMBER_OF_OPT; i++) { - legal = 0; /* -1 => illegal, 1 => legal, 0 => undecided. */ + for (i = 0; i < NUMBER_OF_CMD; i++) + if (command & (1<<i)) + break; - for (j = 0; j < NUMBER_OF_CMD; j++) { - if (!(command & (1<<j))) - continue; + return i; +} - if (!(options & (1<<i))) { - if (commands_v_options[j][i] == 1) - exit_error(PARAMETER_PROBLEM, - "You need to supply the " - "`-%c' option for this " - "command\n", optflags[i]); - } else { - if (commands_v_options[j][i] != 0) - legal = 1; - else if (legal == 0) - legal = -1; - } +void generic_opt_check(int options, + int num_opts, + char *optset, + const char *optflg[]) +{ + int i; + + for (i = 0; i < num_opts; i++) { + if (!(options & (1<<i))) { + if (optset[i] == 1) + exit_error(PARAMETER_PROBLEM, + "You need to supply the " + "`--%s' option for this " + "command\n", optflg[i]); + } else { + if (optset[i] == 0) + exit_error(PARAMETER_PROBLEM, "Illegal " + "option `--%s' with this " + "command\n", optflg[i]); } - if (legal == -1) - exit_error(PARAMETER_PROBLEM, "Illegal option `-%c' " - "with this command\n", optflags[i]); } } @@ -664,7 +653,7 @@ static struct ctproto_handler *h; int main(int argc, char *argv[]) { - int c; + int c, cmd; unsigned int type = 0, event_mask = 0, l4flags = 0, status = 0; int res = 0; int family = AF_UNSPEC; @@ -978,7 +967,7 @@ int main(int argc, char *argv[]) break; default: if (h && h->parse_opts - &&!h->parse_opts(c - h->option_offset, argv, obj, + &&!h->parse_opts(c - h->option_offset, obj, exptuple, mask, &l4flags)) exit_error(PARAMETER_PROBLEM, "parse error\n"); @@ -996,16 +985,15 @@ int main(int argc, char *argv[]) if (family == AF_UNSPEC) family = AF_INET; - generic_cmd_check(command, options); - generic_opt_check(command, options); + cmd = bit2cmd(command); + generic_cmd_check(cmd, options); + generic_opt_check(options, + NUMBER_OF_OPT, + commands_v_options[cmd], + optflags); - if (!(command & CT_HELP) - && h && h->final_check - && !h->final_check(l4flags, command, obj)) { - usage(argv[0]); - extension_help(h); - exit_error(PARAMETER_PROBLEM, "Missing protocol arguments!\n"); - } + if (!(command & CT_HELP) && h && h->final_check) + h->final_check(l4flags, cmd, obj); switch(command) { diff --git a/src/mcast.c b/src/mcast.c index 6193a59..cdaed5f 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -26,6 +26,8 @@ #include <sys/time.h> #include <unistd.h> #include <string.h> +#include <sys/ioctl.h> +#include <net/if.h> #include "mcast.h" #include "debug.h" @@ -71,6 +73,18 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) return NULL; } + if(conf->iface[0]) { + struct ifreq ifr; + + strncpy(ifr.ifr_name, conf->iface, sizeof(ifr.ifr_name)); + + if (ioctl(m->fd, SIOCGIFMTU, &ifr) == -1) { + debug("ioctl"); + return NULL; + } + conf->mtu = ifr.ifr_mtu; + } + if (setsockopt(m->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { debug("mcast_sock_server_create:setsockopt1"); diff --git a/src/network.c b/src/network.c index d162839..a7843dc 100644 --- a/src/network.c +++ b/src/network.c @@ -90,9 +90,33 @@ int prepare_send_netmsg(struct mcast_sock *m, void *data) return ret; } +static int tx_buflenmax; static int tx_buflen = 0; -/* XXX: use buffer size of interface MTU */ -static char __tx_buf[1460], *tx_buf = __tx_buf; +static char *tx_buf; + +#define HEADERSIZ 28 /* IP header (20 bytes) + UDP header 8 (bytes) */ + +int mcast_buffered_init(struct mcast_conf *conf) +{ + int mtu = conf->mtu - HEADERSIZ; + + /* default to Ethernet MTU 1500 bytes */ + if (mtu == 0) + mtu = 1500 - HEADERSIZ; + + tx_buf = malloc(mtu); + if (tx_buf == NULL) + return -1; + + tx_buflenmax = mtu; + + return 0; +} + +void mcast_buffered_destroy(void) +{ + free(tx_buf); +} /* return 0 if it is not sent, otherwise return 1 */ int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, int len) @@ -101,8 +125,8 @@ int mcast_buffered_send_netmsg(struct mcast_sock *m, void *data, int len) struct nethdr *net = data; retry: - if (tx_buflen + len < sizeof(__tx_buf)) { - memcpy(__tx_buf + tx_buflen, net, len); + if (tx_buflen + len < tx_buflenmax) { + memcpy(tx_buf + tx_buflen, net, len); tx_buflen += len; } else { __do_send(m, tx_buf, tx_buflen); diff --git a/src/read_config_lex.l b/src/read_config_lex.l index dee90c9..87e98d1 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -42,7 +42,7 @@ ip6_part {hex_255}":"? ip6_form1 {ip6_part}{0,16}"::"{ip6_part}{0,16} ip6_form2 ({hex_255}":"){16}{hex_255} ip6 {ip6_form1}|{ip6_form2} -string [a-zA-Z]* +string [a-zA-Z0-9]* persistent [P|p][E|e][R|r][S|s][I|i][S|s][T|t][E|e][N|n][T|T] nack [N|n][A|a][C|c][K|k] @@ -52,6 +52,7 @@ nack [N|n][A|a][C|c][K|k] "IPv6_address" { return T_IPV6_ADDR; } "IPv4_interface" { return T_IPV4_IFACE; } "IPv6_interface" { return T_IPV6_IFACE; } +"Interface" { return T_IFACE; } "Port" { return T_PORT; } "Multicast" { return T_MULTICAST; } "HashSize" { return T_HASHSIZE; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 57250b4..de592d2 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -1,6 +1,6 @@ %{ /* - * (C) 2006 by Pablo Neira Ayuso <pablo@netfilter.org> + * (C) 2006-2007 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 by @@ -45,7 +45,7 @@ struct ct_conf conf; %token T_GENERAL T_SYNC T_STATS T_RELAX_TRANSITIONS T_BUFFER_SIZE T_DELAY %token T_SYNC_MODE T_LISTEN_TO T_FAMILY T_RESEND_BUFFER_SIZE %token T_PERSISTENT T_NACK T_CHECKSUM T_WINDOWSIZE T_ON T_OFF -%token T_REPLICATE T_FOR +%token T_REPLICATE T_FOR T_IFACE %token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN @@ -227,6 +227,11 @@ multicast_option : T_IPV6_IFACE T_IP conf.mcast.ipproto = AF_INET6; }; +multicast_option : T_IFACE T_STRING +{ + strncpy(conf.mcast.iface, $2, IFNAMSIZ); +}; + multicast_option : T_BACKLOG T_NUMBER { fprintf(stderr, "Notice: Backlog option inside Multicast clause is " diff --git a/src/sync-mode.c b/src/sync-mode.c index f30cb95..917a3b2 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -86,7 +86,7 @@ retry: static void mcast_handler() { int numbytes, remain; - char __net[4096], *ptr = __net; + char __net[65536], *ptr = __net; /* XXX: maximum MTU for IPv4 */ numbytes = mcast_recv(STATE_SYNC(mcast_server), __net, sizeof(__net)); if (numbytes <= 0) @@ -173,6 +173,11 @@ static int init_sync(void) return -1; } + if (mcast_buffered_init(&CONFIG(mcast)) == -1) { + dlog(STATE(log), "[FAIL] can't init tx buffer!"); + return -1; + } + /* initialization of multicast sequence generation */ STATE_SYNC(last_seq_sent) = time(NULL); @@ -207,6 +212,8 @@ static void kill_sync() mcast_server_destroy(STATE_SYNC(mcast_server)); mcast_client_destroy(STATE_SYNC(mcast_client)); + mcast_buffered_destroy(); + if (STATE_SYNC(sync)->kill) STATE_SYNC(sync)->kill(); } |