Monero
Loading...
Searching...
No Matches
nfct_get.c
Go to the documentation of this file.
1#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <time.h>
5#include <string.h>
6#include <arpa/inet.h>
7
8#ifdef USE_NFCT
9#include <libmnl/libmnl.h>
10#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
11
12#include <linux/netfilter/nf_conntrack_tcp.h>
13
14struct data_cb_s
15{
16 struct sockaddr_storage * ext;
17 uint8_t found;
18};
19
20static int data_cb(const struct nlmsghdr *nlh, void *data)
21{
22 struct nf_conntrack *ct;
23 struct data_cb_s * d = (struct data_cb_s*) data;
24 struct sockaddr_in* ext4 = (struct sockaddr_in*) d->ext;
25
26 ct = nfct_new();
27 if (ct == NULL)
28 return MNL_CB_OK;
29 nfct_nlmsg_parse(nlh, ct);
30
31 if (data) {
32 ext4->sin_addr.s_addr = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST);
33 ext4->sin_port = nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST);
34 }
35 d->found = 1;
36 nfct_destroy(ct);
37
38 return MNL_CB_OK;
39}
40
41int get_nat_ext_addr(struct sockaddr* src, struct sockaddr *dst, uint8_t proto,
42 struct sockaddr_storage* ret_ext)
43{
44 struct mnl_socket *nl;
45 struct nlmsghdr *nlh;
46 struct nfgenmsg *nfh;
47 char buf[MNL_SOCKET_BUFFER_SIZE];
48 unsigned int seq, portid;
49 struct nf_conntrack *ct;
50 int ret;
51 struct data_cb_s data;
52
53 if ((!src)&&(!dst)) {
54 return 0;
55 }
56
57 if (src->sa_family != dst->sa_family) {
58 return 0;
59 }
60
61 nl = mnl_socket_open(NETLINK_NETFILTER);
62 if (nl == NULL) {
63// perror("mnl_socket_open");
64 goto free_nl;
65 }
66
67 if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
68// perror("mnl_socket_bind");
69 goto free_nl;
70 }
71 portid = mnl_socket_get_portid(nl);
72
73 memset(buf, 0, sizeof(buf));
74 nlh = mnl_nlmsg_put_header(buf);
75 nlh->nlmsg_type = (NFNL_SUBSYS_CTNETLINK << 8) | IPCTNL_MSG_CT_GET;
76 nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK;
77 nlh->nlmsg_seq = seq = time(NULL);
78
79 nfh = mnl_nlmsg_put_extra_header(nlh, sizeof(struct nfgenmsg));
80 nfh->nfgen_family = src->sa_family;
81 nfh->version = NFNETLINK_V0;
82 nfh->res_id = 0;
83
84 ct = nfct_new();
85 if (ct == NULL) {
86 goto free_nl;
87 }
88
89 nfct_set_attr_u8(ct, ATTR_L3PROTO, src->sa_family);
90 if (src->sa_family == AF_INET) {
91 struct sockaddr_in *src4 = (struct sockaddr_in *)src;
92 struct sockaddr_in *dst4 = (struct sockaddr_in *)dst;
93 nfct_set_attr_u32(ct, ATTR_IPV4_SRC, src4->sin_addr.s_addr);
94 nfct_set_attr_u32(ct, ATTR_IPV4_DST, dst4->sin_addr.s_addr);
95 nfct_set_attr_u16(ct, ATTR_PORT_SRC, src4->sin_port);
96 nfct_set_attr_u16(ct, ATTR_PORT_DST, dst4->sin_port);
97 } else if (src->sa_family == AF_INET6) {
98 struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)src;
99 struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst;
100 nfct_set_attr(ct, ATTR_IPV6_SRC, &src6->sin6_addr);
101 nfct_set_attr(ct, ATTR_IPV6_DST, &dst6->sin6_addr);
102 nfct_set_attr_u16(ct, ATTR_PORT_SRC, src6->sin6_port);
103 nfct_set_attr_u16(ct, ATTR_PORT_DST, dst6->sin6_port);
104 }
105 nfct_set_attr_u8(ct, ATTR_L4PROTO, proto);
106
107 nfct_nlmsg_build(nlh, ct);
108
109 ret = mnl_socket_sendto(nl, nlh, nlh->nlmsg_len);
110 if (ret == -1) {
111 goto free_ct;
112 }
113
114 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
115 data.ext = ret_ext;
116 data.found = 0;
117 while (ret > 0) {
118 ret = mnl_cb_run(buf, ret, seq, portid, data_cb, &data);
119 if (ret <= MNL_CB_STOP)
120 break;
121 ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
122 }
123
124free_ct:
125 nfct_destroy(ct);
126free_nl:
127 mnl_socket_close(nl);
128
129 return data.found;
130}
131
132#else
133#define DST "dst="
134#define DST_PORT "dport="
135#define SRC "src="
136#define SRC_PORT "sport="
137#define IP_CONNTRACK_LOCATION "/proc/net/ip_conntrack"
138#define NF_CONNTRACK_LOCATION "/proc/net/nf_conntrack"
139
140int get_nat_ext_addr(struct sockaddr* src, struct sockaddr *dst, uint8_t proto,
141 struct sockaddr_storage* ret_ext)
142{
143 FILE *f;
144 int af;
145
146 if (!src)
147 return -2;
148
149 af = src->sa_family;
150
151 if ((f = fopen(NF_CONNTRACK_LOCATION, "r")) == NULL) {
152 if ((f = fopen(IP_CONNTRACK_LOCATION, "r")) == NULL) {
153 printf("could not read info about connections from the kernel, "
154 "make sure netfilter is enabled in kernel or by modules.\n");
155 return -1;
156 }
157 }
158
159 while (!feof(f)) {
160 char line[256], *str;
161 memset(line, 0, sizeof(line));
162 str = fgets(line, sizeof(line), f);
163 if (line[0] != 0) {
164 char *token, *saveptr;
165 int j;
166 uint8_t src_f, src_port_f, dst_f, dst_port_f;
167 src_f=src_port_f=dst_f=dst_port_f=0;
168
169 for (j = 1; ; j++, str = NULL) {
170 token = strtok_r(str, " ", &saveptr);
171 if (token == NULL)
172 break;
173
174 if ((j==2)&&(af!=atoi(token)))
175 break;
176 if ((j==4)&&(proto!=atoi(token)))
177 break;
178 if (j<=4)
179 continue;
180
181 if (strncmp(token, SRC, sizeof(SRC) - 1) == 0) {
182 char *srcip = token + sizeof(SRC) - 1;
183 uint32_t buf[4];
184 memset(buf,0,sizeof(buf));
185
186 if (inet_pton(af, srcip, buf)!=1)
187 break;
188
189 if (af==AF_INET) {
190 struct sockaddr_in *src4=(struct sockaddr_in*)src;
191 if (!src_f) {
192 if (src4->sin_addr.s_addr != buf[0])
193 break;
194 src_f = 1;
195 }
196 }
197 }
198 if (strncmp(token, SRC_PORT, sizeof(SRC_PORT) - 1) == 0) {
199 char *src_port = token + sizeof(SRC_PORT) - 1;
200 uint16_t port=atoi(src_port);
201
202 if (af==AF_INET) {
203 struct sockaddr_in *src4=(struct sockaddr_in*)src;
204 if (!src_port_f) {
205 if (ntohs(src4->sin_port) != port)
206 break;
207 src_port_f = 1;
208 }
209 }
210 }
211
212 if (strncmp(token, DST, sizeof(DST) - 1) == 0) {
213 char *dstip = token + sizeof(DST) - 1;
214 uint32_t buf[4];
215 memset(buf,0,sizeof(buf));
216 if (inet_pton(af, dstip, buf)!=1)
217 break;
218 if (af==AF_INET) {
219 struct sockaddr_in *dst4=(struct sockaddr_in*)dst;
220 if (!dst_f) {
221 if (dst4->sin_addr.s_addr != buf[0])
222 break;
223 dst_f = 1;
224 } else {
225 struct sockaddr_in*ret4=(struct sockaddr_in*)ret_ext;
226 ret_ext->ss_family = AF_INET;
227 ret4->sin_addr.s_addr = buf[0];
228 }
229 }
230 }
231 if (strncmp(token, DST_PORT, sizeof(DST_PORT)-1) == 0) {
232 char *dst_port = token + sizeof(DST_PORT) - 1;
233 uint16_t port=atoi(dst_port);
234 if (af==AF_INET) {
235 struct sockaddr_in *dst4=(struct sockaddr_in*)dst;
236 if (!dst_port_f) {
237 if (ntohs(dst4->sin_port) != port)
238 break;
239 dst_port_f = 1;
240 } else {
241 struct sockaddr_in*ret4=(struct sockaddr_in*)ret_ext;
242 ret_ext->ss_family = AF_INET;
243 ret4->sin_port = htons(port);
244 }
245 }
246 }
247 }
248 if (src_f && src_port_f && dst_f && dst_port_f) {
249 fclose(f);
250 return 1;
251 }
252 }
253 }
254 fclose(f);
255
256 return 0;
257}
258#endif
Definition d.py:1
int time
Definition gen_wide_data.py:40
#define SRC
Definition nfct_get.c:135
#define SRC_PORT
Definition nfct_get.c:136
int get_nat_ext_addr(struct sockaddr *src, struct sockaddr *dst, uint8_t proto, struct sockaddr_storage *ret_ext)
Definition nfct_get.c:140
#define DST
Definition nfct_get.c:133
#define DST_PORT
Definition nfct_get.c:134
#define IP_CONNTRACK_LOCATION
Definition nfct_get.c:137
#define NF_CONNTRACK_LOCATION
Definition nfct_get.c:138
const char *const str
Definition portlistingparse.c:23
const char * buf
Definition slow_memmem.cpp:73
unsigned short uint16_t
Definition stdint.h:125
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
std::string data
Definition base58.cpp:37