4 * $Id: util.c,v 1.36 2000/02/09 19:17:52 gram Exp $
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@zing.org>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
41 #ifdef HAVE_SYS_TYPES_H
42 #include <sys/types.h>
45 #ifdef HAVE_SYS_STAT_H
49 #ifdef NEED_SNPRINTF_H
55 # include "snprintf.h"
70 typedef int mode_t; /* for win32 */
75 #ifdef HAVE_SYS_SOCKET_H
76 #include <sys/socket.h>
79 #ifdef HAVE_SYS_IOCTL_H
80 #include <sys/ioctl.h>
87 #ifdef HAVE_SYS_SOCKIO_H
88 # include <sys/sockio.h>
96 * Given a pathname, return a pointer to the last pathname separator
97 * character in the pathname, or NULL if the pathname contains no
101 find_last_pathname_separator(char *path)
109 * We have to scan for '\' or '/'.
110 * Get to the end of the string.
112 separator = path + strlen(path); /* points to ending '\0' */
113 while (separator > path) {
115 if (c == '\\' || c == '/')
116 return separator; /* found it */
120 * OK, we didn't find any, so no directories - but there might
121 * be a drive letter....
123 return strchr(path, ':');
125 separator = strrchr(path, '/');
131 * Given a pathname, return the last component.
134 get_basename(char *path)
138 filename = find_last_pathname_separator(path);
139 if (filename == NULL) {
141 * There're no directories, drive letters, etc. in the
142 * name; the pathname *is* the file name.
147 * Skip past the pathname or drive letter separator.
155 * Given a pathname, return a string containing everything but the
156 * last component. NOTE: this overwrites the pathname handed into
160 get_dirname(char *path)
164 separator = find_last_pathname_separator(path);
165 if (separator == NULL) {
167 * There're no directories, drive letters, etc. in the
168 * name; there is no directory path to return.
174 * Get rid of the last pathname separator and the final file
180 * "path" now contains the pathname of the directory containing
181 * the file/directory to which it referred.
187 setup_tmpdir(char *dir)
189 int len = strlen(dir);
192 /* Append slash if necessary */
193 if (dir[len - 1] == '/') {
197 newdir = g_malloc(len + 2);
205 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
207 static const char suffix[] = "XXXXXXXXXX";
208 int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
212 if (namebuflen < namelen) {
213 /* Stick in a truncated name, so that if this error is
214 reported with the file name, you at least get
216 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
217 errno = ENAMETOOLONG;
220 strcpy(namebuf, dir);
221 strcat(namebuf, pfx);
222 strcat(namebuf, suffix);
224 /* The Single UNIX Specification doesn't say that "mkstemp()"
225 creates the temporary file with mode rw-------, so we
226 won't assume that all UNIXes will do so; instead, we set
227 the umask to 0077 to take away all group and other
228 permissions, attempt to create the file, and then put
230 old_umask = umask(0077);
231 tmp_fd = mkstemp(namebuf);
236 static char *tmpdir = NULL;
238 static char *temp = NULL;
240 static char *E_tmpdir;
243 #define P_tmpdir "/var/tmp"
247 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
251 static gboolean initialized;
254 if ((dir = getenv("TMPDIR")) != NULL)
255 tmpdir = setup_tmpdir(dir);
257 if ((dir = getenv("TEMP")) != NULL)
258 temp = setup_tmpdir(dir);
261 E_tmpdir = setup_tmpdir(P_tmpdir);
265 if (tmpdir != NULL) {
266 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
273 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
279 fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
283 return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
286 /* ASCII/EBCDIC conversion tables from
287 * http://www.room42.com/store/computer_center/code_tables.shtml
289 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
290 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
291 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
292 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
293 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
294 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
295 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
296 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
297 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
298 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
299 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
300 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
301 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
302 0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
303 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
304 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
305 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
306 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
307 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
308 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
309 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
310 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
311 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
312 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
313 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
314 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
315 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
316 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
317 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
318 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
319 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
320 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
321 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
325 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
332 for (i = 0; i < bytes; i++, bufptr++) {
333 *bufptr = ASCII_translate_EBCDIC[*bufptr];
338 ASCII_to_EBCDIC1(guint8 c)
340 return ASCII_translate_EBCDIC[c];
343 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
344 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
345 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
346 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
347 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
348 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
349 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
350 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
351 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
352 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
353 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
354 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
355 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
356 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
357 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
358 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
359 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
360 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
361 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
362 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
363 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
364 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
365 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
366 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
367 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
368 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
369 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
370 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
371 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
372 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
373 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
374 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
375 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
379 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
386 for (i = 0; i < bytes; i++, bufptr++) {
387 *bufptr = EBCDIC_translate_ASCII[*bufptr];
392 EBCDIC_to_ASCII1(guint8 c)
394 return EBCDIC_translate_ASCII[c];
400 * If the ability to capture packets is added to Wiretap, these
401 * routines should be moved to the Wiretap source (with
402 * "get_interface_list()" and "free_interface_list()" renamed to
403 * "wtap_get_interface_list()" and "wtap_free_interface_list()",
404 * and modified to use Wiretap routines to attempt to open the
408 struct search_user_data {
414 search_for_if_cb(gpointer data, gpointer user_data);
417 free_if_cb(gpointer data, gpointer user_data);
421 get_interface_list(int *err, char *err_str)
424 gint nonloopback_pos = 0;
425 struct ifreq *ifr, *last;
427 struct ifreq ifrflags;
428 int sock = socket(AF_INET, SOCK_DGRAM, 0);
429 struct search_user_data user_data;
433 sprintf(err_str, "Error opening socket: %s",
439 * Since we have to grab the interface list all at once, we'll
440 * make plenty of room.
442 ifc.ifc_len = 1024 * sizeof(struct ifreq);
443 ifc.ifc_buf = malloc(ifc.ifc_len);
445 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0 ||
446 ifc.ifc_len < sizeof(struct ifreq)) {
447 sprintf(err_str, "SIOCGIFCONF error getting list of interfaces: %s",
452 ifr = (struct ifreq *) ifc.ifc_req;
453 last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
456 * Skip addresses that begin with "dummy", or that include
457 * a ":" (the latter are Solaris virtuals).
459 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
460 strchr(ifr->ifr_name, ':') != NULL)
464 * If we already have this interface name on the list,
465 * don't add it (SIOCGIFCONF returns, at least on
466 * BSD-flavored systems, one entry per interface *address*;
467 * if an interface has multiple addresses, we get multiple
470 user_data.name = ifr->ifr_name;
471 user_data.found = FALSE;
472 g_list_foreach(il, search_for_if_cb, &user_data);
477 * Get the interface flags.
479 memset(&ifrflags, 0, sizeof ifrflags);
480 strncpy(ifrflags.ifr_name, ifr->ifr_name,
481 sizeof ifrflags.ifr_name);
482 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
485 sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s",
486 ifr->ifr_name, strerror(errno));
491 * Skip interfaces that aren't up.
493 if (!(ifrflags.ifr_flags & IFF_UP))
497 * Skip interfaces that we can't open with "libpcap".
498 * Open with the minimum packet size - it appears that the
499 * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
500 * supplied is too large, rather than just truncating it.
502 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
509 * If it's a loopback interface, add it at the end of the
510 * list, otherwise add it after the last non-loopback
511 * interface, so all loopback interfaces go at the end - we
512 * don't want a loopback interface to be the default capture
513 * device unless there are no non-loopback devices.
515 if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
516 strncmp(ifr->ifr_name, "lo", 2) == 0)
517 il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
519 il = g_list_insert(il, g_strdup(ifr->ifr_name),
522 * Insert the next non-loopback interface after this
530 ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
532 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
541 * No interfaces found.
543 *err = NO_INTERFACES_FOUND;
549 g_list_foreach(il, free_if_cb, NULL);
554 *err = CANT_GET_INTERFACE_LIST;
559 search_for_if_cb(gpointer data, gpointer user_data)
561 struct search_user_data *search_user_data = user_data;
563 if (strcmp((char *)data, search_user_data->name) == 0)
564 search_user_data->found = TRUE;
568 get_interface_list(int *err, char *err_str) {
574 names = (wchar_t *)pcap_lookupdev(err_str);
581 while (names[i] != 0)
582 newname[j++] = names[i++];
587 il = g_list_append(il, g_strdup(newname));
595 free_if_cb(gpointer data, gpointer user_data)
601 free_interface_list(GList *if_list)
603 while (if_list != NULL) {
604 g_free(if_list->data);
605 if_list = g_list_remove_link(if_list, if_list);
609 #endif /* HAVE_LIBPCAP */
615 static const char *home = NULL;
620 /* Return the cached value, if available */
624 env_value = getenv("HOME");
631 /* XXX - on NT, get the user name and append it to
632 "C:\winnt\profiles\"?
633 What about Windows 9x? */
636 pwd = getpwuid(getuid());
638 /* This is cached, so we don't need to worry
639 about allocating multiple ones of them. */
640 home = g_strdup(pwd->pw_dir);