OpenVAS Scanner  7.0.0~git
capture_packet.c
Go to the documentation of this file.
1 /* Copyright (C) 2002 - 2004 Tenable Network Security
2  *
3  * SPDX-License-Identifier: GPL-2.0-only
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 #include "capture_packet.h"
20 
21 #include "../misc/bpf_share.h" /* for bpf_datalink */
22 #include "../misc/pcap_openvas.h" /* for get_datalink_size */
23 
24 #include <arpa/inet.h> /* for inet_ntoa */
25 #include <glib.h> /* for gfree */
26 #include <netinet/ip.h>
27 #include <pcap.h>
28 #include <string.h> /* for bcopy */
29 #include <sys/param.h>
30 #ifdef __FreeBSD__
31 #include <sys/socket.h>
32 #endif
33 
34 extern int
35 islocalhost (struct in_addr *);
36 
43 int
44 init_capture_device (struct in_addr src, struct in_addr dest, char *filter)
45 {
46  int ret = -1;
47  char *interface = NULL;
48  char *a_dst, *a_src;
49  char errbuf[PCAP_ERRBUF_SIZE];
50  int free_filter = 0;
51 
52  a_src = g_strdup (inet_ntoa (src));
53  a_dst = g_strdup (inet_ntoa (dest));
54 
55  if ((filter == NULL) || (filter[0] == '\0') || (filter[0] == '0'))
56  {
57  filter = g_malloc0 (256);
58  free_filter = 1;
59  if (islocalhost (&src) == 0)
60  snprintf (filter, 256, "ip and (src host %s and dst host %s)", a_src,
61  a_dst);
62  }
63  else
64  {
65  if (islocalhost (&src) == 0)
66  filter = g_strdup (filter);
67  else
68  filter = g_malloc0 (1);
69  free_filter = 1;
70  }
71 
72  g_free (a_dst);
73  g_free (a_src);
74 
75  if ((interface = routethrough (&src, &dest))
76  || (interface = pcap_lookupdev (errbuf)))
77  ret = bpf_open_live (interface, filter);
78 
79  if (free_filter != 0)
80  g_free (filter);
81 
82  return ret;
83 }
84 
85 struct ip *
86 capture_next_packet (int bpf, int timeout, int *sz)
87 {
88  int len;
89  int dl_len;
90  char *packet = NULL;
91  char *ret = NULL;
92  struct timeval past, now, then;
93  struct timezone tz;
94 
95  if (bpf < 0)
96  return NULL;
97 
98  dl_len = get_datalink_size (bpf_datalink (bpf));
99  bzero (&past, sizeof (past));
100  bzero (&now, sizeof (now));
101  gettimeofday (&then, &tz);
102  for (;;)
103  {
104  bcopy (&then, &past, sizeof (then));
105  packet = (char *) bpf_next (bpf, &len);
106  if (packet != NULL)
107  break;
108  gettimeofday (&now, &tz);
109 
110  if (now.tv_usec < past.tv_usec)
111  {
112  past.tv_sec++;
113  now.tv_usec += 1000000;
114  }
115 
116  if (timeout > 0)
117  {
118  if ((now.tv_sec - past.tv_sec) >= timeout)
119  break;
120  }
121  else
122  break;
123  }
124 
125  if (packet != NULL)
126  {
127  struct ip *ip;
128  ip = (struct ip *) (packet + dl_len);
129 #ifdef BSD_BYTE_ORDERING
130  ip->ip_len = ntohs (ip->ip_len);
131  ip->ip_off = ntohs (ip->ip_off);
132 #endif
133  ip->ip_id = ntohs (ip->ip_id);
134  ret = g_malloc0 (len - dl_len);
135  bcopy (ip, ret, len - dl_len);
136  if (sz != NULL)
137  *sz = len - dl_len;
138  }
139  return ((struct ip *) ret);
140 }
141 
142 int
143 init_v6_capture_device (struct in6_addr src, struct in6_addr dest, char *filter)
144 {
145  int ret = -1;
146  char *interface = NULL;
147  char *a_dst, *a_src;
148  int free_filter = 0;
149  char name[INET6_ADDRSTRLEN];
150  char errbuf[PCAP_ERRBUF_SIZE];
151 
152  a_src = g_strdup (inet_ntop (AF_INET6, &src, name, INET6_ADDRSTRLEN));
153  a_dst = g_strdup (inet_ntop (AF_INET6, &dest, name, INET6_ADDRSTRLEN));
154 
155  if ((filter == NULL) || (filter[0] == '\0') || (filter[0] == '0'))
156  {
157  filter = g_malloc0 (256);
158  free_filter = 1;
159  if (v6_islocalhost (&src) == 0)
160  snprintf (filter, 256, "ip and (src host %s and dst host %s", a_src,
161  a_dst);
162  }
163  else
164  {
165  if (v6_islocalhost (&src) == 0)
166  filter = g_strdup (filter);
167  else
168  filter = g_malloc0 (1);
169  free_filter = 1;
170  }
171 
172  g_free (a_dst);
173  g_free (a_src);
174 
175  if ((interface = v6_routethrough (&src, &dest))
176  || (interface = pcap_lookupdev (errbuf)))
177  ret = bpf_open_live (interface, filter);
178 
179  if (free_filter != 0)
180  g_free (filter);
181 
182  return ret;
183 }
184 
185 struct ip6_hdr *
186 capture_next_v6_packet (int bpf, int timeout, int *sz)
187 {
188  int len;
189  int dl_len;
190  char *packet = NULL;
191  char *ret = NULL;
192  struct timeval past, now, then;
193  struct timezone tz;
194 
195  if (bpf < 0)
196  return NULL;
197 
198  dl_len = get_datalink_size (bpf_datalink (bpf));
199  bzero (&past, sizeof (past));
200  bzero (&now, sizeof (now));
201  gettimeofday (&then, &tz);
202 
203  for (;;)
204  {
205  bcopy (&then, &past, sizeof (then));
206  packet = (char *) bpf_next (bpf, &len);
207 
208  if (packet != NULL)
209  break;
210 
211  gettimeofday (&now, &tz);
212  if (now.tv_usec < past.tv_usec)
213  {
214  past.tv_sec++;
215  now.tv_usec += 1000000;
216  }
217 
218  if (timeout > 0)
219  {
220  if ((now.tv_sec - past.tv_sec) >= timeout)
221  break;
222  }
223  else
224  break;
225  }
226 
227  if (packet != NULL)
228  {
229  struct ip6_hdr *ip6;
230  ip6 = (struct ip6_hdr *) (packet + dl_len);
231 #ifdef BSD_BYTE_ORDERING
232  ip6->ip6_plen = ntohs (ip6->ip6_plen);
233 #endif
234  ret = g_malloc0 (len - dl_len);
235  bcopy (ip6, ret, len - dl_len);
236  if (sz != NULL)
237  *sz = len - dl_len;
238  }
239 
240  return ((struct ip6_hdr *) ret);
241 }
bpf_open_live
int bpf_open_live(char *iface, char *filter)
Definition: bpf_share.c:52
capture_packet.h
timeval
struct timeval timeval(unsigned long val)
Definition: nasl_builtin_synscan.c:105
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:789
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:268
name
const char * name
Definition: nasl_init.c:377
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.
Definition: capture_packet.c:44
bpf_datalink
int bpf_datalink(int bpf)
Definition: bpf_share.c:151
capture_next_packet
struct ip * capture_next_packet(int bpf, int timeout, int *sz)
Definition: capture_packet.c:86
get_datalink_size
int get_datalink_size(int datalink)
Definition: pcap.c:295
capture_next_v6_packet
struct ip6_hdr * capture_next_v6_packet(int bpf, int timeout, int *sz)
Definition: capture_packet.c:186
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:231
bpf_next
u_char * bpf_next(int bpf, int *caplen)
Definition: bpf_share.c:143
init_v6_capture_device
int init_v6_capture_device(struct in6_addr src, struct in6_addr dest, char *filter)
Definition: capture_packet.c:143
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:975