Have the makefile run windepoyqt if it exists to copy the required dlls to the instal...
[metze/wireshark/wip.git] / capture-pcap-util-unix.c
1 /* capture-pcap-util-unix.c
2  * UN*X-specific utility routines for packet capture
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #include "config.h"
24
25 #include <glib.h>
26
27 #ifdef HAVE_LIBPCAP
28
29 #ifdef HAVE_PCAP_FINDALLDEVS
30
31 #include <pcap.h>
32
33 #else /* HAVE_PCAP_FINDALLDEVS */
34
35 #include <stdlib.h>
36 #include <string.h>
37 #include <stdio.h>
38 #include <errno.h>
39
40 #ifdef HAVE_UNISTD_H
41 #include <unistd.h>
42 #endif
43
44 #ifdef HAVE_SYS_SOCKET_H
45 #include <sys/socket.h>
46 #endif
47
48 #ifdef HAVE_SYS_IOCTL_H
49 #include <sys/ioctl.h>
50 #endif
51
52 /*
53  * Keep Digital UNIX happy when including <net/if.h>.
54  */
55 struct mbuf;
56 struct rtentry;
57 #include <net/if.h>
58
59 #ifdef HAVE_SYS_SOCKIO_H
60 # include <sys/sockio.h>
61 #endif
62
63 #include "capture-pcap-util.h"
64
65 #endif  /* HAVE_PCAP_FINDALLDEVS */
66
67 #include <capchild/capture_ifinfo.h>
68 #include "capture-pcap-util.h"
69 #include "capture-pcap-util-int.h"
70
71 #ifdef HAVE_PCAP_REMOTE
72 GList *
73 get_remote_interface_list(const char *hostname, const char *port,
74                           int auth_type, const char *username,
75                           const char *passwd, int *err, char **err_str)
76 {
77     struct pcap_rmtauth auth;
78     char source[PCAP_BUF_SIZE];
79     char errbuf[PCAP_ERRBUF_SIZE];
80     GList *result;
81
82     if (pcap_createsrcstr(source, PCAP_SRC_IFREMOTE, hostname, port,
83                           NULL, errbuf) == -1) {
84         *err = CANT_GET_INTERFACE_LIST;
85         if (err_str != NULL)
86             *err_str = cant_get_if_list_error_message(errbuf);
87         return NULL;
88     }
89
90     auth.type = auth_type;
91     auth.username = g_strdup(username);
92     auth.password = g_strdup(passwd);
93
94     result = get_interface_list_findalldevs_ex(source, &auth, err, err_str);
95     g_free(auth.username);
96     g_free(auth.password);
97
98     return result;
99 }
100 #endif
101
102 #ifdef HAVE_PCAP_FINDALLDEVS
103 GList *
104 get_interface_list(int *err, char **err_str)
105 {
106         return get_interface_list_findalldevs(err, err_str);
107 }
108 #else /* HAVE_PCAP_FINDALLDEVS */
109 struct search_user_data {
110         char    *name;
111         if_info_t *if_info;
112 };
113
114 static void
115 search_for_if_cb(gpointer data, gpointer user_data)
116 {
117         struct search_user_data *search_user_data = user_data;
118         if_info_t *if_info = data;
119
120         if (strcmp(if_info->name, search_user_data->name) == 0)
121                 search_user_data->if_info = if_info;
122 }
123
124 GList *
125 get_interface_list(int *err, char **err_str)
126 {
127         GList  *il = NULL;
128         gint    nonloopback_pos = 0;
129         struct  ifreq *ifr, *last;
130         struct  ifconf ifc;
131         struct  ifreq ifrflags;
132         int     sock = socket(AF_INET, SOCK_DGRAM, 0);
133         struct search_user_data user_data;
134         pcap_t *pch;
135         int len, lastlen;
136         char *buf;
137         if_info_t *if_info;
138         char errbuf[PCAP_ERRBUF_SIZE];
139         gboolean loopback;
140
141         if (sock < 0) {
142                 *err = CANT_GET_INTERFACE_LIST;
143                 if (err_str != NULL) {
144                         *err_str = g_strdup_printf(
145                             "Can't get list of interfaces: error opening socket: %s",
146                             g_strerror(errno));
147                 }
148                 return NULL;
149         }
150
151         /*
152          * This code came from: W. Richard Stevens: "UNIX Network Programming",
153          * Networking APIs: Sockets and XTI, Vol 1, page 434.
154          */
155         lastlen = 0;
156         len = 100 * sizeof(struct ifreq);
157         for ( ; ; ) {
158                 buf = g_malloc(len);
159                 ifc.ifc_len = len;
160                 ifc.ifc_buf = buf;
161                 memset (buf, 0, len);
162                 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
163                         if (errno != EINVAL || lastlen != 0) {
164                                 if (err_str != NULL) {
165                                         *err_str = g_strdup_printf(
166                                             "Can't get list of interfaces: SIOCGIFCONF ioctl error: %s",
167                                             g_strerror(errno));
168                                 }
169                                 goto fail;
170                         }
171                 } else {
172                         if ((unsigned int) ifc.ifc_len < sizeof(struct ifreq)) {
173                                 if (err_str != NULL) {
174                                         *err_str = g_strdup(
175                                             "Can't get list of interfaces: SIOCGIFCONF ioctl gave too small return buffer");
176                                 }
177                                 goto fail;
178                         }
179                         if (ifc.ifc_len == lastlen)
180                                 break;                  /* success, len has not changed */
181                         lastlen = ifc.ifc_len;
182                 }
183                 len += 10 * sizeof(struct ifreq);       /* increment */
184                 g_free(buf);
185         }
186         ifr = (struct ifreq *) ifc.ifc_req;
187         last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
188         while (ifr < last) {
189                 /*
190                  * Skip entries that begin with "dummy", or that include
191                  * a ":" (the latter are Solaris virtuals).
192                  */
193                 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
194                     strchr(ifr->ifr_name, ':') != NULL)
195                         goto next;
196
197                 /*
198                  * If we already have this interface name on the list,
199                  * don't add it, but, if we don't already have an IP
200                  * address for it, add that address (SIOCGIFCONF returns,
201                  * at least on BSD-flavored systems, one entry per
202                  * interface *address*; if an interface has multiple
203                  * addresses, we get multiple entries for it).
204                  */
205                 user_data.name = ifr->ifr_name;
206                 user_data.if_info = NULL;
207                 g_list_foreach(il, search_for_if_cb, &user_data);
208                 if (user_data.if_info != NULL) {
209                         if_info_add_address(user_data.if_info, &ifr->ifr_addr);
210                         goto next;
211                 }
212
213                 /*
214                  * Get the interface flags.
215                  */
216                 memset(&ifrflags, 0, sizeof ifrflags);
217                 g_strlcpy(ifrflags.ifr_name, ifr->ifr_name,
218                     sizeof ifrflags.ifr_name);
219                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
220                         if (errno == ENXIO)
221                                 goto next;
222                         if (err_str != NULL) {
223                                 *err_str = g_strdup_printf(
224                                     "Can't get list of interfaces: SIOCGIFFLAGS error getting flags for interface %s: %s",
225                                     ifr->ifr_name, g_strerror(errno));
226                         }
227                         goto fail;
228                 }
229
230                 /*
231                  * Skip interfaces that aren't up.
232                  */
233                 if (!(ifrflags.ifr_flags & IFF_UP))
234                         goto next;
235
236                 /*
237                  * Skip interfaces that we can't open with "libpcap".
238                  * Open with the minimum packet size - it appears that the
239                  * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
240                  * supplied is too large, rather than just truncating it.
241                  */
242                 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
243                     errbuf);
244                 if (pch == NULL)
245                         goto next;
246                 pcap_close(pch);
247
248                 /*
249                  * If it's a loopback interface, add it at the end of the
250                  * list, otherwise add it after the last non-loopback
251                  * interface, so all loopback interfaces go at the end - we
252                  * don't want a loopback interface to be the default capture
253                  * device unless there are no non-loopback devices.
254                  */
255                 loopback = ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
256                     strncmp(ifr->ifr_name, "lo", 2) == 0);
257                 if_info = if_info_new(ifr->ifr_name, NULL, loopback);
258                 if_info_add_address(if_info, &ifr->ifr_addr);
259                 if (loopback)
260                         il = g_list_append(il, if_info);
261                 else {
262                         il = g_list_insert(il, if_info, nonloopback_pos);
263                         /*
264                          * Insert the next non-loopback interface after this
265                          * one.
266                          */
267                         nonloopback_pos++;
268                 }
269
270         next:
271 #ifdef HAVE_SA_LEN
272                 ifr = (struct ifreq *) ((char *) ifr +
273                     (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr) ?
274                         ifr->ifr_addr.sa_len : sizeof(ifr->ifr_addr)) +
275                     IFNAMSIZ);
276 #else
277                 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
278 #endif
279         }
280
281 #ifdef linux
282         /*
283          * OK, maybe we have support for the "any" device, to do a cooked
284          * capture on all interfaces at once.
285          * Try opening it and, if that succeeds, add it to the end of
286          * the list of interfaces.
287          */
288         pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, errbuf);
289         if (pch != NULL) {
290                 /*
291                  * It worked; we can use the "any" device.
292                  */
293                 if_info = if_info_new("any",
294                     "Pseudo-device that captures on all interfaces", FALSE);
295                 il = g_list_insert(il, if_info, -1);
296                 pcap_close(pch);
297         }
298 #endif
299
300         g_free(ifc.ifc_buf);
301         close(sock);
302
303         if (il == NULL) {
304                 /*
305                  * No interfaces found.
306                  */
307                 *err = NO_INTERFACES_FOUND;
308                 if (err_str != NULL)
309                         *err_str = NULL;
310         }
311         return il;
312
313 fail:
314         if (il != NULL)
315                 free_interface_list(il);
316         g_free(ifc.ifc_buf);
317         close(sock);
318         *err = CANT_GET_INTERFACE_LIST;
319         return NULL;
320 }
321 #endif /* HAVE_PCAP_FINDALLDEVS */
322
323 /*
324  * Get an error message string for a CANT_GET_INTERFACE_LIST error from
325  * "get_interface_list()".
326  */
327 gchar *
328 cant_get_if_list_error_message(const char *err_str)
329 {
330         return g_strdup_printf("Can't get list of interfaces: %s", err_str);
331 }
332
333 /*
334  * Append the version of libpcap with which we were compiled to a GString.
335  */
336 void
337 get_compiled_pcap_version(GString *str)
338 {
339         /*
340          * NOTE: in *some* flavors of UN*X, the data from a shared
341          * library might be linked into executable images that are
342          * linked with that shared library, in which case you could
343          * look at pcap_version[] to get the version with which
344          * the program was compiled.
345          *
346          * In other flavors of UN*X, that doesn't happen, so
347          * pcap_version[] gives you the version the program is
348          * running with, not the version it was built with, and,
349          * in at least some of them, if the length of a data item
350          * referred to by the executable - such as the pcap_version[]
351          * string - isn't the same in the version of the library
352          * with which the program was built and the version with
353          * which it was run, the run-time linker will complain,
354          * which is Not Good.
355          *
356          * So, for now, we just give up on reporting the version
357          * of libpcap with which we were compiled.
358          */
359         g_string_append(str, "with libpcap");
360 }
361
362 /*
363  * Append the version of libpcap with which we we're running to a GString.
364  */
365 void
366 get_runtime_pcap_version(GString *str)
367 {
368         g_string_append_printf(str, "with ");
369 #ifdef HAVE_PCAP_LIB_VERSION
370         g_string_append(str, pcap_lib_version());
371 #else
372         g_string_append(str, "libpcap (version unknown)");
373 #endif
374 }
375
376 #else /* HAVE_LIBPCAP */
377
378 /*
379  * Append an indication that we were not compiled with libpcap
380  * to a GString.
381  */
382 void
383 get_compiled_pcap_version(GString *str)
384 {
385         g_string_append(str, "without libpcap");
386 }
387
388 /*
389  * Don't append anything, as we weren't even compiled to use WinPcap.
390  */
391 void
392 get_runtime_pcap_version(GString *str _U_)
393 {
394 }
395
396 #endif /* HAVE_LIBPCAP */