netfilter-titan/testproject/NetfilterConntrack.cc

115 lines
3.6 KiB
C++

/* netfilter connection tracking functions for Eclipse Titan
* (C) 2017 by Harald Welte <laforge@gnumonks.org>
* Licensed under Eclipse Public License - v1.0 or GPLv2, at your choice */
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
#include "NetfilterConntrack_Functions.hh"
namespace NetfilterConntrack__Functions
{
/* call-back function called for every matching conntrack entry */
static int cb(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data)
{
CHARSTRING *ret_val = (CHARSTRING *) data;
char buf[1024];
nfct_snprintf(buf, sizeof(buf), ct, NFCT_T_UNKNOWN, NFCT_O_XML, NFCT_OF_SHOW_LAYER3 | NFCT_OF_TIMESTAMP);
//printf(buf);
*ret_val += buf;
return NFCT_CB_CONTINUE;
}
struct nfct_handle *_nfct_init(CHARSTRING *ret_val)
{
struct nfct_handle *h;
h = nfct_open(CONNTRACK, 0);
if (!h) {
TTCN_error("nfct_open");
return NULL;
}
nfct_callback_register(h, NFCT_T_ALL, cb, (void *) ret_val);
return h;
}
/* external function exposed to TTCN3 */
CHARSTRING f__get__conntracks__xml(void)
{
#if 0
const char *flow = "<flow xmlns=\"http://www.netfilter.org/xml/libnetfilter_conntrack\"><meta direction=\"original\"><layer3 protonum=\"2\" protoname=\"ipv4\"><src>100.86.194.120</src><dst>195.238.226.19</dst></layer3><layer4 protonum=\"6\" protoname=\"tcp\"><sport>50528</sport><dport>443</dport></layer4></meta><meta direction=\"reply\"><layer3 protonum=\"2\" protoname=\"ipv4\"><src>195.238.226.19</src><dst>100.86.194.120</dst></layer3><layer4 protonum=\"6\" protoname=\"tcp\"><sport>443</sport><dport>50528</dport></layer4></meta><meta direction=\"independent\"><state>ESTABLISHED</state><timeout>423663</timeout><mark>0</mark><use>1</use><id>477116416</id><assured/></meta></flow>";
CHARSTRING ret_val(strlen(flow), flow);
return ret_val;
#else
struct nfct_handle *h;
uint32_t family = AF_INET;
int rc;
CHARSTRING ret_val("<flows xmlns=\"http://www.netfilter.org/xml/libnetfilter_conntrack\">");
h = _nfct_init(&ret_val);
rc = nfct_query(h, NFCT_Q_DUMP, &family);
if (rc < 0) {
ret_val += "</flows>";
return ret_val;
}
nfct_close(h);
ret_val += "</flows>";
return ret_val;
#endif
}
/* get a single conntrack entry for given 5-tuple */
CHARSTRING f__get__conntrack__xml(const CHARSTRING& src_ip, const CHARSTRING& dst_ip, const INTEGER& l4_proto, const INTEGER& src_port, const INTEGER& dst_port)
{
struct nfct_handle *h;
struct nf_conntrack *ct;
uint32_t family = AF_INET;
struct in_addr ia_src, ia_dst;
int rc;
CHARSTRING ret_val("<flows xmlns=\"http://www.netfilter.org/xml/libnetfilter_conntrack\">");
h = _nfct_init(&ret_val);
ct = nfct_new();
if (!ct) {
TTCN_error("error in nfct_new()");
}
if (inet_aton(src_ip, &ia_src) && inet_aton(dst_ip, &ia_dst)) {
nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
nfct_set_attr_u32(ct, ATTR_IPV4_SRC, ia_src.s_addr);
nfct_set_attr_u32(ct, ATTR_IPV4_DST, ia_dst.s_addr);
} else {
struct in6_addr ia6_src, ia6_dst;
inet_pton(AF_INET6, src_ip, &ia6_src);
inet_pton(AF_INET6, src_ip, &ia6_dst);
nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6);
nfct_set_attr(ct, ATTR_IPV6_SRC, &ia6_src);
nfct_set_attr(ct, ATTR_IPV6_DST, &ia6_dst);
}
nfct_set_attr_u8(ct, ATTR_L4PROTO, l4_proto.get_long_long_val());
nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(src_port.get_long_long_val()));
nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(dst_port.get_long_long_val()));
nfct_query(h, NFCT_Q_GET, ct);
nfct_close(h);
nfct_destroy(ct);
ret_val += "</flows>";
return ret_val;
}
}