Added two new arguments to epan_init() and proto_init() to
[obnox/wireshark/wip.git] / util.c
1 /* util.c
2  * Utility routines
3  *
4  * $Id: util.c,v 1.50 2001/03/22 06:14:27 guy Exp $
5  *
6  * Ethereal - Network traffic analyzer
7  * By Gerald Combs <gerald@zing.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * 
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  * 
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <stdio.h>
35 #include <errno.h>
36
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #ifdef HAVE_SYS_TYPES_H
42 #include <sys/types.h>
43 #endif
44
45 #ifdef HAVE_SYS_STAT_H
46 #include <sys/stat.h>
47 #endif
48
49 #ifdef NEED_SNPRINTF_H
50 # include "snprintf.h"
51 #endif
52
53 #ifndef WIN32
54 #include <pwd.h>
55 #endif
56
57 #ifdef NEED_MKSTEMP
58 #include "mkstemp.h"
59 #endif
60
61 #include "util.h"
62
63 #ifdef HAVE_IO_H
64 #include <io.h>
65 typedef int mode_t;     /* for win32 */
66 #endif
67
68 #ifdef HAVE_LIBPCAP
69
70 #ifdef HAVE_SYS_SOCKET_H
71 #include <sys/socket.h>
72 #endif
73
74 #ifdef HAVE_SYS_IOCTL_H
75 #include <sys/ioctl.h>
76 #endif
77
78 #include <pcap.h>
79
80 #ifndef WIN32
81 #include <net/if.h>
82 #endif
83
84 #ifdef HAVE_SYS_SOCKIO_H
85 # include <sys/sockio.h>
86 #endif
87
88 #include "globals.h"
89
90 #endif
91
92 /*
93  * Given a pathname, return:
94  *
95  *      the errno, if an attempt to "stat()" the file fails;
96  *
97  *      EISDIR, if the attempt succeeded and the file turned out
98  *      to be a directory;
99  *
100  *      0, if the attempt succeeded and the file turned out not
101  *      to be a directory.
102  */
103
104 /*
105  * Visual C++ on Win32 systems doesn't define these.  (Old UNIX systems don't
106  * define them either.)
107  *
108  * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
109  */
110 #ifndef S_ISREG
111 #define S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
112 #endif
113 #ifndef S_IFIFO
114 #define S_IFIFO _S_IFIFO
115 #endif
116 #ifndef S_ISFIFO
117 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
118 #endif
119 #ifndef S_ISDIR
120 #define S_ISDIR(mode)   (((mode) & S_IFMT) == S_IFDIR)
121 #endif
122
123 int
124 test_for_directory(const char *path)
125 {
126         struct stat statb;
127
128         if (stat(path, &statb) < 0)
129                 return errno;
130
131         if (S_ISDIR(statb.st_mode))
132                 return EISDIR;
133         else
134                 return 0;
135 }
136
137 /*
138  * Given a pathname, return a pointer to the last pathname separator
139  * character in the pathname, or NULL if the pathname contains no
140  * separators.
141  */
142 char *
143 find_last_pathname_separator(char *path)
144 {
145         char *separator;
146
147 #ifdef WIN32
148         char c;
149
150         /*
151          * We have to scan for '\' or '/'.
152          * Get to the end of the string.
153          */
154         separator = path + strlen(path);        /* points to ending '\0' */
155         while (separator > path) {
156                 c = *--separator;
157                 if (c == '\\' || c == '/')
158                         return separator;       /* found it */
159         }
160
161         /*
162          * OK, we didn't find any, so no directories - but there might
163          * be a drive letter....
164          */
165         return strchr(path, ':');
166 #else
167         separator = strrchr(path, '/');
168 #endif
169         return separator;
170 }
171
172 /*
173  * Given a pathname, return the last component.
174  */
175 char *
176 get_basename(char *path)
177 {
178         char *filename;
179
180         filename = find_last_pathname_separator(path);
181         if (filename == NULL) {
182                 /*
183                  * There're no directories, drive letters, etc. in the
184                  * name; the pathname *is* the file name.
185                  */
186                 filename = path;
187         } else {
188                 /*
189                  * Skip past the pathname or drive letter separator.
190                  */
191                 filename++;
192         }
193         return filename;
194 }
195
196 /*
197  * Given a pathname, return a string containing everything but the
198  * last component.  NOTE: this overwrites the pathname handed into
199  * it....
200  */
201 char *
202 get_dirname(char *path)
203 {
204         char *separator;
205
206         separator = find_last_pathname_separator(path);
207         if (separator == NULL) {
208                 /*
209                  * There're no directories, drive letters, etc. in the
210                  * name; there is no directory path to return.
211                  */
212                 return NULL;
213         }
214
215         /*
216          * Get rid of the last pathname separator and the final file
217          * name following it.
218          */
219         *separator = '\0';
220
221         /*
222          * "path" now contains the pathname of the directory containing
223          * the file/directory to which it referred.
224          */
225         return path;
226 }
227
228 /*
229  * Collect command-line arguments as a string consisting of the arguments,
230  * separated by spaces.
231  */
232 char *
233 get_args_as_string(int argc, char **argv, int optind)
234 {
235         int len;
236         int i;
237         char *argstring;
238
239         /*
240          * Find out how long the string will be.
241          */
242         len = 0;
243         for (i = optind; i < argc; i++) {
244                 len += strlen(argv[i]);
245                 len++;  /* space, or '\0' if this is the last argument */
246         }
247
248         /*
249          * Allocate the buffer for the string.
250          */
251         argstring = g_malloc(len);
252
253         /*
254          * Now construct the string.
255          */
256         strcpy(argstring, "");
257         i = optind;
258         for (;;) {
259                 strcat(argstring, argv[i]);
260                 i++;
261                 if (i == argc)
262                         break;
263                 strcat(argstring, " ");
264         }
265         return argstring;
266 }
267
268 static char *
269 setup_tmpdir(char *dir)
270 {
271         int len = strlen(dir);
272         char *newdir;
273
274         /* Append slash if necessary */
275         if (dir[len - 1] == '/') {
276                 newdir = dir;
277         }
278         else {
279                 newdir = g_malloc(len + 2);
280                 strcpy(newdir, dir);
281                 strcat(newdir, "/");
282         }
283         return newdir;
284 }
285
286 static int
287 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
288 {
289         static const char suffix[] = "XXXXXXXXXX";
290         int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
291         mode_t old_umask;
292         int tmp_fd;
293
294         if (namebuflen < namelen) {
295                 /* Stick in a truncated name, so that if this error is
296                    reported with the file name, you at least get
297                    something. */
298                 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
299                 errno = ENAMETOOLONG;
300                 return -1;
301         }
302         strcpy(namebuf, dir);
303         strcat(namebuf, pfx);
304         strcat(namebuf, suffix);
305
306         /* The Single UNIX Specification doesn't say that "mkstemp()"
307            creates the temporary file with mode rw-------, so we
308            won't assume that all UNIXes will do so; instead, we set
309            the umask to 0077 to take away all group and other
310            permissions, attempt to create the file, and then put
311            the umask back. */
312         old_umask = umask(0077);
313         tmp_fd = mkstemp(namebuf);
314         umask(old_umask);
315         return tmp_fd;
316 }
317
318 static char *tmpdir = NULL;
319 #ifdef WIN32
320 static char *temp = NULL;
321 #endif
322 static char *E_tmpdir;
323
324 #ifndef P_tmpdir
325 #define P_tmpdir "/var/tmp"
326 #endif
327
328 int
329 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
330 {
331         char *dir;
332         int fd;
333         static gboolean initialized;
334
335         if (!initialized) {
336                 if ((dir = getenv("TMPDIR")) != NULL)
337                         tmpdir = setup_tmpdir(dir);
338 #ifdef WIN32
339                 if ((dir = getenv("TEMP")) != NULL)
340                         temp = setup_tmpdir(dir);
341 #endif
342
343                 E_tmpdir = setup_tmpdir(P_tmpdir);
344                 initialized = TRUE;
345         }
346
347         if (tmpdir != NULL) {
348                 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
349                 if (fd != -1)
350                         return fd;
351         }
352
353 #ifdef WIN32
354         if (temp != NULL) {
355                 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
356                 if (fd != -1)
357                         return fd;
358         }
359 #endif
360
361         fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
362         if (fd != -1)
363                 return fd;
364
365         return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
366 }
367
368 /* ASCII/EBCDIC conversion tables from
369  * http://www.room42.com/store/computer_center/code_tables.shtml
370  */
371 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
372     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
373     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
374     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
375     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
376     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
377     0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
378     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
379     0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
380     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
381     0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
382     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
383     0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
384     0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
385     0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
386     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
387     0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
388     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
389     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
390     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
391     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
392     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
393     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
394     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
395     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
396     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
397     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
398     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
399     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
400     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
401     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
402     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
403     0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
404 };
405
406 void
407 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
408 {
409         guint   i;
410         guint8  *bufptr;
411
412         bufptr = buf;
413
414         for (i = 0; i < bytes; i++, bufptr++) {
415                 *bufptr = ASCII_translate_EBCDIC[*bufptr];
416         }
417 }
418
419 guint8
420 ASCII_to_EBCDIC1(guint8 c)
421 {
422         return ASCII_translate_EBCDIC[c];
423 }
424
425 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
426     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
427     0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
428     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
429     0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
430     0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
431     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
432     0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
433     0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
434     0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
435     0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
436     0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
437     0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
438     0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
439     0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
440     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
441     0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
442     0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
443     0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
444     0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
445     0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
446     0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
447     0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
448     0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
449     0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
450     0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
451     0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
452     0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,                                             
453     0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
454     0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
455     0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
456     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,                 
457     0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
458 };
459
460 void
461 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
462 {
463         guint   i;
464         guint8  *bufptr;
465
466         bufptr = buf;
467
468         for (i = 0; i < bytes; i++, bufptr++) {
469                 *bufptr = EBCDIC_translate_ASCII[*bufptr];
470         }
471 }
472
473 guint8
474 EBCDIC_to_ASCII1(guint8 c)
475 {
476         return EBCDIC_translate_ASCII[c];
477 }
478
479 #ifdef HAVE_LIBPCAP
480
481 /*
482  * If the ability to capture packets is added to Wiretap, these
483  * routines should be moved to the Wiretap source (with
484  * "get_interface_list()" and "free_interface_list()" renamed to
485  * "wtap_get_interface_list()" and "wtap_free_interface_list()",
486  * and modified to use Wiretap routines to attempt to open the
487  * interface.
488  */
489
490 struct search_user_data {
491         char    *name;
492         int     found;
493 };
494
495 static void
496 search_for_if_cb(gpointer data, gpointer user_data);
497
498 static void
499 free_if_cb(gpointer data, gpointer user_data);
500
501 #ifndef WIN32
502 GList *
503 get_interface_list(int *err, char *err_str)
504 {
505         GList  *il = NULL;
506         gint    nonloopback_pos = 0;
507         struct  ifreq *ifr, *last;
508         struct  ifconf ifc;
509         struct  ifreq ifrflags;
510         int     sock = socket(AF_INET, SOCK_DGRAM, 0);
511         struct search_user_data user_data;
512         pcap_t *pch;
513         int len, lastlen;
514         char *buf;
515
516         if (sock < 0) {
517                 sprintf(err_str, "Error opening socket: %s",
518                     strerror(errno));
519                 return NULL;
520         }
521
522         /*
523          * This code came from: W. Richard Stevens: "UNIX Network Programming",
524          * Networking APIs: Sockets and XTI, Vol 1, page 434.
525          */
526         lastlen = 0;
527         len = 100 * sizeof(struct ifreq);
528         for ( ; ; ) {
529                 buf = g_malloc(len);
530                 ifc.ifc_len = len;
531                 ifc.ifc_buf = buf;
532                 memset (buf, 0, len);
533                 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) {
534                         if (errno != EINVAL || lastlen != 0) {
535                                 sprintf(err_str,
536                                         "SIOCGIFCONF ioctl error getting list of interfaces: %s",
537                                         strerror(errno));
538                                 goto fail;
539                         }
540                 } else {
541                         if (ifc.ifc_len < sizeof(struct ifreq)) {
542                                 sprintf(err_str,
543                                         "SIOCGIFCONF ioctl gave too small return buffer");
544                                 goto fail;
545                         }
546                         if (ifc.ifc_len == lastlen)
547                                 break;                  /* success, len has not changed */
548                         lastlen = ifc.ifc_len;
549                 }
550                 len += 10 * sizeof(struct ifreq);       /* increment */
551                 g_free(buf);
552         }
553         ifr = (struct ifreq *) ifc.ifc_req;
554         last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
555         while (ifr < last) {
556                 /*
557                  * Skip addresses that begin with "dummy", or that include
558                  * a ":" (the latter are Solaris virtuals).
559                  */
560                 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
561                     strchr(ifr->ifr_name, ':') != NULL)
562                         goto next;
563
564                 /*
565                  * If we already have this interface name on the list,
566                  * don't add it (SIOCGIFCONF returns, at least on
567                  * BSD-flavored systems, one entry per interface *address*;
568                  * if an interface has multiple addresses, we get multiple
569                  * entries for it).
570                  */
571                 user_data.name = ifr->ifr_name;
572                 user_data.found = FALSE;
573                 g_list_foreach(il, search_for_if_cb, &user_data);
574                 if (user_data.found)
575                         goto next;
576
577                 /*
578                  * Get the interface flags.
579                  */
580                 memset(&ifrflags, 0, sizeof ifrflags);
581                 strncpy(ifrflags.ifr_name, ifr->ifr_name,
582                     sizeof ifrflags.ifr_name);
583                 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
584                         if (errno == ENXIO)
585                                 goto next;
586                         sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s",
587                             ifr->ifr_name, strerror(errno));
588                         goto fail;
589                 }
590
591                 /*
592                  * Skip interfaces that aren't up.
593                  */
594                 if (!(ifrflags.ifr_flags & IFF_UP))
595                         goto next;
596
597                 /*
598                  * Skip interfaces that we can't open with "libpcap".
599                  * Open with the minimum packet size - it appears that the
600                  * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
601                  * supplied is too large, rather than just truncating it.
602                  */
603                 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
604                     err_str);
605                 if (pch == NULL)
606                         goto next;
607                 pcap_close(pch);
608
609                 /*
610                  * If it's a loopback interface, add it at the end of the
611                  * list, otherwise add it after the last non-loopback
612                  * interface, so all loopback interfaces go at the end - we
613                  * don't want a loopback interface to be the default capture
614                  * device unless there are no non-loopback devices.
615                  */
616                 if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
617                     strncmp(ifr->ifr_name, "lo", 2) == 0)
618                         il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
619                 else {
620                         il = g_list_insert(il, g_strdup(ifr->ifr_name),
621                             nonloopback_pos);
622                         /*
623                          * Insert the next non-loopback interface after this
624                          * one.
625                          */
626                         nonloopback_pos++;
627                 }
628
629         next:
630 #ifdef HAVE_SA_LEN
631                 ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
632 #else
633                 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
634 #endif
635         }
636
637 #ifdef linux
638         /*
639          * OK, maybe we have support for the "any" device, to do a cooked
640          * capture on all interfaces at once.
641          * Try opening it and, if that succeeds, add it to the end of
642          * the list of interfaces.
643          */
644         pch = pcap_open_live("any", MIN_PACKET_SIZE, 0, 0, err_str);
645         if (pch != NULL) {
646                 /*
647                  * It worked; we can use the "any" device.
648                  */
649                 il = g_list_insert(il, g_strdup("any"), -1);
650                 pcap_close(pch);
651         }
652 #endif
653
654         g_free(ifc.ifc_buf);
655         close(sock);
656
657         if (il == NULL) {
658                 /*
659                  * No interfaces found.
660                  */
661                 *err = NO_INTERFACES_FOUND;
662         }
663         return il;
664
665 fail:
666         if (il != NULL) {
667                 g_list_foreach(il, free_if_cb, NULL);
668                 g_list_free(il);
669         }
670         g_free(ifc.ifc_buf);
671         close(sock);
672         *err = CANT_GET_INTERFACE_LIST;
673         return NULL;
674 }
675
676 static void
677 search_for_if_cb(gpointer data, gpointer user_data)
678 {
679         struct search_user_data *search_user_data = user_data;
680
681         if (strcmp((char *)data, search_user_data->name) == 0)
682                 search_user_data->found = TRUE;
683 }
684 #else
685 GList *
686 get_interface_list(int *err, char *err_str) {
687   GList  *il = NULL;
688   wchar_t *names;
689   char *win95names; 
690   char newname[255];
691   int i, j, done;
692   
693   names = (wchar_t *)pcap_lookupdev(err_str);
694   i = done = 0;
695
696   if (names) {
697           if (names[0]<256) { 
698                   /* If names[0] is less than 256 it means the first byte is 0
699                      This implies that we are using unicode characters */
700                   do 
701                   { 
702                           j = 0; 
703                           while (names[i] != 0) 
704                                   newname[j++] = names[i++]; 
705                           i++; 
706                           if (names[i] == 0) 
707                                   done = 1; 
708                           newname[j++] = 0; 
709                           il = g_list_append(il, g_strdup(newname)); 
710                   } while (!done); 
711           } 
712           else { 
713                   /* Otherwise we are in Windows 95/98 and using ascii(8 bit)
714                      characters */
715                   do 
716                   { 
717                           win95names=(char *)names; 
718                           j = 0; 
719                           while (win95names[i] != 0) 
720                                   newname[j++] = win95names[i++]; 
721                           i++; 
722                           if (win95names[i] == 0) 
723                                   done = 1; 
724                           newname[j++] = 0; 
725                           il = g_list_append(il, g_strdup(newname)); 
726                   } while (!done); 
727           } 
728   }
729   return(il);
730 }
731 #endif
732
733 static void
734 free_if_cb(gpointer data, gpointer user_data)
735 {
736         g_free(data);
737 }
738
739 void
740 free_interface_list(GList *if_list)
741 {
742         while (if_list != NULL) {
743                 g_free(if_list->data);
744                 if_list = g_list_remove_link(if_list, if_list);
745         }
746 }
747
748 #endif /* HAVE_LIBPCAP */
749
750
751 /* Compute the difference between two seconds/microseconds time stamps. */
752 void
753 compute_timestamp_diff(gint *diffsec, gint *diffusec,
754         guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
755 {
756   if (sec1 == sec2) {
757     /* The seconds part of the first time is the same as the seconds
758        part of the second time, so if the microseconds part of the first
759        time is less than the microseconds part of the second time, the
760        first time is before the second time.  The microseconds part of
761        the delta should just be the difference between the microseconds
762        part of the first time and the microseconds part of the second
763        time; don't adjust the seconds part of the delta, as it's OK if
764        the microseconds part is negative. */
765
766     *diffsec = sec1 - sec2;
767     *diffusec = usec1 - usec2;
768   } else if (sec1 <= sec2) {
769     /* The seconds part of the first time is less than the seconds part
770        of the second time, so the first time is before the second time.
771
772        Both the "seconds" and "microseconds" value of the delta
773        should have the same sign, so if the difference between the
774        microseconds values would be *positive*, subtract 1,000,000
775        from it, and add one to the seconds value. */
776     *diffsec = sec1 - sec2;
777     if (usec2 >= usec1) {
778       *diffusec = usec1 - usec2;
779     } else {
780       *diffusec = (usec1 - 1000000) - usec2;
781       (*diffsec)++;
782     }
783   } else {
784     /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
785     *diffsec = sec1 - sec2;
786     if (usec2 <= usec1) {
787       *diffusec = usec1 - usec2;
788     } else {
789       *diffusec = (usec1 + 1000000) - usec2;
790       (*diffsec)--;
791     }
792   }
793 }