diff options
Diffstat (limited to 'cli/extensions')
-rw-r--r-- | cli/extensions/Makefile.am | 16 | ||||
-rw-r--r-- | cli/extensions/libct_proto_icmp.c | 108 | ||||
-rw-r--r-- | cli/extensions/libct_proto_icmp.man | 10 | ||||
-rw-r--r-- | cli/extensions/libct_proto_sctp.c | 164 | ||||
-rw-r--r-- | cli/extensions/libct_proto_tcp.c | 180 | ||||
-rw-r--r-- | cli/extensions/libct_proto_tcp.man | 16 | ||||
-rw-r--r-- | cli/extensions/libct_proto_udp.c | 141 | ||||
-rw-r--r-- | cli/extensions/libct_proto_udp.man | 13 |
8 files changed, 648 insertions, 0 deletions
diff --git a/cli/extensions/Makefile.am b/cli/extensions/Makefile.am new file mode 100644 index 0000000..5366ee3 --- /dev/null +++ b/cli/extensions/Makefile.am @@ -0,0 +1,16 @@ +include $(top_srcdir)/Make_global.am + +AM_CFLAGS=-fPIC -Wall +LIBS= + +pkglib_LTLIBRARIES = ct_proto_tcp.la ct_proto_udp.la \ + ct_proto_icmp.la ct_proto_sctp.la + +ct_proto_tcp_la_SOURCES = libct_proto_tcp.c +ct_proto_tcp_la_LDFLAGS = -module -avoid-version +ct_proto_udp_la_SOURCES = libct_proto_udp.c +ct_proto_udp_la_LDFLAGS = -module -avoid-version +ct_proto_icmp_la_SOURCES = libct_proto_icmp.c +ct_proto_icmp_la_LDFLAGS = -module -avoid-version +ct_proto_sctp_la_SOURCES = libct_proto_sctp.c +ct_proto_sctp_la_LDFLAGS = -module -avoid-version diff --git a/cli/extensions/libct_proto_icmp.c b/cli/extensions/libct_proto_icmp.c new file mode 100644 index 0000000..e7cb04d --- /dev/null +++ b/cli/extensions/libct_proto_icmp.c @@ -0,0 +1,108 @@ +/* + * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net> + * Harald Welte <laforge@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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include <stdio.h> +#include <getopt.h> +#include <stdlib.h> +#include <netinet/in.h> /* For htons */ +#include <netinet/ip_icmp.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack_icmp.h> +#include "conntrack.h" + +static struct option opts[] = { + {"icmp-type", 1, 0, '1'}, + {"icmp-code", 1, 0, '2'}, + {"icmp-id", 1, 0, '3'}, + {0, 0, 0, 0} +}; + +static void help() +{ + fprintf(stdout, "--icmp-type icmp type\n"); + fprintf(stdout, "--icmp-code icmp code\n"); + fprintf(stdout, "--icmp-id icmp id\n"); +} + +/* Add 1; spaces filled with 0. */ +static u_int8_t invmap[] + = { [ICMP_ECHO] = ICMP_ECHOREPLY + 1, + [ICMP_ECHOREPLY] = ICMP_ECHO + 1, + [ICMP_TIMESTAMP] = ICMP_TIMESTAMPREPLY + 1, + [ICMP_TIMESTAMPREPLY] = ICMP_TIMESTAMP + 1, + [ICMP_INFO_REQUEST] = ICMP_INFO_REPLY + 1, + [ICMP_INFO_REPLY] = ICMP_INFO_REQUEST + 1, + [ICMP_ADDRESS] = ICMP_ADDRESSREPLY + 1, + [ICMP_ADDRESSREPLY] = ICMP_ADDRESS + 1}; + +static int parse(char c, char *argv[], + struct nfct_tuple *orig, + struct nfct_tuple *reply, + struct nfct_tuple *exptuple, + struct nfct_tuple *mask, + union nfct_protoinfo *proto, + unsigned int *flags) +{ + switch(c) { + case '1': + if (optarg) { + orig->l4dst.icmp.type = atoi(optarg); + reply->l4dst.icmp.type = + invmap[orig->l4dst.icmp.type] - 1; + *flags |= ICMP_TYPE; + } + break; + case '2': + if (optarg) { + orig->l4dst.icmp.code = atoi(optarg); + reply->l4dst.icmp.code = 0; + *flags |= ICMP_CODE; + } + break; + case '3': + if (optarg) { + orig->l4src.icmp.id = htons(atoi(optarg)); + reply->l4dst.icmp.id = 0; + *flags |= ICMP_ID; + } + break; + } + return 1; +} + +static int final_check(unsigned int flags, + unsigned int command, + struct nfct_tuple *orig, + struct nfct_tuple *reply) +{ + if (!(flags & ICMP_TYPE)) + return 0; + else if (!(flags & ICMP_CODE)) + return 0; + + return 1; +} + +static struct ctproto_handler icmp = { + .name = "icmp", + .protonum = IPPROTO_ICMP, + .parse_opts = parse, + .final_check = final_check, + .help = help, + .opts = opts, + .version = VERSION, +}; + +static void __attribute__ ((constructor)) init(void); + +static void init(void) +{ + register_proto(&icmp); +} diff --git a/cli/extensions/libct_proto_icmp.man b/cli/extensions/libct_proto_icmp.man new file mode 100644 index 0000000..3b860d0 --- /dev/null +++ b/cli/extensions/libct_proto_icmp.man @@ -0,0 +1,10 @@ +This module matches on ICMP-specific fields. +.TP +.BI "--icmp-type " "TYPE" +ICMP Type. Has to be specified numerically. +.TP +.BI "--icmp-code " "CODE" +ICMP Code. Has to be specified numerically. +.TP +.BI "--icmp-id " "ID" +ICMP Id. Has to be specified numerically. diff --git a/cli/extensions/libct_proto_sctp.c b/cli/extensions/libct_proto_sctp.c new file mode 100644 index 0000000..1c8f0d1 --- /dev/null +++ b/cli/extensions/libct_proto_sctp.c @@ -0,0 +1,164 @@ +/* + * (C) 2005 by Harald Welte <laforge@netfilter.org> + * 2006 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include <stdio.h> +#include <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> /* For htons */ +#include "conntrack.h" +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack_sctp.h> + +static struct option opts[] = { + {"orig-port-src", 1, 0, '1'}, + {"orig-port-dst", 1, 0, '2'}, + {"reply-port-src", 1, 0, '3'}, + {"reply-port-dst", 1, 0, '4'}, + {"state", 1, 0, '5'}, + {"tuple-port-src", 1, 0, '6'}, + {"tuple-port-dst", 1, 0, '7'}, + {0, 0, 0, 0} +}; + +static const char *states[] = { + "NONE", + "CLOSED", + "COOKIE_WAIT", + "COOKIE_ECHOED", + "ESTABLISHED", + "SHUTDOWN_SENT", + "SHUTDOWN_RECV", + "SHUTDOWN_ACK_SENT", +}; + +static void help() +{ + fprintf(stdout, "--orig-port-src original source port\n"); + fprintf(stdout, "--orig-port-dst original destination port\n"); + fprintf(stdout, "--reply-port-src reply source port\n"); + fprintf(stdout, "--reply-port-dst reply destination port\n"); + fprintf(stdout, "--state SCTP state, fe. ESTABLISHED\n"); + fprintf(stdout, "--tuple-port-src expectation tuple src port\n"); + fprintf(stdout, "--tuple-port-src expectation tuple dst port\n"); +} + +static int parse_options(char c, char *argv[], + struct nfct_tuple *orig, + struct nfct_tuple *reply, + struct nfct_tuple *exptuple, + struct nfct_tuple *mask, + union nfct_protoinfo *proto, + unsigned int *flags) +{ + switch(c) { + case '1': + if (optarg) { + orig->l4src.sctp.port = htons(atoi(optarg)); + *flags |= SCTP_ORIG_SPORT; + } + break; + case '2': + if (optarg) { + orig->l4dst.sctp.port = htons(atoi(optarg)); + *flags |= SCTP_ORIG_DPORT; + } + break; + case '3': + if (optarg) { + reply->l4src.sctp.port = htons(atoi(optarg)); + *flags |= SCTP_REPL_SPORT; + } + break; + case '4': + if (optarg) { + reply->l4dst.sctp.port = htons(atoi(optarg)); + *flags |= SCTP_REPL_DPORT; + } + break; + case '5': + if (optarg) { + int i; + for (i=0; i<10; i++) { + if (strcmp(optarg, states[i]) == 0) { + /* FIXME: Add state to + * nfct_protoinfo + proto->sctp.state = i; */ + break; + } + } + if (i == 10) { + printf("doh?\n"); + return 0; + } + *flags |= SCTP_STATE; + } + break; + case '6': + if (optarg) { + exptuple->l4src.sctp.port = htons(atoi(optarg)); + *flags |= SCTP_EXPTUPLE_SPORT; + } + break; + case '7': + if (optarg) { + exptuple->l4dst.sctp.port = htons(atoi(optarg)); + *flags |= SCTP_EXPTUPLE_DPORT; + } + + } + return 1; +} + +static int final_check(unsigned int flags, + unsigned int command, + struct nfct_tuple *orig, + struct nfct_tuple *reply) +{ + int ret = 0; + + if ((flags & (SCTP_ORIG_SPORT|SCTP_ORIG_DPORT)) + && !(flags & (SCTP_REPL_SPORT|SCTP_REPL_DPORT))) { + reply->l4src.sctp.port = orig->l4dst.sctp.port; + reply->l4dst.sctp.port = orig->l4src.sctp.port; + ret = 1; + } else if (!(flags & (SCTP_ORIG_SPORT|SCTP_ORIG_DPORT)) + && (flags & (SCTP_REPL_SPORT|SCTP_REPL_DPORT))) { + orig->l4src.sctp.port = reply->l4dst.sctp.port; + orig->l4dst.sctp.port = reply->l4src.sctp.port; + ret = 1; + } + if ((flags & (SCTP_ORIG_SPORT|SCTP_ORIG_DPORT)) + && ((flags & (SCTP_REPL_SPORT|SCTP_REPL_DPORT)))) + ret = 1; + + /* --state is missing and we are trying to create a conntrack */ + if (ret && (command & CT_CREATE) && (!(flags & SCTP_STATE))) + ret = 0; + + return ret; +} + +static struct ctproto_handler sctp = { + .name = "sctp", + .protonum = IPPROTO_SCTP, + .parse_opts = parse_options, + .final_check = final_check, + .help = help, + .opts = opts, + .version = VERSION, +}; + +static void __attribute__ ((constructor)) init(void); + +static void init(void) +{ + register_proto(&sctp); +} diff --git a/cli/extensions/libct_proto_tcp.c b/cli/extensions/libct_proto_tcp.c new file mode 100644 index 0000000..ee24206 --- /dev/null +++ b/cli/extensions/libct_proto_tcp.c @@ -0,0 +1,180 @@ +/* + * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include <stdio.h> +#include <getopt.h> +#include <stdlib.h> +#include <string.h> +#include <netinet/in.h> /* For htons */ +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack_tcp.h> + +#include "conntrack.h" + +static struct option opts[] = { + {"orig-port-src", 1, 0, '1'}, + {"orig-port-dst", 1, 0, '2'}, + {"reply-port-src", 1, 0, '3'}, + {"reply-port-dst", 1, 0, '4'}, + {"mask-port-src", 1, 0, '5'}, + {"mask-port-dst", 1, 0, '6'}, + {"state", 1, 0, '7'}, + {"tuple-port-src", 1, 0, '8'}, + {"tuple-port-dst", 1, 0, '9'}, + {0, 0, 0, 0} +}; + +static const char *states[] = { + "NONE", + "SYN_SENT", + "SYN_RECV", + "ESTABLISHED", + "FIN_WAIT", + "CLOSE_WAIT", + "LAST_ACK", + "TIME_WAIT", + "CLOSE", + "LISTEN" +}; + +static void help() +{ + fprintf(stdout, "--orig-port-src original source port\n"); + fprintf(stdout, "--orig-port-dst original destination port\n"); + fprintf(stdout, "--reply-port-src reply source port\n"); + fprintf(stdout, "--reply-port-dst reply destination port\n"); + fprintf(stdout, "--mask-port-src mask source port\n"); + fprintf(stdout, "--mask-port-dst mask destination port\n"); + fprintf(stdout, "--tuple-port-src expectation tuple src port\n"); + fprintf(stdout, "--tuple-port-src expectation tuple dst port\n"); + fprintf(stdout, "--state TCP state, fe. ESTABLISHED\n"); +} + +static int parse_options(char c, char *argv[], + struct nfct_tuple *orig, + struct nfct_tuple *reply, + struct nfct_tuple *exptuple, + struct nfct_tuple *mask, + union nfct_protoinfo *proto, + unsigned int *flags) +{ + switch(c) { + case '1': + if (optarg) { + orig->l4src.tcp.port = htons(atoi(optarg)); + *flags |= TCP_ORIG_SPORT; + } + break; + case '2': + if (optarg) { + orig->l4dst.tcp.port = htons(atoi(optarg)); + *flags |= TCP_ORIG_DPORT; + } + break; + case '3': + if (optarg) { + reply->l4src.tcp.port = htons(atoi(optarg)); + *flags |= TCP_REPL_SPORT; + } + break; + case '4': + if (optarg) { + reply->l4dst.tcp.port = htons(atoi(optarg)); + *flags |= TCP_REPL_DPORT; + } + break; + case '5': + if (optarg) { + mask->l4src.tcp.port = htons(atoi(optarg)); + *flags |= TCP_MASK_SPORT; + } + break; + case '6': + if (optarg) { + mask->l4dst.tcp.port = htons(atoi(optarg)); + *flags |= TCP_MASK_DPORT; + } + break; + case '7': + if (optarg) { + int i; + for (i=0; i<10; i++) { + if (strcmp(optarg, states[i]) == 0) { + proto->tcp.state = i; + break; + } + } + if (i == 10) { + printf("doh?\n"); + return 0; + } + *flags |= TCP_STATE; + } + break; + case '8': + if (optarg) { + exptuple->l4src.tcp.port = htons(atoi(optarg)); + *flags |= TCP_EXPTUPLE_SPORT; + } + break; + case '9': + if (optarg) { + exptuple->l4dst.tcp.port = htons(atoi(optarg)); + *flags |= TCP_EXPTUPLE_DPORT; + } + break; + } + return 1; +} + +static int final_check(unsigned int flags, + unsigned int command, + struct nfct_tuple *orig, + struct nfct_tuple *reply) +{ + int ret = 0; + + if ((flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) + && !(flags & (TCP_REPL_SPORT|TCP_REPL_DPORT))) { + reply->l4src.tcp.port = orig->l4dst.tcp.port; + reply->l4dst.tcp.port = orig->l4src.tcp.port; + ret = 1; + } else if (!(flags & (TCP_ORIG_SPORT|TCP_ORIG_DPORT)) + && (flags & (TCP_REPL_SPORT|TCP_REPL_DPORT))) { + orig->l4src.tcp.port = reply->l4dst.tcp.port; + orig->l4dst.tcp.port = reply->l4src.tcp.port; + ret = 1; + } + 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; +} + +static struct ctproto_handler tcp = { + .name = "tcp", + .protonum = IPPROTO_TCP, + .parse_opts = parse_options, + .final_check = final_check, + .help = help, + .opts = opts, + .version = VERSION, +}; + +static void __attribute__ ((constructor)) init(void); + +static void init(void) +{ + register_proto(&tcp); +} diff --git a/cli/extensions/libct_proto_tcp.man b/cli/extensions/libct_proto_tcp.man new file mode 100644 index 0000000..41783f8 --- /dev/null +++ b/cli/extensions/libct_proto_tcp.man @@ -0,0 +1,16 @@ +This module matches on TCP-specific fields. +.TP +.BI "--orig-port-src " "PORT" +Source port in original direction +.TP +.BI "--orig-port-dst " "PORT" +Destination port in original direction +.TP +.BI "--reply-port-src " "PORT" +Source port in reply direction +.TP +.BI "--reply-port-dst " "PORT" +Destination port in reply direction +.TP +.BI "--state " "[NONE|SYN_SENT|SYN_RECV|ESTABLISHED|FIN_WAIT|CLOSE_WAIT|LAST_ACK|TIME_WAIT|CLOSE|LISTEN]" +TCP state diff --git a/cli/extensions/libct_proto_udp.c b/cli/extensions/libct_proto_udp.c new file mode 100644 index 0000000..48079e0 --- /dev/null +++ b/cli/extensions/libct_proto_udp.c @@ -0,0 +1,141 @@ +/* + * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net> + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#include <stdio.h> +#include <getopt.h> +#include <stdlib.h> +#include <netinet/in.h> /* For htons */ +#include "conntrack.h" +#include <libnetfilter_conntrack/libnetfilter_conntrack.h> +#include <libnetfilter_conntrack/libnetfilter_conntrack_udp.h> + +static struct option opts[] = { + {"orig-port-src", 1, 0, '1'}, + {"orig-port-dst", 1, 0, '2'}, + {"reply-port-src", 1, 0, '3'}, + {"reply-port-dst", 1, 0, '4'}, + {"mask-port-src", 1, 0, '5'}, + {"mask-port-dst", 1, 0, '6'}, + {"tuple-port-src", 1, 0, '7'}, + {"tuple-port-dst", 1, 0, '8'}, + {0, 0, 0, 0} +}; + +static void help() +{ + fprintf(stdout, "--orig-port-src original source port\n"); + fprintf(stdout, "--orig-port-dst original destination port\n"); + fprintf(stdout, "--reply-port-src reply source port\n"); + fprintf(stdout, "--reply-port-dst reply destination port\n"); + fprintf(stdout, "--mask-port-src mask source port\n"); + fprintf(stdout, "--mask-port-dst mask destination port\n"); + fprintf(stdout, "--tuple-port-src expectation tuple src port\n"); + fprintf(stdout, "--tuple-port-src expectation tuple dst port\n"); +} + +static int parse_options(char c, char *argv[], + struct nfct_tuple *orig, + struct nfct_tuple *reply, + struct nfct_tuple *exptuple, + struct nfct_tuple *mask, + union nfct_protoinfo *proto, + unsigned int *flags) +{ + switch(c) { + case '1': + if (optarg) { + orig->l4src.udp.port = htons(atoi(optarg)); + *flags |= UDP_ORIG_SPORT; + } + break; + case '2': + if (optarg) { + orig->l4dst.udp.port = htons(atoi(optarg)); + *flags |= UDP_ORIG_DPORT; + } + break; + case '3': + if (optarg) { + reply->l4src.udp.port = htons(atoi(optarg)); + *flags |= UDP_REPL_SPORT; + } + break; + case '4': + if (optarg) { + reply->l4dst.udp.port = htons(atoi(optarg)); + *flags |= UDP_REPL_DPORT; + } + break; + case '5': + if (optarg) { + mask->l4src.udp.port = htons(atoi(optarg)); + *flags |= UDP_MASK_SPORT; + } + break; + case '6': + if (optarg) { + mask->l4dst.udp.port = htons(atoi(optarg)); + *flags |= UDP_MASK_DPORT; + } + break; + case '7': + if (optarg) { + exptuple->l4src.udp.port = htons(atoi(optarg)); + *flags |= UDP_EXPTUPLE_SPORT; + } + break; + case '8': + if (optarg) { + exptuple->l4dst.udp.port = htons(atoi(optarg)); + *flags |= UDP_EXPTUPLE_DPORT; + } + + } + return 1; +} + +static int final_check(unsigned int flags, + unsigned int command, + struct nfct_tuple *orig, + struct nfct_tuple *reply) +{ + if ((flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) + && !(flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))) { + reply->l4src.udp.port = orig->l4dst.udp.port; + reply->l4dst.udp.port = orig->l4src.udp.port; + return 1; + } else if (!(flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) + && (flags & (UDP_REPL_SPORT|UDP_REPL_DPORT))) { + orig->l4src.udp.port = reply->l4dst.udp.port; + orig->l4dst.udp.port = reply->l4src.udp.port; + return 1; + } + if ((flags & (UDP_ORIG_SPORT|UDP_ORIG_DPORT)) + && ((flags & (UDP_REPL_SPORT|UDP_REPL_DPORT)))) + return 1; + + return 0; +} + +static struct ctproto_handler udp = { + .name = "udp", + .protonum = IPPROTO_UDP, + .parse_opts = parse_options, + .final_check = final_check, + .help = help, + .opts = opts, + .version = VERSION, +}; + +static void __attribute__ ((constructor)) init(void); + +static void init(void) +{ + register_proto(&udp); +} diff --git a/cli/extensions/libct_proto_udp.man b/cli/extensions/libct_proto_udp.man new file mode 100644 index 0000000..c67fedf --- /dev/null +++ b/cli/extensions/libct_proto_udp.man @@ -0,0 +1,13 @@ +This module matches on UDP-specific fields. +.TP +.BI "--orig-port-src " "PORT" +Source port in original direction +.TP +.BI "--orig-port-dst " "PORT" +Destination port in original direction +.TP +.BI "--reply-port-src " "PORT" +Source port in reply direction +.TP +.BI "--reply-port-dst " "PORT" +Destination port in reply direction |