7#include <libmnl/libmnl.h>
8#include <linux/netfilter/nfnetlink.h>
9#include <linux/netfilter/nfnetlink_conntrack.h>
11static int parse_ip_cb(
const struct nlattr *attr,
void *data)
13 const struct nlattr **tb = data;
23 perror(
"mnl_attr_validate");
32static void print_ip(
const struct nlattr *nest)
34 struct nlattr *tb[CTA_IP_MAX+1] = {};
37 if (tb[CTA_IP_V4_SRC]) {
39 printf(
"src=%s ", inet_ntoa(*in));
41 if (tb[CTA_IP_V4_DST]) {
43 printf(
"dst=%s ", inet_ntoa(*in));
47static int parse_proto_cb(
const struct nlattr *attr,
void *data)
49 const struct nlattr **tb = data;
57 case CTA_PROTO_ICMP_TYPE:
58 case CTA_PROTO_ICMP_CODE:
60 perror(
"mnl_attr_validate");
64 case CTA_PROTO_SRC_PORT:
65 case CTA_PROTO_DST_PORT:
66 case CTA_PROTO_ICMP_ID:
68 perror(
"mnl_attr_validate");
77static void print_proto(
const struct nlattr *nest)
79 struct nlattr *tb[CTA_PROTO_MAX+1] = {};
82 if (tb[CTA_PROTO_NUM]) {
85 if (tb[CTA_PROTO_SRC_PORT]) {
89 if (tb[CTA_PROTO_DST_PORT]) {
93 if (tb[CTA_PROTO_ICMP_ID]) {
97 if (tb[CTA_PROTO_ICMP_TYPE]) {
100 if (tb[CTA_PROTO_ICMP_CODE]) {
105static int parse_tuple_cb(
const struct nlattr *attr,
void *data)
107 const struct nlattr **tb = data;
116 perror(
"mnl_attr_validate");
120 case CTA_TUPLE_PROTO:
122 perror(
"mnl_attr_validate");
131static void print_tuple(
const struct nlattr *nest)
133 struct nlattr *tb[CTA_TUPLE_MAX+1] = {};
136 if (tb[CTA_TUPLE_IP]) {
137 print_ip(tb[CTA_TUPLE_IP]);
139 if (tb[CTA_TUPLE_PROTO]) {
140 print_proto(tb[CTA_TUPLE_PROTO]);
144static int data_attr_cb(
const struct nlattr *attr,
void *data)
146 const struct nlattr **tb = data;
155 perror(
"mnl_attr_validate");
163 perror(
"mnl_attr_validate");
172static int data_cb(
const struct nlmsghdr *nlh,
void *data)
174 struct nlattr *tb[CTA_MAX+1] = {};
177 switch(nlh->nlmsg_type & 0xFF) {
178 case IPCTNL_MSG_CT_NEW:
179 if (nlh->nlmsg_flags & (NLM_F_CREATE|NLM_F_EXCL))
180 printf(
"%9s ",
"[NEW] ");
182 printf(
"%9s ",
"[UPDATE] ");
184 case IPCTNL_MSG_CT_DELETE:
185 printf(
"%9s ",
"[DESTROY] ");
190 if (tb[CTA_TUPLE_ORIG]) {
191 print_tuple(tb[CTA_TUPLE_ORIG]);
196 if (tb[CTA_SECMARK]) {
205 struct mnl_socket *nl;
206 char buf[MNL_SOCKET_BUFFER_SIZE];
211 perror(
"mnl_socket_open");
216 NF_NETLINK_CONNTRACK_UPDATE |
217 NF_NETLINK_CONNTRACK_DESTROY,
218 MNL_SOCKET_AUTOPID) < 0) {
219 perror(
"mnl_socket_bind");
226 perror(
"mnl_socket_recvfrom");
230 ret =
mnl_cb_run(buf, ret, 0, 0, data_cb, NULL);
232 perror(
"mnl_cb_run");
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)
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)
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)
int mnl_socket_close(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)