From 18bbf19becaab7dc4137406928f96ad089192f69 Mon Sep 17 00:00:00 2001 From: "/C=EU/ST=EU/CN=Pablo Neira Ayuso/emailAddress=pablo@netfilter.org" Date: Wed, 18 Jul 2007 20:04:00 +0000 Subject: 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 --- src/conntrack.c | 108 ++++++++++++++++++++++---------------------------- src/mcast.c | 14 +++++++ src/network.c | 32 +++++++++++++-- src/read_config_lex.l | 3 +- src/read_config_yy.y | 9 ++++- src/sync-mode.c | 9 ++++- 6 files changed, 107 insertions(+), 68 deletions(-) (limited to 'src') 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< illegal, 1 => legal, 0 => undecided. */ + for (i = 0; i < NUMBER_OF_CMD; i++) + if (command & (1<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 #include #include +#include +#include #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 + * (C) 2006-2007 by Pablo Neira Ayuso * * 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(); } -- cgit v1.2.3