OpenVAS Scanner 23.32.3
capture_packet.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 * SPDX-FileCopyrightText: 2002-2004 Tenable Network Security
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
7#include "capture_packet.h"
8
9#include "../misc/bpf_share.h" /* for bpf_datalink */
10#include "../misc/pcap_openvas.h" /* for get_datalink_size */
11
12#include <arpa/inet.h> /* for inet_ntoa */
13#include <glib.h> /* for gfree */
14#include <netinet/ip.h>
15#include <pcap.h>
16#include <sys/param.h>
17#ifdef __FreeBSD__
18#include <sys/socket.h>
19#endif
20
21extern int
22islocalhost (struct in_addr *);
23
30int
31init_capture_device (struct in_addr src, struct in_addr dest, char *filter)
32{
33 int ret = -1;
34 char *interface = NULL;
35 char *a_dst, *a_src;
36 char errbuf[PCAP_ERRBUF_SIZE];
37 int free_filter = 0;
38 pcap_if_t *alldevsp = NULL; /* list of capture devices */
39
40 a_src = g_strdup (inet_ntoa (src));
41 a_dst = g_strdup (inet_ntoa (dest));
42
43 if ((filter == NULL) || (filter[0] == '\0') || (filter[0] == '0'))
44 {
45 filter = g_malloc0 (256);
46 free_filter = 1;
47 if (islocalhost (&src) == 0)
48 snprintf (filter, 256, "ip and (src host %s and dst host %s)", a_src,
49 a_dst);
50 }
51 else
52 {
53 if (islocalhost (&src) == 0)
54 filter = g_strdup (filter);
55 else
56 filter = g_malloc0 (1);
57 free_filter = 1;
58 }
59
60 g_free (a_dst);
61 g_free (a_src);
62
63 if ((interface = routethrough (&src, &dest)))
64 {
65 ret = bpf_open_live (interface, filter);
66 }
67 else
68 {
69 if (pcap_findalldevs (&alldevsp, errbuf) < 0)
70 g_message ("Error for pcap_findalldevs(): %s", errbuf);
71 if (alldevsp != NULL)
72 interface = alldevsp->name;
73 ret = bpf_open_live (interface, filter);
74 }
75
76 if (free_filter != 0)
77 g_free (filter);
78
79 if (alldevsp != NULL)
80 pcap_freealldevs (alldevsp);
81
82 return ret;
83}
84
95char *
96capture_next_frame (int bpf, int timeout, int *sz, int dl_layer_only)
97{
98 int len;
99 int dl_len;
100 char *frame = NULL;
101 char *ret = NULL;
102 struct timeval past, now, then;
103 struct timezone tz;
104
105 if (bpf < 0)
106 return NULL;
107
108 dl_len = get_datalink_size (bpf_datalink (bpf));
109 memset (&past, '\0', sizeof (past));
110 memset (&now, '\0', sizeof (now));
111 gettimeofday (&then, &tz);
112 for (;;)
113 {
114 memcpy (&past, &then, sizeof (then));
115 frame = (char *) bpf_next (bpf, &len);
116 if (frame != NULL)
117 break;
118 gettimeofday (&now, &tz);
119
120 if (now.tv_usec < past.tv_usec)
121 {
122 past.tv_sec++;
123 now.tv_usec += 1000000;
124 }
125
126 if (timeout > 0)
127 {
128 if ((now.tv_sec - past.tv_sec) >= timeout)
129 break;
130 }
131 else
132 break;
133 }
134
135 if (frame != NULL)
136 {
137 if (dl_layer_only == 1)
138 {
139 ret = g_malloc0 (dl_len);
140 memcpy (ret, frame, dl_len);
141 if (sz != NULL)
142 *sz = dl_len;
143 }
144 else
145 {
146 ret = g_malloc0 (len);
147 memcpy (ret, frame, len);
148 if (sz != NULL)
149 *sz = len;
150 }
151 }
152
153 return ret;
154}
155
156struct ip *
157capture_next_packet (int bpf, int timeout, int *sz)
158{
159 int len;
160 int dl_len;
161 char *packet = NULL;
162 char *ret = NULL;
163 struct timeval past, now, then;
164 struct timezone tz;
165
166 if (bpf < 0)
167 return NULL;
168
169 dl_len = get_datalink_size (bpf_datalink (bpf));
170 memset (&past, '\0', sizeof (past));
171 memset (&now, '\0', sizeof (now));
172 gettimeofday (&then, &tz);
173 for (;;)
174 {
175 memcpy (&past, &then, sizeof (then));
176 packet = (char *) bpf_next (bpf, &len);
177 if (packet != NULL)
178 break;
179 gettimeofday (&now, &tz);
180
181 if (now.tv_usec < past.tv_usec)
182 {
183 past.tv_sec++;
184 now.tv_usec += 1000000;
185 }
186
187 if (timeout > 0)
188 {
189 if ((now.tv_sec - past.tv_sec) >= timeout)
190 break;
191 }
192 else
193 break;
194 }
195
196 if (packet != NULL)
197 {
198 struct ip *ip;
199
200 ip = (struct ip *) (packet + dl_len);
201#ifdef BSD_BYTE_ORDERING
202 ip->ip_len = ntohs (ip->ip_len);
203 ip->ip_off = ntohs (ip->ip_off);
204#endif
205 ip->ip_id = ntohs (ip->ip_id);
206 ret = g_malloc0 (len - dl_len);
207 memcpy (ret, ip, len - dl_len);
208 if (sz != NULL)
209 *sz = len - dl_len;
210 }
211 return ((struct ip *) ret);
212}
213
214int
215init_v6_capture_device (struct in6_addr src, struct in6_addr dest, char *filter)
216{
217 int ret = -1;
218 char *interface = NULL;
219 char *a_dst, *a_src;
220 int free_filter = 0;
221 char name[INET6_ADDRSTRLEN];
222 char errbuf[PCAP_ERRBUF_SIZE];
223 pcap_if_t *alldevsp = NULL; /* list of capture devices */
224
225 a_src = g_strdup (inet_ntop (AF_INET6, &src, name, INET6_ADDRSTRLEN));
226 a_dst = g_strdup (inet_ntop (AF_INET6, &dest, name, INET6_ADDRSTRLEN));
227
228 if ((filter == NULL) || (filter[0] == '\0') || (filter[0] == '0'))
229 {
230 filter = g_malloc0 (256);
231 free_filter = 1;
232 if (v6_islocalhost (&src) == 0)
233 snprintf (filter, 256, "ip and (src host %s and dst host %s", a_src,
234 a_dst);
235 }
236 else
237 {
238 if (v6_islocalhost (&src) == 0)
239 filter = g_strdup (filter);
240 else
241 filter = g_malloc0 (1);
242 free_filter = 1;
243 }
244
245 g_free (a_dst);
246 g_free (a_src);
247
248 if ((interface = v6_routethrough (&src, &dest)))
249 {
250 ret = bpf_open_live (interface, filter);
251 }
252 else
253 {
254 if (pcap_findalldevs (&alldevsp, errbuf) < 0)
255 g_message ("Error for pcap_findalldevs(): %s", errbuf);
256 if (alldevsp != NULL)
257 interface = alldevsp->name;
258 ret = bpf_open_live (interface, filter);
259 }
260
261 if (free_filter != 0)
262 g_free (filter);
263
264 if (alldevsp != NULL)
265 pcap_freealldevs (alldevsp);
266
267 return ret;
268}
269
270struct ip6_hdr *
271capture_next_v6_packet (int bpf, int timeout, int *sz)
272{
273 int len;
274 int dl_len;
275 char *packet = NULL;
276 char *ret = NULL;
277 struct timeval past, now, then;
278 struct timezone tz;
279
280 if (bpf < 0)
281 return NULL;
282
283 dl_len = get_datalink_size (bpf_datalink (bpf));
284 memset (&past, '\0', sizeof (past));
285 memset (&now, '\0', sizeof (now));
286 gettimeofday (&then, &tz);
287
288 for (;;)
289 {
290 memcpy (&past, &then, sizeof (then));
291 packet = (char *) bpf_next (bpf, &len);
292
293 if (packet != NULL)
294 break;
295
296 gettimeofday (&now, &tz);
297 if (now.tv_usec < past.tv_usec)
298 {
299 past.tv_sec++;
300 now.tv_usec += 1000000;
301 }
302
303 if (timeout > 0)
304 {
305 if ((now.tv_sec - past.tv_sec) >= timeout)
306 break;
307 }
308 else
309 break;
310 }
311
312 if (packet != NULL)
313 {
314 struct ip6_hdr *ip6;
315 ip6 = (struct ip6_hdr *) (packet + dl_len);
316#ifdef BSD_BYTE_ORDERING
317 ip6->ip6_plen = ntohs (ip6->ip6_plen);
318#endif
319 ret = g_malloc0 (len - dl_len);
320 memcpy (ret, ip6, len - dl_len);
321 if (sz != NULL)
322 *sz = len - dl_len;
323 }
324
325 return ((struct ip6_hdr *) ret);
326}
int bpf_open_live(char *iface, char *filter)
Definition bpf_share.c:39
int bpf_datalink(int bpf)
Definition bpf_share.c:158
u_char * bpf_next(int bpf, int *caplen)
Definition bpf_share.c:150
Header file for module bpf_share.
struct ip6_hdr * capture_next_v6_packet(int bpf, int timeout, int *sz)
char * capture_next_frame(int bpf, int timeout, int *sz, int dl_layer_only)
Capture a link layer frame.
int islocalhost(struct in_addr *)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:271
int init_capture_device(struct in_addr src, struct in_addr dest, char *filter)
Set up the pcap filter, and select the correct interface.
struct ip * capture_next_packet(int bpf, int timeout, int *sz)
int init_v6_capture_device(struct in6_addr src, struct in6_addr dest, char *filter)
static struct timeval timeval(unsigned long val)
const char * name
Definition nasl_init.c:439
uint8_t len
int islocalhost(struct in_addr *addr)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:271
char * routethrough(struct in_addr *dest, struct in_addr *source)
An awesome function to determine what interface a packet to a given destination should be routed thro...
Definition pcap.c:1070
int v6_islocalhost(struct in6_addr *addr)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition pcap.c:234
char * v6_routethrough(struct in6_addr *dest, struct in6_addr *source)
An awesome function to determine what interface a packet to a given destination should be routed thro...
Definition pcap.c:851
int get_datalink_size(int datalink)
Definition pcap.c:298
Header file for module pcap.