From 9ab85762233756f1e828f7c4c6007d25ac26f494 Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org" Date: Tue, 12 Jul 2005 23:24:06 +0000 Subject: o Use conntrack netlink attributes: Major change o Kill action setting: Mask based dumping --- extensions/libct_proto_icmp.c | 31 +++++------ extensions/libct_proto_sctp.c | 108 ++++++++++++++++++++++++-------------- extensions/libct_proto_tcp.c | 118 ++++++++++++++++++++++++++++++------------ extensions/libct_proto_udp.c | 94 ++++++++++++++++++++++++--------- 4 files changed, 240 insertions(+), 111 deletions(-) (limited to 'extensions') diff --git a/extensions/libct_proto_icmp.c b/extensions/libct_proto_icmp.c index 6a2db92..24d3d3f 100644 --- a/extensions/libct_proto_icmp.c +++ b/extensions/libct_proto_icmp.c @@ -11,8 +11,6 @@ #include #include #include /* For htons */ -#include -#include #include "libct_proto.h" static struct option opts[] = { @@ -41,27 +39,28 @@ void help() } int parse(char c, char *argv[], - struct ip_conntrack_tuple *orig, - struct ip_conntrack_tuple *reply, - union ip_conntrack_proto *proto, + struct ctnl_tuple *orig, + struct ctnl_tuple *reply, + struct ctnl_tuple *mask, + union ctnl_protoinfo *proto, unsigned int *flags) { switch(c) { case '1': if (optarg) { - orig->dst.u.icmp.type = atoi(optarg); + orig->l4dst.icmp.type = atoi(optarg); *flags |= ICMP_TYPE; } break; case '2': if (optarg) { - orig->dst.u.icmp.code = atoi(optarg); + orig->l4dst.icmp.code = atoi(optarg); *flags |= ICMP_CODE; } break; case '3': if (optarg) { - reply->src.u.icmp.id = atoi(optarg); + orig->l4src.icmp.id = atoi(optarg); *flags |= ICMP_ID; } break; @@ -69,7 +68,9 @@ int parse(char c, char *argv[], return 1; } -int final_check(unsigned int flags) +int final_check(unsigned int flags, + struct ctnl_tuple *orig, + struct ctnl_tuple *reply) { if (!(flags & ICMP_TYPE)) return 0; @@ -79,18 +80,18 @@ int final_check(unsigned int flags) return 1; } -void print_tuple(struct ip_conntrack_tuple *t) +void print_proto(struct ctnl_tuple *t) { - fprintf(stdout, "type=%d code=%d id=%d ", t->dst.u.icmp.type, - t->dst.u.icmp.code, - t->src.u.icmp.id); + fprintf(stdout, "type=%d code=%d id=%d", t->l4dst.icmp.type, + t->l4dst.icmp.code, + t->l4src.icmp.id); } static struct ctproto_handler icmp = { .name = "icmp", .protonum = 1, - .parse = parse, - .print_tuple = print_tuple, + .parse_opts = parse, + .print_proto = print_proto, .final_check = final_check, .help = help, .opts = opts diff --git a/extensions/libct_proto_sctp.c b/extensions/libct_proto_sctp.c index b84c2ba..5b50fbc 100644 --- a/extensions/libct_proto_sctp.c +++ b/extensions/libct_proto_sctp.c @@ -1,26 +1,26 @@ /* - * (C) 2005 by Harald Welte + * (C) 2005 by Harald Welte * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation + * 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 #include #include -#include #include /* For htons */ -#include -#include +#include #include "libct_proto.h" +#include "libctnetlink.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'}, + {"state", 1, 0, '7'}, {0, 0, 0, 0} }; @@ -52,43 +52,44 @@ static const char *states[] = { "SHUTDOWN_ACK_SENT", }; -static void help() +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, eg. ESTABLISHED\n"); + fprintf(stdout, "--state SCTP state, fe. ESTABLISHED\n"); } -static int parse(char c, char *argv[], - struct ip_conntrack_tuple *orig, - struct ip_conntrack_tuple *reply, - union ip_conntrack_proto *proto, - unsigned int *flags) +int parse_options(char c, char *argv[], + struct ctnl_tuple *orig, + struct ctnl_tuple *reply, + struct ctnl_tuple *mask, + union ctnl_protoinfo *proto, + unsigned int *flags) { switch(c) { case '1': if (optarg) { - orig->src.u.sctp.port = htons(atoi(optarg)); + orig->l4src.sctp.port = htons(atoi(optarg)); *flags |= ORIG_SPORT; } break; case '2': if (optarg) { - orig->dst.u.sctp.port = htons(atoi(optarg)); + orig->l4dst.sctp.port = htons(atoi(optarg)); *flags |= ORIG_DPORT; } break; case '3': if (optarg) { - reply->src.u.sctp.port = htons(atoi(optarg)); + reply->l4src.sctp.port = htons(atoi(optarg)); *flags |= REPL_SPORT; } break; case '4': if (optarg) { - reply->dst.u.sctp.port = htons(atoi(optarg)); + reply->l4dst.sctp.port = htons(atoi(optarg)); *flags |= REPL_DPORT; } break; @@ -97,7 +98,9 @@ static int parse(char c, char *argv[], int i; for (i=0; i<10; i++) { if (strcmp(optarg, states[i]) == 0) { - proto->sctp.state = i; + /* FIXME: Add state to + * ctnl_protoinfo + proto->sctp.state = i; */ break; } } @@ -111,39 +114,68 @@ static int parse(char c, char *argv[], return 1; } -static int final_check(unsigned int flags) +int final_check(unsigned int flags, + struct ctnl_tuple *orig, + struct ctnl_tuple *reply) { - if ((flags & ORIG_SPORT) && (flags & ORIG_DPORT)) + if ((flags & (ORIG_SPORT|ORIG_DPORT)) + && !(flags & (REPL_SPORT|REPL_DPORT))) { + reply->l4src.sctp.port = orig->l4dst.sctp.port; + reply->l4dst.sctp.port = orig->l4src.sctp.port; return 1; - else if ((flags & REPL_SPORT) && (flags & REPL_DPORT)) + } else if (!(flags & (ORIG_SPORT|ORIG_DPORT)) + && (flags & (REPL_SPORT|REPL_DPORT))) { + orig->l4src.sctp.port = reply->l4dst.sctp.port; + orig->l4dst.sctp.port = reply->l4src.sctp.port; + return 1; + } + if ((flags & (ORIG_SPORT|ORIG_DPORT)) + && ((flags & (REPL_SPORT|REPL_DPORT)))) return 1; return 0; } -static void print_tuple(struct ip_conntrack_tuple *t) +void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple) +{ + if (cda[CTA_PROTO_SCTP_SRC-1]) + tuple->l4src.sctp.port = + *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_SCTP_SRC-1]); + if (cda[CTA_PROTO_SCTP_DST-1]) + tuple->l4dst.sctp.port = + *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_SCTP_DST-1]); +} + +void parse_protoinfo(struct nfattr *cda[], struct ctnl_conntrack *ct) +{ +/* if (cda[CTA_PROTOINFO_SCTP_STATE-1]) + ct->protoinfo.sctp.state = + *(u_int8_t *)NFA_DATA(cda[CTA_PROTOINFO_SCTP_STATE-1]); +*/ +} + +void print_protoinfo(union ctnl_protoinfo *protoinfo) { - fprintf(stdout, "sport=%d dport=%d ", ntohs(t->src.u.sctp.port), - ntohs(t->dst.u.sctp.port)); +/* fprintf(stdout, "%s ", states[protoinfo->sctp.state]); */ } -static void print_proto(union ip_conntrack_proto *proto) +void print_proto(struct ctnl_tuple *tuple) { - if (proto->sctp.state > sizeof(states)/sizeof(char *)) - fprintf(stdout, "[%u] ", proto->sctp.state); - else - fprintf(stdout, "[%s] ", states[proto->sctp.state]); + fprintf(stdout, "sport=%u dport=%u ", htons(tuple->l4src.sctp.port), + htons(tuple->l4dst.sctp.port)); } static struct ctproto_handler sctp = { - .name = "sctp", - .protonum = 132, - .parse = parse, - .print_tuple = print_tuple, - .print_proto = print_proto, - .final_check = final_check, - .help = help, - .opts = opts, + .name = "sctp", + .protonum = 132, + .parse_opts = parse_options, + .parse_protoinfo = parse_protoinfo, + .parse_proto = parse_proto, + .print_proto = print_proto, + .print_protoinfo = print_protoinfo, + .final_check = final_check, + .help = help, + .opts = opts }; void __attribute__ ((constructor)) init(void); diff --git a/extensions/libct_proto_tcp.c b/extensions/libct_proto_tcp.c index 45ee29b..5fa3652 100644 --- a/extensions/libct_proto_tcp.c +++ b/extensions/libct_proto_tcp.c @@ -10,18 +10,19 @@ #include #include #include -#include #include /* For htons */ -#include -#include +#include #include "libct_proto.h" +#include "libctnetlink.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'}, + {"mask-port-src", 1, 0, '5'}, + {"mask-port-dst", 1, 0, '6'}, + {"state", 1, 0, '7'}, {0, 0, 0, 0} }; @@ -38,7 +39,13 @@ enum tcp_param_flags { REPL_DPORT_BIT = 3, REPL_DPORT = (1 << REPL_DPORT_BIT), - STATE_BIT = 4, + MASK_SPORT_BIT = 4, + MASK_SPORT = (1 << MASK_SPORT_BIT), + + MASK_DPORT_BIT = 5, + MASK_DPORT = (1 << MASK_DPORT_BIT), + + STATE_BIT = 6, STATE = (1 << STATE_BIT) }; @@ -55,47 +62,62 @@ static const char *states[] = { "LISTEN" }; -static void help() +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, "--state TCP state, fe. ESTABLISHED\n"); } -static int parse(char c, char *argv[], - struct ip_conntrack_tuple *orig, - struct ip_conntrack_tuple *reply, - union ip_conntrack_proto *proto, - unsigned int *flags) +int parse_options(char c, char *argv[], + struct ctnl_tuple *orig, + struct ctnl_tuple *reply, + struct ctnl_tuple *mask, + union ctnl_protoinfo *proto, + unsigned int *flags) { switch(c) { case '1': if (optarg) { - orig->src.u.tcp.port = htons(atoi(optarg)); + orig->l4src.tcp.port = htons(atoi(optarg)); *flags |= ORIG_SPORT; } break; case '2': if (optarg) { - orig->dst.u.tcp.port = htons(atoi(optarg)); + orig->l4dst.tcp.port = htons(atoi(optarg)); *flags |= ORIG_DPORT; } break; case '3': if (optarg) { - reply->src.u.tcp.port = htons(atoi(optarg)); + reply->l4src.tcp.port = htons(atoi(optarg)); *flags |= REPL_SPORT; } break; case '4': if (optarg) { - reply->dst.u.tcp.port = htons(atoi(optarg)); + reply->l4dst.tcp.port = htons(atoi(optarg)); *flags |= REPL_DPORT; } break; case '5': + if (optarg) { + mask->l4src.tcp.port = htons(atoi(optarg)); + *flags |= MASK_SPORT; + } + break; + case '6': + if (optarg) { + mask->l4src.tcp.port = htons(atoi(optarg)); + *flags |= MASK_DPORT; + } + break; + case '7': if (optarg) { int i; for (i=0; i<10; i++) { @@ -114,39 +136,67 @@ static int parse(char c, char *argv[], return 1; } -static int final_check(unsigned int flags) +int final_check(unsigned int flags, + struct ctnl_tuple *orig, + struct ctnl_tuple *reply) { - if ((flags & ORIG_SPORT) && (flags & ORIG_DPORT)) + if ((flags & (ORIG_SPORT|ORIG_DPORT)) + && !(flags & (REPL_SPORT|REPL_DPORT))) { + reply->l4src.tcp.port = orig->l4dst.tcp.port; + reply->l4dst.tcp.port = orig->l4src.tcp.port; return 1; - else if ((flags & REPL_SPORT) && (flags & REPL_DPORT)) + } else if (!(flags & (ORIG_SPORT|ORIG_DPORT)) + && (flags & (REPL_SPORT|REPL_DPORT))) { + orig->l4src.tcp.port = reply->l4dst.tcp.port; + orig->l4dst.tcp.port = reply->l4src.tcp.port; + return 1; + } + if ((flags & (ORIG_SPORT|ORIG_DPORT)) + && ((flags & (REPL_SPORT|REPL_DPORT)))) return 1; return 0; } -static void print_tuple(struct ip_conntrack_tuple *t) +void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple) +{ + if (cda[CTA_PROTO_TCP_SRC-1]) + tuple->l4src.tcp.port = + *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_TCP_SRC-1]); + if (cda[CTA_PROTO_TCP_DST-1]) + tuple->l4dst.tcp.port = + *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_TCP_DST-1]); +} + +void parse_protoinfo(struct nfattr *cda[], struct ctnl_conntrack *ct) +{ + if (cda[CTA_PROTOINFO_TCP_STATE-1]) + ct->protoinfo.tcp.state = + *(u_int8_t *)NFA_DATA(cda[CTA_PROTOINFO_TCP_STATE-1]); +} + +void print_protoinfo(union ctnl_protoinfo *protoinfo) { - fprintf(stdout, "sport=%d dport=%d ", ntohs(t->src.u.tcp.port), - ntohs(t->dst.u.tcp.port)); + fprintf(stdout, "%s ", states[protoinfo->tcp.state]); } -static void print_proto(union ip_conntrack_proto *proto) +void print_proto(struct ctnl_tuple *tuple) { - if (proto->tcp.state > sizeof(states)/sizeof(char *)) - fprintf(stdout, "[%u] ", states[proto->tcp.state]); - else - fprintf(stdout, "[%s] ", states[proto->tcp.state]); + fprintf(stdout, "sport=%u dport=%u ", htons(tuple->l4src.tcp.port), + htons(tuple->l4dst.tcp.port)); } static struct ctproto_handler tcp = { - .name = "tcp", - .protonum = 6, - .parse = parse, - .print_tuple = print_tuple, - .print_proto = print_proto, - .final_check = final_check, - .help = help, - .opts = opts, + .name = "tcp", + .protonum = 6, + .parse_opts = parse_options, + .parse_protoinfo = parse_protoinfo, + .parse_proto = parse_proto, + .print_proto = print_proto, + .print_protoinfo = print_protoinfo, + .final_check = final_check, + .help = help, + .opts = opts }; void __attribute__ ((constructor)) init(void); diff --git a/extensions/libct_proto_udp.c b/extensions/libct_proto_udp.c index 0088cc5..aa733f0 100644 --- a/extensions/libct_proto_udp.c +++ b/extensions/libct_proto_udp.c @@ -11,15 +11,17 @@ #include #include #include /* For htons */ -#include -#include +#include #include "libct_proto.h" +#include "libctnetlink.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'}, {0, 0, 0, 0} }; @@ -35,6 +37,12 @@ enum udp_param_flags { REPL_DPORT_BIT = 3, REPL_DPORT = (1 << REPL_DPORT_BIT), + + MASK_SPORT_BIT = 4, + MASK_SPORT = (1 << MASK_SPORT_BIT), + + MASK_DPORT_BIT = 5, + MASK_DPORT = (1 << MASK_DPORT_BIT), }; void help() @@ -43,67 +51,105 @@ void help() 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"); } -int parse(char c, char *argv[], - struct ip_conntrack_tuple *orig, - struct ip_conntrack_tuple *reply, - union ip_conntrack_proto *proto, - unsigned int *flags) +int parse_options(char c, char *argv[], + struct ctnl_tuple *orig, + struct ctnl_tuple *reply, + struct ctnl_tuple *mask, + union ctnl_protoinfo *proto, + unsigned int *flags) { switch(c) { case '1': if (optarg) { - orig->src.u.udp.port = htons(atoi(optarg)); + orig->l4src.udp.port = htons(atoi(optarg)); *flags |= ORIG_SPORT; } break; case '2': if (optarg) { - orig->dst.u.udp.port = htons(atoi(optarg)); + orig->l4dst.udp.port = htons(atoi(optarg)); *flags |= ORIG_DPORT; } break; case '3': if (optarg) { - reply->src.u.udp.port = htons(atoi(optarg)); + reply->l4src.udp.port = htons(atoi(optarg)); *flags |= REPL_SPORT; } break; case '4': if (optarg) { - reply->dst.u.udp.port = htons(atoi(optarg)); + reply->l4dst.udp.port = htons(atoi(optarg)); *flags |= REPL_DPORT; } break; + case '5': + if (optarg) { + mask->l4src.udp.port = htons(atoi(optarg)); + *flags |= MASK_SPORT; + } + break; + case '6': + if (optarg) { + mask->l4src.udp.port = htons(atoi(optarg)); + *flags |= MASK_DPORT; + } + break; } return 1; } -int final_check(unsigned int flags) +int final_check(unsigned int flags, + struct ctnl_tuple *orig, + struct ctnl_tuple *reply) { - if ((flags & ORIG_SPORT) && (flags & ORIG_DPORT)) + if ((flags & (ORIG_SPORT|ORIG_DPORT)) + && !(flags & (REPL_SPORT|REPL_DPORT))) { + reply->l4src.udp.port = orig->l4dst.udp.port; + reply->l4dst.udp.port = orig->l4src.udp.port; + return 1; + } else if (!(flags & (ORIG_SPORT|ORIG_DPORT)) + && (flags & (REPL_SPORT|REPL_DPORT))) { + orig->l4src.udp.port = reply->l4dst.udp.port; + orig->l4dst.udp.port = reply->l4src.udp.port; return 1; - else if ((flags & REPL_SPORT) && (flags & REPL_DPORT)) + } + if ((flags & (ORIG_SPORT|ORIG_DPORT)) + && ((flags & (REPL_SPORT|REPL_DPORT)))) return 1; return 0; } -void print_tuple(struct ip_conntrack_tuple *t) +void parse_proto(struct nfattr *cda[], struct ctnl_tuple *tuple) +{ + if (cda[CTA_PROTO_UDP_SRC-1]) + tuple->l4src.udp.port = + *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_UDP_SRC-1]); + if (cda[CTA_PROTO_UDP_DST-1]) + tuple->l4dst.udp.port = + *(u_int16_t *)NFA_DATA(cda[CTA_PROTO_UDP_DST-1]); +} + +void print_proto(struct ctnl_tuple *tuple) { - fprintf(stdout, "sport=%d dport=%d ", ntohs(t->src.u.udp.port), - ntohs(t->dst.u.udp.port)); + fprintf(stdout, "sport=%u dport=%u ", htons(tuple->l4src.udp.port), + htons(tuple->l4dst.udp.port)); } static struct ctproto_handler udp = { - .name = "udp", - .protonum = 17, - .parse = parse, - .print_tuple = print_tuple, - .final_check = final_check, - .help = help, - .opts = opts + .name = "udp", + .protonum = 17, + .parse_opts = parse_options, + .parse_proto = parse_proto, + .print_proto = print_proto, + .final_check = final_check, + .help = help, + .opts = opts }; void __attribute__ ((constructor)) init(void); -- cgit v1.2.3