9 #include <libmnl/libmnl.h>
10 #include <linux/netfilter.h>
11 #include <linux/netfilter/nfnetlink.h>
12 #include <linux/netfilter/nfnetlink_log.h>
14 static int parse_attr_cb(
const struct nlattr *attr,
void *data)
16 const struct nlattr **tb = data;
17 int type = mnl_attr_get_type(attr);
20 if (mnl_attr_type_valid(attr, NFULA_MAX) < 0)
25 case NFULA_IFINDEX_INDEV:
26 case NFULA_IFINDEX_OUTDEV:
27 case NFULA_IFINDEX_PHYSINDEV:
28 case NFULA_IFINDEX_PHYSOUTDEV:
29 if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
30 perror(
"mnl_attr_validate");
35 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
36 sizeof(
struct nfulnl_msg_packet_timestamp)) < 0) {
37 perror(
"mnl_attr_validate2");
42 if (mnl_attr_validate2(attr, MNL_TYPE_UNSPEC,
43 sizeof(
struct nfulnl_msg_packet_hw)) < 0) {
44 perror(
"mnl_attr_validate2");
49 if (mnl_attr_validate(attr, MNL_TYPE_NUL_STRING) < 0) {
50 perror(
"mnl_attr_validate");
61 static int log_cb(
const struct nlmsghdr *nlh,
void *data)
63 struct nlattr *tb[NFULA_MAX+1] = {};
64 struct nfulnl_msg_packet_hdr *ph = NULL;
65 const char *prefix = NULL;
68 mnl_attr_parse(nlh,
sizeof(
struct nfgenmsg), parse_attr_cb, tb);
69 if (tb[NFULA_PACKET_HDR])
70 ph = mnl_attr_get_payload(tb[NFULA_PACKET_HDR]);
72 prefix = mnl_attr_get_str(tb[NFULA_PREFIX]);
74 mark = ntohl(mnl_attr_get_u32(tb[NFULA_MARK]));
76 printf(
"log received (prefix=\"%s\" hw=0x%04x hook=%u mark=%u)\n",
77 prefix ? prefix :
"", ntohs(ph->hw_protocol), ph->hook,
83 static struct nlmsghdr *
84 nflog_build_cfg_pf_request(
char *buf, uint8_t command)
86 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
87 nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
88 nlh->nlmsg_flags = NLM_F_REQUEST;
90 struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh,
sizeof(*nfg));
91 nfg->nfgen_family = AF_INET;
92 nfg->version = NFNETLINK_V0;
94 struct nfulnl_msg_config_cmd cmd = {
97 mnl_attr_put(nlh, NFULA_CFG_CMD,
sizeof(cmd), &cmd);
102 static struct nlmsghdr *
103 nflog_build_cfg_request(
char *buf, uint8_t command,
int qnum)
105 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
106 nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
107 nlh->nlmsg_flags = NLM_F_REQUEST;
109 struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh,
sizeof(*nfg));
110 nfg->nfgen_family = AF_INET;
111 nfg->version = NFNETLINK_V0;
112 nfg->res_id = htons(qnum);
114 struct nfulnl_msg_config_cmd cmd = {
117 mnl_attr_put(nlh, NFULA_CFG_CMD,
sizeof(cmd), &cmd);
122 static struct nlmsghdr *
123 nflog_build_cfg_params(
char *buf, uint8_t mode,
int range,
int qnum)
125 struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
126 nlh->nlmsg_type = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
127 nlh->nlmsg_flags = NLM_F_REQUEST;
129 struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh,
sizeof(*nfg));
130 nfg->nfgen_family = AF_UNSPEC;
131 nfg->version = NFNETLINK_V0;
132 nfg->res_id = htons(qnum);
134 struct nfulnl_msg_config_mode params = {
135 .copy_range = htonl(range),
138 mnl_attr_put(nlh, NFULA_CFG_MODE,
sizeof(params), ¶ms);
143 int main(
int argc,
char *argv[])
146 char buf[MNL_SOCKET_BUFFER_SIZE];
147 struct nlmsghdr *nlh;
149 unsigned int portid, qnum;
152 printf(
"Usage: %s [queue_num]\n", argv[0]);
155 qnum = atoi(argv[1]);
157 nl = mnl_socket_open(NETLINK_NETFILTER);
159 perror(
"mnl_socket_open");
163 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
164 perror(
"mnl_socket_bind");
167 portid = mnl_socket_get_portid(nl);
169 nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_UNBIND);
171 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
172 perror(
"mnl_socket_sendto");
176 nlh = nflog_build_cfg_pf_request(buf, NFULNL_CFG_CMD_PF_BIND);
178 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
179 perror(
"mnl_socket_sendto");
183 nlh = nflog_build_cfg_request(buf, NFULNL_CFG_CMD_BIND, qnum);
185 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
186 perror(
"mnl_socket_sendto");
190 nlh = nflog_build_cfg_params(buf, NFULNL_COPY_PACKET, 0xFFFF, qnum);
192 if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
193 perror(
"mnl_socket_sendto");
197 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
199 perror(
"mnl_socket_recvfrom");
203 ret = mnl_cb_run(buf, ret, 0, portid, log_cb, NULL);
205 perror(
"mnl_cb_run");
209 ret = mnl_socket_recvfrom(nl, buf,
sizeof(buf));
211 perror(
"mnl_socket_recvfrom");
216 mnl_socket_close(nl);