7 #include <sys/select.h>
10 #include <libmnl/libmnl.h>
11 #include <linux/netfilter/nfnetlink.h>
12 #include <linux/netfilter/nfnetlink_conntrack.h>
13 #include <linux/netfilter/nf_conntrack_common.h>
14 #include <linux/netfilter/nf_conntrack_tcp.h>
16 static void put_msg(
char *buf, uint16_t i,
int seq)
20 struct nlattr *nest1, *nest2;
22 nlh = mnl_nlmsg_put_header(buf);
23 nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_NEW;
24 nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL|NLM_F_ACK;
27 nfh = mnl_nlmsg_put_extra_header(nlh,
sizeof(
struct nfgenmsg));
28 nfh->nfgen_family = AF_INET;
29 nfh->version = NFNETLINK_V0;
32 nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_ORIG);
33 nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
34 mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr(
"1.1.1.1"));
35 mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr(
"2.2.2.2"));
36 mnl_attr_nest_end(nlh, nest2);
38 nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO);
39 mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP);
40 mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(i));
41 mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(1025));
42 mnl_attr_nest_end(nlh, nest2);
43 mnl_attr_nest_end(nlh, nest1);
45 nest1 = mnl_attr_nest_start(nlh, CTA_TUPLE_REPLY);
46 nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
47 mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, inet_addr(
"2.2.2.2"));
48 mnl_attr_put_u32(nlh, CTA_IP_V4_DST, inet_addr(
"1.1.1.1"));
49 mnl_attr_nest_end(nlh, nest2);
51 nest2 = mnl_attr_nest_start(nlh, CTA_TUPLE_PROTO);
52 mnl_attr_put_u8(nlh, CTA_PROTO_NUM, IPPROTO_TCP);
53 mnl_attr_put_u16(nlh, CTA_PROTO_SRC_PORT, htons(1025));
54 mnl_attr_put_u16(nlh, CTA_PROTO_DST_PORT, htons(i));
55 mnl_attr_nest_end(nlh, nest2);
56 mnl_attr_nest_end(nlh, nest1);
58 nest1 = mnl_attr_nest_start(nlh, CTA_PROTOINFO);
59 nest2 = mnl_attr_nest_start(nlh, CTA_PROTOINFO_TCP);
60 mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_STATE, TCP_CONNTRACK_SYN_SENT);
61 mnl_attr_nest_end(nlh, nest2);
62 mnl_attr_nest_end(nlh, nest1);
64 mnl_attr_put_u32(nlh, CTA_STATUS, htonl(IPS_CONFIRMED));
65 mnl_attr_put_u32(nlh, CTA_TIMEOUT, htonl(1000));
68 static int cb_err(
const struct nlmsghdr *nlh,
void *data)
70 struct nlmsgerr *err = mnl_nlmsg_get_payload(nlh);
72 printf(
"message with seq %u has failed: %s\n",
73 nlh->nlmsg_seq, strerror(-err->error));
77 static mnl_cb_t cb_ctl_array[NLMSG_MIN_TYPE] = {
78 [NLMSG_ERROR] = cb_err,
84 int ret, fd = mnl_socket_get_fd(nl);
85 size_t len = mnl_nlmsg_batch_size(b);
86 char rcv_buf[MNL_SOCKET_BUFFER_SIZE];
88 ret = mnl_socket_sendto(nl, mnl_nlmsg_batch_head(b), len);
90 perror(
"mnl_socket_sendto");
101 FD_SET(fd, &readfds);
103 ret = select(fd+1, &readfds, NULL, NULL, &tv);
108 while (ret > 0 && FD_ISSET(fd, &readfds)) {
109 ret = mnl_socket_recvfrom(nl, rcv_buf,
sizeof(rcv_buf));
111 perror(
"mnl_socket_recvfrom");
115 ret = mnl_cb_run2(rcv_buf, ret, 0, portid,
116 NULL, NULL, cb_ctl_array,
117 MNL_ARRAY_SIZE(cb_ctl_array));
119 perror(
"mnl_cb_run2");
123 ret = select(fd+1, &readfds, NULL, NULL, &tv);
129 FD_SET(fd, &readfds);
136 char snd_buf[MNL_SOCKET_BUFFER_SIZE*2];
139 unsigned int seq, portid;
142 nl = mnl_socket_open(NETLINK_NETFILTER);
144 perror(
"mnl_socket_open");
147 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
148 perror(
"mnl_socket_bind");
151 portid = mnl_socket_get_portid(nl);
157 b = mnl_nlmsg_batch_start(snd_buf, MNL_SOCKET_BUFFER_SIZE);
159 perror(
"mnl_nlmsg_batch_start");
164 for (i=1024, j=0; i<65535; i++, j++) {
165 put_msg(mnl_nlmsg_batch_current(b), i, seq+j);
169 if (mnl_nlmsg_batch_next(b))
172 send_batch(nl, b, portid);
176 mnl_nlmsg_batch_reset(b);
180 if (!mnl_nlmsg_batch_is_empty(b))
181 send_batch(nl, b, portid);
183 mnl_nlmsg_batch_stop(b);
184 mnl_socket_close(nl);