115 lines
3.6 KiB
C++
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;
|
|
}
|
|
}
|