proto_registrar_get_nth(hfinfo->id) == hfinfo, so use the latter rather
[obnox/wireshark/wip.git] / pcap-util.c
1 /* pcap-util.c
2  * Utility routines for packet capture
3  *
4  * $Id: pcap-util.c,v 1.5 2002/04/01 03:55:44 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@ethereal.com>
8  * Copyright 1998 Gerald Combs
9  * 
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  * 
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  * 
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #ifdef HAVE_LIBPCAP
30
31 #include <glib.h>
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdio.h>
36 #include <errno.h>
37
38 #ifdef HAVE_UNISTD_H
39 #include <unistd.h>
40 #endif
41
42 #ifdef HAVE_SYS_TYPES_H
43 #include <sys/types.h>
44 #endif
45
46 #ifdef HAVE_SYS_SOCKET_H
47 #include <sys/socket.h>
48 #endif
49
50 #ifdef HAVE_SYS_IOCTL_H
51 #include <sys/ioctl.h>
52 #endif
53
54 #include <pcap.h>
55
56 #ifndef WIN32
57 #include <net/if.h>
58 #endif
59
60 #ifdef HAVE_SYS_SOCKIO_H
61 # include <sys/sockio.h>
62 #endif
63
64 #include "globals.h"
65
66 #ifdef WIN32
67 #include "capture-wpcap.h"
68 #endif
69
70 #include "pcap-util.h"
71
72 /*
73  * Get the data-link type for a libpcap device.
74  * This works around AIX 5.x's non-standard and incompatible-with-the-
75  * rest-of-the-universe libpcap.
76  */
77 int
78 get_pcap_linktype(pcap_t *pch, char *devname
79 #ifndef AIX
80         _U_
81 #endif
82 )
83 {
84         int linktype;
85 #ifdef AIX
86         char *ifacename;
87 #endif
88
89         linktype = pcap_datalink(pch);
90 #ifdef AIX
91
92         /*
93          * The libpcap that comes with AIX 5.x uses RFC 1573 ifType values
94          * rather than DLT_ values for link-layer types; the ifType values
95          * for LAN devices are:
96          *
97          *      Ethernet        6
98          *      802.3           7
99          *      Token Ring      9
100          *      FDDI            15
101          *
102          * The AIX names for LAN devices begin with:
103          *
104          *      Ethernet                en
105          *      802.3                   et
106          *      Token Ring              tr
107          *      FDDI                    fi
108          *
109          * (The difference between "Ethernet" and "802.3" is presumably
110          * whether packets have an Ethernet header, with a packet type,
111          * or an 802.3 header, with a packet length, followed by an 802.2
112          * header and possibly a SNAP header.)
113          *
114          * If the device name matches "linktype" interpreted as an ifType
115          * value, rather than as a DLT_ value, we will assume this is AIX's
116          * non-standard, incompatible libpcap, rather than a standard libpcap,
117          * and will map the link-layer type to the standard DLT_ value for
118          * that link-layer type, as that's what the rest of Ethereal expects.
119          *
120          * (This means the capture files won't be readable by a tcpdump
121          * linked with AIX's non-standard libpcap, but so it goes.  They
122          * *will* be readable by standard versions of tcpdump, Ethereal,
123          * and so on.)
124          *
125          * XXX - if we conclude we're using AIX libpcap, should we also
126          * set a flag to cause us to assume the time stamps are in
127          * seconds-and-nanoseconds form, and to convert them to
128          * seconds-and-microseconds form before processing them and
129          * writing them out?
130          */
131
132         /*
133          * Find the last component of the device name, which is the
134          * interface name.
135          */
136         ifacename = strchr(devname, '/');
137         if (ifacename == NULL)
138                 ifacename = devnames;
139
140         /* See if it matches any of the LAN device names. */
141         if (strncmp(ifacename, "en", 2) == 0) {
142                 if (linktype == 6) {
143                         /*
144                          * That's the RFC 1573 value for Ethernet; map it
145                          * to DLT_EN10MB.
146                          */
147                         linktype = 1;
148                 }
149         } else if (strncmp(ifacename, "et", 2) == 0) {
150                 if (linktype == 7) {
151                         /*
152                          * That's the RFC 1573 value for 802.3; map it to
153                          * DLT_EN10MB.
154                          * (libpcap, tcpdump, Ethereal, etc. don't care if
155                          * it's Ethernet or 802.3.)
156                          */
157                         linktype = 1;
158                 }
159         } else if (strncmp(ifacename, "tr") == 0) {
160                 if (linktype == 9) {
161                         /*
162                          * That's the RFC 1573 value for 802.5 (Token Ring);
163                          * map it to DLT_IEEE802, which is what's used for
164                          * Token Ring.
165                          */
166                         linktype = 6;
167                 }
168         } else if (strncmp(ifacename, "fi") == 0) {
169                 if (linktype == 15) {
170                         /*
171                          * That's the RFC 1573 value for FDDI; map it to
172                          * DLT_FDDI.
173                          */
174                         linktype = 10;
175                 }
176         }
177 #endif
178
179         return linktype;
180 }
181
182 /*
183  * If the ability to capture packets is added to Wiretap, these
184  * routines should be moved to the Wiretap source (with
185  * "get_interface_list()" and "free_interface_list()" renamed to
186  * "wtap_get_interface_list()" and "wtap_free_interface_list()",
187  * and modified to use Wiretap routines to attempt to open the
188  * interface.
189  */
190
191 struct search_user_data {
192         char    *name;
193         int     found;
194 };
195
196 static void
197 search_for_if_cb(gpointer data, gpointer user_data);
198
199 static void
200 free_if_cb(gpointer data, gpointer user_data);
201
202 #ifndef WIN32
203 GList *
204 get_interface_list(int *err, char *err_str)
205 {
206         GList  *il = NULL;
207         gint    nonloopback_pos = 0;
208         struct  ifreq *ifr, *last;
209         struct  ifconf ifc;
210         struct  ifreq ifrflags;
211         int     sock = socket(AF_INET, SOCK_DGRAM, 0);
212         struct search_user_data user_data;
213         pcap_t *pch;
214         int len, lastlen;
215         char *buf;
216
217         if (sock < 0) {
218                 sprintf(err_str, "Error opening socket: %s",
219                     strerror(errno));
220                 return NULL;
221         }
222
223         /*
224          * This code came from: W. Richard Stevens: "UNIX Network Programming",
225          * Networking APIs: Sockets and XTI, Vol 1, page 434.
226          */
227         lastlen = 0;
228         len = 100 * sizeof(struct ifreq);
229         for ( ; ; ) {
230                 buf = g_malloc(len);
231                 ifc.ifc_len = len;
232                 ifc.ifc_buf = buf;
233                 memset (buf, 0, len);
234                 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
235                         if (errno != EINVAL || lastlen != 0) {
236                                 sprintf(err_str,
237                                         "SIOCGIFCONF ioctl error getting list of interfaces: %s",
238                                         strerror(errno));
239                                 goto fail;
240                         }
241                 } else {
242                         if ((unsigned) ifc.ifc_len < sizeof(struct ifreq)) {
243                                 sprintf(err_str,
244                                         "SIOCGIFCONF ioctl gave too small return buffer");
245                                 goto fail;
246                         }
247                         if (ifc.ifc_len == lastlen)
248                                 break;                  /* success, len has not changed */
249                         lastlen = ifc.ifc_len;
250                 }
251                 len += 10 * sizeof(struct ifreq);       /* increment */
252                 g_free(buf);
253         }
254         ifr = (struct ifreq *) ifc.ifc_req;
255         last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
256         while (ifr < last) {
257                 /*
258                  * Skip addresses that begin with "dummy", or that include
259                  * a ":" (the latter are Solaris virtuals).
260                  */
261                 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
262                     strchr(ifr->ifr_name, ':') != NULL)
263                         goto next;
264
265                 /*
266                  * If we already have this interface name on the list,
267                  * don't add it (SIOCGIFCONF returns, at least on
268                  * BSD-flavored systems, one entry per interface *address*;
269                  * if an interface has multiple addresses, we get multiple
270                  * entries for it).
271                  */
272                 user_data.name = ifr->ifr_name;
273                 user_data.found = FALSE;
274                 g_list_foreach(il, search_for_if_cb, &user_data);
275                 if (user_data.found)
276                         goto next;
277
278                 /*
279                  * Get the interface flags.
280                  */
281                 memset(&ifrflags, 0, sizeof ifrflags);
282                 strncpy(ifrflags.ifr_name, ifr->ifr_name,
283                     sizeof ifrflags.ifr_name);
284                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
285                         if (errno == ENXIO)
286                                 goto next;
287                         sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s",
288                             ifr->ifr_name, strerror(errno));
289                         goto fail;
290                 }
291
292                 /*
293                  * Skip interfaces that aren't up.
294                  */
295                 if (!(ifrflags.ifr_flags & IFF_UP))
296                         goto next;
297
298                 /*
299                  * Skip interfaces that we can't open with "libpcap".
300                  * Open with the minimum packet size - it appears that the
301                  * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
302                  * supplied is too large, rather than just truncating it.
303                  */
304                 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
305                     err_str);
306                 if (pch == NULL)
307                         goto next;
308                 pcap_close(pch);
309
310                 /*
311                  * If it's a loopback interface, add it at the end of the
312                  * list, otherwise add it after the last non-loopback
313                  * interface, so all loopback interfaces go at the end - we
314                  * don't want a loopback interface to be the default capture
315                  * device unless there are no non-loopback devices.
316                  */
317                 if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
318                     strncmp(ifr->ifr_name, "lo", 2) == 0)
319                         il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
320                 else {
321                         il = g_list_insert(il, g_strdup(ifr->ifr_name),
322                             nonloopback_pos);
323                         /*
324                          * Insert the next non-loopback interface after this
325                          * one.
326                          */
327                         nonloopback_pos++;
328                 }
329
330         next:
331 #ifdef HAVE_SA_LEN
332                 ifr = (struct ifreq *) ((char *) ifr +
333                     (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_addr) ?
334                         ifr->ifr_addr.sa_len : sizeof(ifr->ifr_addr)) +
335                     IFNAMSIZ);
336 #else
337                 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
338 #endif
339         }
340
341 #ifdef linux
342         /*
343          * OK, maybe we have support for the "any" device, to do a cooked
344          * capture on all interfaces at once.
345          * Try opening it and, if that succeeds, add it to the end of
346          * the list of interfaces.
347          */
348         pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, err_str);
349         if (pch != NULL) {
350                 /*
351                  * It worked; we can use the "any" device.
352                  */
353                 il = g_list_insert(il, g_strdup("any"), -1);
354                 pcap_close(pch);
355         }
356 #endif
357
358         g_free(ifc.ifc_buf);
359         close(sock);
360
361         if (il == NULL) {
362                 /*
363                  * No interfaces found.
364                  */
365                 *err = NO_INTERFACES_FOUND;
366         }
367         return il;
368
369 fail:
370         if (il != NULL) {
371                 g_list_foreach(il, free_if_cb, NULL);
372                 g_list_free(il);
373         }
374         g_free(ifc.ifc_buf);
375         close(sock);
376         *err = CANT_GET_INTERFACE_LIST;
377         return NULL;
378 }
379
380 static void
381 search_for_if_cb(gpointer data, gpointer user_data)
382 {
383         struct search_user_data *search_user_data = user_data;
384
385         if (strcmp((char *)data, search_user_data->name) == 0)
386                 search_user_data->found = TRUE;
387 }
388 #else
389 GList *
390 get_interface_list(int *err, char *err_str) {
391   GList  *il = NULL;
392   wchar_t *names;
393   char *win95names; 
394   char newname[255];
395   int i, j, done;
396   
397   /* On Windows pcap_lookupdev is implemented by calling
398    * PacketGetAdapterNames.  According to the documentation I can find
399    * (http://winpcap.polito.it/docs/dll.htm#PacketGetAdapterNames)
400    * this means that:
401    *
402    * On Windows 95x, pcap_lookupdev returns an ASCII string with the
403    * names of the adapters separated by a single ASCII "\0", a double
404    * "\0", followed by the descriptions of the adapters separated by a
405    * single ASCII "\0" . The string is terminated by a double "\0".
406    *
407    * On Windows NTx, pcap_lookupdev returns the names of the adapters,
408    * in UNICODE format, separated by a single UNICODE "\0" (i.e. 2
409    * ASCII "\0"), a double UNICODE "\0", followed by the descriptions
410    * of the adapters, in ASCII format, separated by a single ASCII
411    * "\0" . The string is terminated by a double ASCII "\0".
412    */
413   names = (wchar_t *)pcap_lookupdev(err_str);
414   i = done = 0;
415
416   if (names) {
417           char* desc = 0;
418           int desc_pos = 0;
419
420           if (names[0]<256) { 
421                   /* If names[0] is less than 256 it means the first byte is 0
422                      This implies that we are using unicode characters */
423                   while(*(names+desc_pos) || *(names+desc_pos-1))
424                         desc_pos++;
425                   desc_pos++;   /* Step over the extra '\0' */
426                   desc = (char*)(names + desc_pos); /* cast *after* addition */
427
428                   do 
429                   { 
430                           j = 0; 
431                           while (names[i] != 0) 
432                                   newname[j++] = names[i++]; 
433                           i++; 
434                           if (names[i] == 0) 
435                                   done = 1; 
436
437                           newname[j++] = ' '; 
438                           newname[j++] = '('; 
439                           while (*desc) {
440                             newname[j++] = *desc++; 
441                           }
442                           desc++; 
443                           newname[j++] = ')'; 
444                           newname[j++] = 0; 
445                           il = g_list_append(il, g_strdup(newname)); 
446                   } while (!done); 
447           } 
448           else { 
449                   /* Otherwise we are in Windows 95/98 and using ascii(8 bit)
450                      characters */
451                   win95names=(char *)names; 
452                   while(*(win95names+desc_pos) || *(win95names+desc_pos-1))
453                         desc_pos++;
454                   desc_pos++;   /* Step over the extra '\0' */
455                   desc = win95names + desc_pos;
456
457                   do 
458                   { 
459                           j = 0; 
460                           while (win95names[i] != 0) 
461                                   newname[j++] = win95names[i++]; 
462                           i++; 
463                           if (win95names[i] == 0) 
464                                   done = 1; 
465                           newname[j++] = ' '; 
466                           newname[j++] = '('; 
467                           while (*desc) {
468                             newname[j++] = *desc++; 
469                           }
470                           newname[j++] = ')'; 
471                           newname[j++] = 0; 
472                           il = g_list_append(il, g_strdup(newname)); 
473                   } while (!done); 
474           } 
475   }
476   return(il);
477 }
478 #endif
479
480 static void
481 free_if_cb(gpointer data, gpointer user_data _U_)
482 {
483         g_free(data);
484 }
485
486 void
487 free_interface_list(GList *if_list)
488 {
489         while (if_list != NULL) {
490                 g_free(if_list->data);
491                 if_list = g_list_remove_link(if_list, if_list);
492         }
493 }
494
495 #endif /* HAVE_LIBPCAP */