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