From 8aa719eb1afb6c6e0a5bf74cbdab79dc82da6c80 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: Mon, 26 Dec 2005 02:29:02 +0000 Subject: o add IPv6 support o clean up layer-4 compare functions o finish the comparison infrastructure: support for tuple/mark matching o fix bug in the default event display when used in conjunction with the comparison infrastructure. o Bumped version to 0.0.30 Thanks to Yasuyuki Kozakai for: [LIBNETFILTER_CONNTRACK] fix dumping IPv6 connections that in included in this commit. --- l3extensions/Makefile.am | 16 ++++ l3extensions/libnetfilter_conntrack_ipv4.c | 94 +++++++++++++++++++++++ l3extensions/libnetfilter_conntrack_ipv6.c | 115 +++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 l3extensions/Makefile.am create mode 100644 l3extensions/libnetfilter_conntrack_ipv4.c create mode 100644 l3extensions/libnetfilter_conntrack_ipv6.c (limited to 'l3extensions') diff --git a/l3extensions/Makefile.am b/l3extensions/Makefile.am new file mode 100644 index 0000000..fa21b2d --- /dev/null +++ b/l3extensions/Makefile.am @@ -0,0 +1,16 @@ +include $(top_srcdir)/Make_global.am + +AUTOMAKE_OPTIONS = no-dependencies foreign + +AM_CFLAGS=-fPIC -Wall +LIBS= + +pkglib_LTLIBRARIES = nfct_l3proto_ipv4.la nfct_l3proto_ipv6.la + +nfct_l3proto_ipv4_la_SOURCES = libnetfilter_conntrack_ipv4.c +nfct_l3proto_ipv4_la_LDFLAGS = -module -avoid-version -release $(VERSION) +nfct_l3proto_ipv4_la_LIBADD = ../src/libnetfilter_conntrack.la + +nfct_l3proto_ipv6_la_SOURCES = libnetfilter_conntrack_ipv6.c +nfct_l3proto_ipv6_la_LDFLAGS = -module -avoid-version -release $(VERSION) +nfct_l3proto_ipv6_la_LIBADD = ../src/libnetfilter_conntrack.la diff --git a/l3extensions/libnetfilter_conntrack_ipv4.c b/l3extensions/libnetfilter_conntrack_ipv4.c new file mode 100644 index 0000000..727ea01 --- /dev/null +++ b/l3extensions/libnetfilter_conntrack_ipv4.c @@ -0,0 +1,94 @@ +/* + * (C) 2005 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include /* For htons */ +#include +#include +#include +#include + +static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple) +{ + if (cda[CTA_IP_V4_SRC-1]) + tuple->src.v4 = *(u_int32_t *)NFA_DATA(cda[CTA_IP_V4_SRC-1]); + + if (cda[CTA_IP_V4_DST-1]) + tuple->dst.v4 = *(u_int32_t *)NFA_DATA(cda[CTA_IP_V4_DST-1]); +} + +static void build_tuple_proto(struct nfnlhdr *req, int size, + struct nfct_tuple *t) +{ + nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4, + sizeof(u_int32_t)); + nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4, + sizeof(u_int32_t)); +} + +static int print_proto(char *buf, struct nfct_tuple *tuple) +{ + struct in_addr src = { .s_addr = tuple->src.v4 }; + struct in_addr dst = { .s_addr = tuple->dst.v4 }; + int size; + + size = sprintf(buf, "src=%s ", inet_ntoa(src)); + size += sprintf(buf+size, "dst=%s ", inet_ntoa(dst)); + + return size; +} + +static int compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int flags) +{ + if (flags & IPV4_ORIG) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum != + ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum) + return 0; + if (flags & IPV4_REPL) + if (ct1->tuple[NFCT_DIR_REPLY].l3protonum != + ct2->tuple[NFCT_DIR_REPLY].l3protonum) + return 0; + if (flags & IPV4_ORIG_SRC) + if (ct1->tuple[NFCT_DIR_ORIGINAL].src.v4 != + ct2->tuple[NFCT_DIR_ORIGINAL].src.v4) + return 0; + if (flags & IPV4_ORIG_DST) + if (ct1->tuple[NFCT_DIR_ORIGINAL].dst.v4 != + ct2->tuple[NFCT_DIR_ORIGINAL].dst.v4) + return 0; + if (flags & IPV4_REPL_SRC) + if (ct1->tuple[NFCT_DIR_REPLY].src.v4 != + ct2->tuple[NFCT_DIR_REPLY].src.v4) + return 0; + if (flags & IPV4_REPL_DST) + if (ct1->tuple[NFCT_DIR_REPLY].dst.v4 != + ct2->tuple[NFCT_DIR_REPLY].dst.v4) + return 0; + + return 1; +} + +static struct nfct_l3proto ipv4 = { + .name = "ipv4", + .protonum = AF_INET, + .parse_proto = parse_proto, + .build_tuple_proto = build_tuple_proto, + .print_proto = print_proto, + .compare = compare, + .version = VERSION +}; + +static void __attribute__ ((constructor)) init(void); + +static void init(void) +{ + nfct_register_l3proto(&ipv4); +} diff --git a/l3extensions/libnetfilter_conntrack_ipv6.c b/l3extensions/libnetfilter_conntrack_ipv6.c new file mode 100644 index 0000000..b0c7a3f --- /dev/null +++ b/l3extensions/libnetfilter_conntrack_ipv6.c @@ -0,0 +1,115 @@ +/* + * (C) 2005 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 + * 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 +#include + +#ifndef HAVE_INET_NTOP_IPV6 +#warning "inet_ntop does not support IPv6" +#endif + +static void parse_proto(struct nfattr *cda[], struct nfct_tuple *tuple) +{ + if (cda[CTA_IP_V6_SRC-1]) + memcpy(tuple->src.v6, NFA_DATA(cda[CTA_IP_V6_SRC-1]), + sizeof(u_int32_t)*4); + + if (cda[CTA_IP_V6_DST-1]) + memcpy(tuple->dst.v6, NFA_DATA(cda[CTA_IP_V6_DST-1]), + sizeof(u_int32_t)*4); +} + +static void build_tuple_proto(struct nfnlhdr *req, int size, + struct nfct_tuple *t) +{ + nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_SRC, &t->src.v6, + sizeof(u_int32_t)*4); + nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_DST, &t->dst.v6, + sizeof(u_int32_t)*4); +} + +static int print_proto(char *buf, struct nfct_tuple *tuple) +{ + struct in6_addr src; + struct in6_addr dst; + char tmp[INET6_ADDRSTRLEN]; + int size; + + memcpy(&src.in6_u, tuple->src.v6, sizeof(struct in6_addr)); + memcpy(&dst.in6_u, tuple->dst.v6, sizeof(struct in6_addr)); + + if (!inet_ntop(AF_INET6, &src, tmp, sizeof(tmp))) + return 0; + size = sprintf(buf, "src=%s ", tmp); + if (!inet_ntop(AF_INET6, &dst, tmp, sizeof(tmp))) + return 0; + size += sprintf(buf + size, "dst=%s ", tmp); + + return size; +} + +static int compare(struct nfct_conntrack *ct1, + struct nfct_conntrack *ct2, + unsigned int flags) +{ + if (flags & IPV6_ORIG) + if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum != + ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum) + return 0; + if (flags & IPV6_REPL) + if (ct1->tuple[NFCT_DIR_REPLY].l3protonum != + ct2->tuple[NFCT_DIR_REPLY].l3protonum) + return 0; + if (flags & IPV6_ORIG_SRC) + if (memcmp(ct1->tuple[NFCT_DIR_ORIGINAL].src.v6, + ct2->tuple[NFCT_DIR_ORIGINAL].src.v6, + sizeof(u_int32_t)*4) == 0) + return 0; + if (flags & IPV6_ORIG_DST) + if (memcmp(ct1->tuple[NFCT_DIR_ORIGINAL].dst.v6, + ct2->tuple[NFCT_DIR_ORIGINAL].dst.v6, + sizeof(u_int32_t)*4) == 0) + return 0; + if (flags & IPV6_REPL_SRC) + if (memcmp(ct1->tuple[NFCT_DIR_REPLY].src.v6, + ct2->tuple[NFCT_DIR_REPLY].src.v6, + sizeof(u_int32_t)*4) == 0) + return 0; + if (flags & IPV6_REPL_DST) + if (memcmp(ct1->tuple[NFCT_DIR_REPLY].dst.v6, + ct2->tuple[NFCT_DIR_REPLY].dst.v6, + sizeof(u_int32_t)*4) == 0) + return 0; + + return 1; +} + +static struct nfct_l3proto ipv6 = { + .name = "ipv6", + .protonum = AF_INET6, + .parse_proto = parse_proto, + .build_tuple_proto = build_tuple_proto, + .print_proto = print_proto, + .compare = compare, + .version = VERSION +}; + +static void __attribute__ ((constructor)) init(void); + +static void init(void) +{ + nfct_register_l3proto(&ipv6); +} -- cgit v1.2.3