OpenVAS Scanner  22.7.9
capture_packet.c File Reference
#include "capture_packet.h"
#include "../misc/bpf_share.h"
#include "../misc/pcap_openvas.h"
#include <arpa/inet.h>
#include <glib.h>
#include <netinet/ip.h>
#include <pcap.h>
#include <sys/param.h>
Include dependency graph for capture_packet.c:

Go to the source code of this file.

Functions

int islocalhost (struct in_addr *)
 Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface. More...
 
int init_capture_device (struct in_addr src, struct in_addr dest, char *filter)
 Set up the pcap filter, and select the correct interface. More...
 
char * capture_next_frame (int bpf, int timeout, int *sz, int dl_layer_only)
 Capture a link layer frame. More...
 
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)
 
struct ip6_hdr * capture_next_v6_packet (int bpf, int timeout, int *sz)
 

Function Documentation

◆ capture_next_frame()

char* capture_next_frame ( int  bpf,
int  timeout,
int *  sz,
int  dl_layer_only 
)

Capture a link layer frame.

Parameters
[in]bpfbpf handler
[in]timeoutthe timeout
[out]szsize of the frame, -1 if no frame was received.
[in]dl_layer_onlyIf the answer should include the payload.
Returns
the link layer frame.

Definition at line 96 of file capture_packet.c.

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 }

References bpf_datalink(), bpf_next(), get_datalink_size(), len, and timeval().

Referenced by send_frame().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ capture_next_packet()

struct ip* capture_next_packet ( int  bpf,
int  timeout,
int *  sz 
)

Definition at line 157 of file capture_packet.c.

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 }

References bpf_datalink(), bpf_next(), get_datalink_size(), len, and timeval().

Referenced by nasl_send_packet().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ capture_next_v6_packet()

struct ip6_hdr* capture_next_v6_packet ( int  bpf,
int  timeout,
int *  sz 
)

Definition at line 271 of file capture_packet.c.

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 }

References bpf_datalink(), bpf_next(), get_datalink_size(), len, and timeval().

Referenced by nasl_send_v6packet().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_capture_device()

int init_capture_device ( struct in_addr  src,
struct in_addr  dest,
char *  filter 
)

Set up the pcap filter, and select the correct interface.

The filter will be changed only if this is necessary

Definition at line 31 of file capture_packet.c.

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 }

References bpf_open_live(), islocalhost(), name, and routethrough().

Referenced by nasl_send_packet(), nasl_tcp_ping(), and send_frame().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ init_v6_capture_device()

int init_v6_capture_device ( struct in6_addr  src,
struct in6_addr  dest,
char *  filter 
)

Definition at line 215 of file capture_packet.c.

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 }

References bpf_open_live(), name, v6_islocalhost(), and v6_routethrough().

Referenced by nasl_send_v6packet(), nasl_tcp_v6_ping(), and send_frame().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ islocalhost()

int islocalhost ( struct in_addr *  )

Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.

Definition at line 261 of file pcap.c.

262 {
263  char dev[128];
264 
265  if (addr == NULL)
266  return -1;
267 
268  /* If it is 0.0.0.0 or starts with 127.0.0.1 then it is
269  probably localhost */
270  if ((addr->s_addr & htonl (0xFF000000)) == htonl (0x7F000000))
271  return 1;
272 
273  if (!addr->s_addr)
274  return 1;
275 
276  /* If it is the same addy as a local interface, then it is
277  probably localhost */
278 
279  if (ipaddr2devname (dev, sizeof (dev), addr) != -1)
280  return 1;
281 
282  /* OK, so to a first approximation, this addy is probably not
283  localhost */
284  return 0;
285 }

References interface_info::addr, and ipaddr2devname().

Referenced by Ensure(), init_capture_device(), nasl_send_packet(), nasl_tcp_ping(), openvas_routethrough(), plugin_run_synscan(), and routethrough().

Here is the call graph for this function:
Here is the caller graph for this function:
bpf_open_live
int bpf_open_live(char *iface, char *filter)
Definition: bpf_share.c:39
v6_routethrough
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:841
islocalhost
int islocalhost(struct in_addr *)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface.
Definition: pcap.c:261
name
const char * name
Definition: nasl_init.c:411
len
uint8_t len
Definition: nasl_packet_forgery.c:1
bpf_datalink
int bpf_datalink(int bpf)
Definition: bpf_share.c:158
timeval
static struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:94
ipaddr2devname
static int ipaddr2devname(char *dev, int sz, struct in_addr *addr)
Definition: pcap.c:197
get_datalink_size
int get_datalink_size(int datalink)
Definition: pcap.c:288
v6_islocalhost
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:224
bpf_next
u_char * bpf_next(int bpf, int *caplen)
Definition: bpf_share.c:150
routethrough
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:1060