OpenVAS Libraries  9.0.3
capture_packet.c
Go to the documentation of this file.
1 /* Nessus Attack Scripting Language
2  *
3  * Copyright (C) 2002 - 2004 Tenable Network Security
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2,
7  * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include <arpa/inet.h> /* for inet_ntoa */
21 #include <string.h> /* for bcopy */
22 #include <glib.h> /* for gfree */
23 #include "../misc/bpf_share.h" /* for bpf_datalink */
24 #include "../misc/pcap_openvas.h" /* for get_datalink_size */
25 
26 #include <pcap.h>
27 
28 #include "capture_packet.h"
29 #include <netinet/ip.h>
30 
31 extern int islocalhost (struct in_addr *);
32 
33 
40 int
41 init_capture_device (struct in_addr src, struct in_addr dst, char *filter)
42 {
43  int ret = -1;
44  char *interface = NULL;
45  char *a_dst, *a_src;
46  char errbuf[PCAP_ERRBUF_SIZE];
47  int free_filter = 0;
48 
49  a_src = g_strdup (inet_ntoa (src));
50  a_dst = g_strdup (inet_ntoa (dst));
51 
52  if ((filter == NULL) || (filter[0] == '\0') || (filter[0] == '0'))
53  {
54  filter = g_malloc0 (256);
55  free_filter = 1;
56  if (islocalhost (&src) == 0)
57  snprintf (filter, 256, "ip and (src host %s and dst host %s)",
58  a_src, a_dst);
59 
60  }
61  else
62  {
63  if (islocalhost (&src) == 0)
64  filter = g_strdup (filter);
65  else
66  filter = g_malloc0 (1);
67  free_filter = 1;
68  }
69 
70  g_free (a_dst);
71  g_free (a_src);
72 
73  if ((interface = routethrough (&src, &dst))
74  || (interface = pcap_lookupdev (errbuf)))
75  ret = bpf_open_live (interface, filter);
76 
77 
78  if (free_filter != 0)
79  g_free (filter);
80 
81  return ret;
82 }
83 
84 struct ip *
85 capture_next_packet (int bpf, int timeout, int *sz)
86 {
87  int len;
88  int dl_len;
89  char *packet = NULL;
90  char *ret = NULL;
91  struct timeval past, now, then;
92  struct timezone tz;
93 
94  if (bpf < 0)
95  return NULL;
96 
97  dl_len = get_datalink_size (bpf_datalink (bpf));
98  bzero (&past, sizeof (past));
99  bzero (&now, sizeof (now));
100  gettimeofday (&then, &tz);
101  for (;;)
102  {
103  bcopy (&then, &past, sizeof (then));
104  packet = (char *) bpf_next (bpf, &len);
105  if (packet != NULL)
106  break;
107  gettimeofday (&now, &tz);
108 
109  if (now.tv_usec < past.tv_usec)
110  {
111  past.tv_sec++;
112  now.tv_usec += 1000000;
113  }
114 
115  if (timeout > 0)
116  {
117  if ((now.tv_sec - past.tv_sec) >= timeout)
118  break;
119  }
120  else
121  break;
122  }
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 
143 int
144 init_v6_capture_device (struct in6_addr src, struct in6_addr dst, char *filter)
145 {
146  int ret = -1;
147  char *interface = NULL;
148  char *a_dst, *a_src;
149  int free_filter = 0;
150  char name[INET6_ADDRSTRLEN];
151  char errbuf[PCAP_ERRBUF_SIZE];
152 
153  a_src = g_strdup (inet_ntop (AF_INET6, &src, name, INET6_ADDRSTRLEN));
154  a_dst = g_strdup (inet_ntop (AF_INET6, &dst, name, INET6_ADDRSTRLEN));
155 
156  if ((filter == NULL) || (filter[0] == '\0') || (filter[0] == '0'))
157  {
158  filter = g_malloc0 (256);
159  free_filter = 1;
160  if (v6_islocalhost (&src) == 0)
161  snprintf (filter, 256, "ip and (src host %s and dst host %s", a_src,
162  a_dst);
163  }
164  else
165  {
166  if (v6_islocalhost (&src) == 0)
167  filter = g_strdup (filter);
168  else
169  filter = g_malloc0 (1);
170  free_filter = 1;
171  }
172 
173  g_free (a_dst);
174  g_free (a_src);
175 
176  if ((interface = v6_routethrough (&src, &dst))
177  || (interface = pcap_lookupdev (errbuf)))
178  ret = bpf_open_live (interface, filter);
179 
180  if (free_filter != 0)
181  g_free (filter);
182 
183  return ret;
184 }
185 
186 
187 struct ip6_hdr *
188 capture_next_v6_packet (int bpf, int timeout, int *sz)
189 {
190  int len;
191  int dl_len;
192  char *packet = NULL;
193  char *ret = NULL;
194  struct timeval past, now, then;
195  struct timezone tz;
196 
197  if (bpf < 0)
198  return NULL;
199 
200  dl_len = get_datalink_size (bpf_datalink (bpf));
201  bzero (&past, sizeof (past));
202  bzero (&now, sizeof (now));
203  gettimeofday (&then, &tz);
204 
205  for (;;)
206  {
207  bcopy (&then, &past, sizeof (then));
208  packet = (char *) bpf_next (bpf, &len);
209 
210  if (packet != NULL)
211  break;
212 
213  gettimeofday (&now, &tz);
214  if (now.tv_usec < past.tv_usec)
215  {
216  past.tv_sec++;
217  now.tv_usec += 1000000;
218  }
219 
220  if (timeout > 0)
221  {
222  if ((now.tv_sec - past.tv_sec) >= timeout)
223  break;
224  }
225  else
226  break;
227  }
228 
229  if (packet != NULL)
230  {
231  struct ip6_hdr *ip6;
232  ip6 = (struct ip6_hdr *) (packet + dl_len);
233 #ifdef BSD_BYTE_ORDERING
234  ip6->ip6_plen = ntohs (ip6->ip6_plen);
235 #endif
236  ret = g_malloc0 (len - dl_len);
237  bcopy (ip6, ret, len - dl_len);
238  if (sz != NULL)
239  *sz = len - dl_len;
240  }
241 
242  return ((struct ip6_hdr *) ret);
243 }
int islocalhost(struct in_addr *)
Tests whether a packet sent to IP is LIKELY to route through the kernel localhost interface...
Definition: pcap.c:415
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:378
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:1061
int get_datalink_size(int datalink)
Definition: pcap.c:442
int bpf_datalink(int bpf)
Definition: bpf_share.c:146
int bpf_open_live(char *iface, char *filter)
Definition: bpf_share.c:40
const char * name
Definition: nasl_init.c:524
struct ip * capture_next_packet(int bpf, int timeout, int *sz)
struct timeval timeval(unsigned long val)
int init_v6_capture_device(struct in6_addr src, struct in6_addr dst, char *filter)
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:1244
u_char * bpf_next(int bpf, int *caplen)
Definition: bpf_share.c:137
struct ip6_hdr * capture_next_v6_packet(int bpf, int timeout, int *sz)
int init_capture_device(struct in_addr src, struct in_addr dst, char *filter)
Set up the pcap filter, and select the correct interface.