10#include <libmnl/libmnl.h>
11#include <linux/netfilter/nfnetlink.h>
12#include <linux/netfilter/nfnetlink_conntrack.h>
14static int parse_counters_cb(
const struct nlattr *attr,
void *data)
16 const struct nlattr **tb = data;
23 case CTA_COUNTERS_PACKETS:
24 case CTA_COUNTERS_BYTES:
26 perror(
"mnl_attr_validate");
35static void print_counters(
const struct nlattr *nest)
37 struct nlattr *tb[CTA_COUNTERS_MAX+1] = {};
40 if (tb[CTA_COUNTERS_PACKETS]) {
41 printf(
"packets=%"PRIu64
" ",
44 if (tb[CTA_COUNTERS_BYTES]) {
45 printf(
"bytes=%"PRIu64
" ",
50static int parse_ip_cb(
const struct nlattr *attr,
void *data)
52 const struct nlattr **tb = data;
62 perror(
"mnl_attr_validate");
69 sizeof(
struct in6_addr)) < 0) {
70 perror(
"mnl_attr_validate2");
79static void print_ip(
const struct nlattr *nest)
81 struct nlattr *tb[CTA_IP_MAX+1] = {};
84 if (tb[CTA_IP_V4_SRC]) {
86 printf(
"src=%s ", inet_ntoa(*in));
88 if (tb[CTA_IP_V4_DST]) {
90 printf(
"dst=%s ", inet_ntoa(*in));
92 if (tb[CTA_IP_V6_SRC]) {
94 char out[INET6_ADDRSTRLEN];
96 if (!inet_ntop(AF_INET6, in, out,
sizeof(out)))
97 printf(
"src=%s ", out);
99 if (tb[CTA_IP_V6_DST]) {
101 char out[INET6_ADDRSTRLEN];
103 if (!inet_ntop(AF_INET6, in, out,
sizeof(out)))
104 printf(
"dst=%s ", out);
108static int parse_proto_cb(
const struct nlattr *attr,
void *data)
110 const struct nlattr **tb = data;
118 case CTA_PROTO_ICMP_TYPE:
119 case CTA_PROTO_ICMP_CODE:
121 perror(
"mnl_attr_validate");
125 case CTA_PROTO_SRC_PORT:
126 case CTA_PROTO_DST_PORT:
127 case CTA_PROTO_ICMP_ID:
129 perror(
"mnl_attr_validate");
138static void print_proto(
const struct nlattr *nest)
140 struct nlattr *tb[CTA_PROTO_MAX+1] = {};
143 if (tb[CTA_PROTO_NUM]) {
146 if (tb[CTA_PROTO_SRC_PORT]) {
150 if (tb[CTA_PROTO_DST_PORT]) {
154 if (tb[CTA_PROTO_ICMP_ID]) {
158 if (tb[CTA_PROTO_ICMP_TYPE]) {
161 if (tb[CTA_PROTO_ICMP_CODE]) {
166static int parse_tuple_cb(
const struct nlattr *attr,
void *data)
168 const struct nlattr **tb = data;
177 perror(
"mnl_attr_validate");
181 case CTA_TUPLE_PROTO:
183 perror(
"mnl_attr_validate");
192static void print_tuple(
const struct nlattr *nest)
194 struct nlattr *tb[CTA_TUPLE_MAX+1] = {};
197 if (tb[CTA_TUPLE_IP]) {
198 print_ip(tb[CTA_TUPLE_IP]);
200 if (tb[CTA_TUPLE_PROTO]) {
201 print_proto(tb[CTA_TUPLE_PROTO]);
205static int data_attr_cb(
const struct nlattr *attr,
void *data)
207 const struct nlattr **tb = data;
215 case CTA_COUNTERS_ORIG:
216 case CTA_COUNTERS_REPLY:
218 perror(
"mnl_attr_validate");
226 perror(
"mnl_attr_validate");
235static int data_cb(
const struct nlmsghdr *nlh,
void *data)
237 struct nlattr *tb[CTA_MAX+1] = {};
241 if (tb[CTA_TUPLE_ORIG])
242 print_tuple(tb[CTA_TUPLE_ORIG]);
250 if (tb[CTA_COUNTERS_ORIG]) {
252 print_counters(tb[CTA_COUNTERS_ORIG]);
255 if (tb[CTA_COUNTERS_REPLY]) {
257 print_counters(tb[CTA_COUNTERS_REPLY]);
266 char buf[MNL_SOCKET_DUMP_SIZE];
267 struct mnl_socket *nl;
268 struct nlmsghdr *nlh;
269 struct nfgenmsg *nfh;
270 uint32_t seq, portid;
275 perror(
"mnl_socket_open");
280 perror(
"mnl_socket_bind");
285 nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET;
286 nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP;
287 nlh->nlmsg_seq = seq = time(NULL);
290 nfh->nfgen_family = AF_INET;
291 nfh->version = NFNETLINK_V0;
296 perror(
"mnl_socket_sendto");
304 perror(
"mnl_socket_recvfrom");
308 ret =
mnl_cb_run(buf, ret, seq, portid, data_cb, NULL);
310 perror(
"mnl_cb_run");
312 }
else if (ret <= MNL_CB_STOP)
uint8_t mnl_attr_get_u8(const struct nlattr *attr)
int mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb, void *data)
uint64_t mnl_attr_get_u64(const struct nlattr *attr)
void * mnl_attr_get_payload(const struct nlattr *attr)
int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data)
int mnl_attr_type_valid(const struct nlattr *attr, uint16_t max)
uint16_t mnl_attr_get_type(const struct nlattr *attr)
int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t exp_len)
uint32_t mnl_attr_get_u32(const struct nlattr *attr)
uint16_t mnl_attr_get_u16(const struct nlattr *attr)
int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data)
void * mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
struct nlmsghdr * mnl_nlmsg_put_header(void *buf)
void * mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
int mnl_socket_close(struct mnl_socket *nl)
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
struct mnl_socket * mnl_socket_open(int bus)
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t bufsiz)
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *buf, size_t len)