4 * $Id: util.c,v 1.39 2000/03/21 06:51:59 guy 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 * Collect command-line arguments as a string consisting of the arguments,
188 * separated by spaces.
191 get_args_as_string(int argc, char **argv, int optind)
198 * Find out how long the string will be.
201 for (i = optind; i < argc; i++) {
202 len += strlen(argv[i]);
203 len++; /* space, or '\0' if this is the last argument */
207 * Allocate the buffer for the string.
209 argstring = g_malloc(len);
212 * Now construct the string.
214 strcpy(argstring, "");
217 strcat(argstring, argv[i]);
221 strcat(argstring, " ");
227 setup_tmpdir(char *dir)
229 int len = strlen(dir);
232 /* Append slash if necessary */
233 if (dir[len - 1] == '/') {
237 newdir = g_malloc(len + 2);
245 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
247 static const char suffix[] = "XXXXXXXXXX";
248 int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
252 if (namebuflen < namelen) {
253 /* Stick in a truncated name, so that if this error is
254 reported with the file name, you at least get
256 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
257 errno = ENAMETOOLONG;
260 strcpy(namebuf, dir);
261 strcat(namebuf, pfx);
262 strcat(namebuf, suffix);
264 /* The Single UNIX Specification doesn't say that "mkstemp()"
265 creates the temporary file with mode rw-------, so we
266 won't assume that all UNIXes will do so; instead, we set
267 the umask to 0077 to take away all group and other
268 permissions, attempt to create the file, and then put
270 old_umask = umask(0077);
271 tmp_fd = mkstemp(namebuf);
276 static char *tmpdir = NULL;
278 static char *temp = NULL;
280 static char *E_tmpdir;
283 #define P_tmpdir "/var/tmp"
287 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
291 static gboolean initialized;
294 if ((dir = getenv("TMPDIR")) != NULL)
295 tmpdir = setup_tmpdir(dir);
297 if ((dir = getenv("TEMP")) != NULL)
298 temp = setup_tmpdir(dir);
301 E_tmpdir = setup_tmpdir(P_tmpdir);
305 if (tmpdir != NULL) {
306 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
313 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
319 fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
323 return try_tempfile(namebuf, namebuflen, "/tmp", pfx);
326 /* ASCII/EBCDIC conversion tables from
327 * http://www.room42.com/store/computer_center/code_tables.shtml
329 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
330 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
331 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
332 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
333 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
334 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
335 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
336 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
337 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
338 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
339 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
340 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
341 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
342 0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
343 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
344 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
345 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
346 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
347 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
348 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
349 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
350 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
351 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
352 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
353 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
354 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
355 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
356 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
357 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
358 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
359 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
360 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
361 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
365 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
372 for (i = 0; i < bytes; i++, bufptr++) {
373 *bufptr = ASCII_translate_EBCDIC[*bufptr];
378 ASCII_to_EBCDIC1(guint8 c)
380 return ASCII_translate_EBCDIC[c];
383 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
384 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
385 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
386 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
387 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
388 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
389 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
390 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
391 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
392 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
393 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
394 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
395 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
396 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
397 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
398 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
399 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
400 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
401 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
402 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
403 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
404 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
405 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
406 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
407 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
408 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
409 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
410 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
411 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
412 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
413 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
414 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
415 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
419 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
426 for (i = 0; i < bytes; i++, bufptr++) {
427 *bufptr = EBCDIC_translate_ASCII[*bufptr];
432 EBCDIC_to_ASCII1(guint8 c)
434 return EBCDIC_translate_ASCII[c];
440 * If the ability to capture packets is added to Wiretap, these
441 * routines should be moved to the Wiretap source (with
442 * "get_interface_list()" and "free_interface_list()" renamed to
443 * "wtap_get_interface_list()" and "wtap_free_interface_list()",
444 * and modified to use Wiretap routines to attempt to open the
448 struct search_user_data {
454 search_for_if_cb(gpointer data, gpointer user_data);
457 free_if_cb(gpointer data, gpointer user_data);
461 get_interface_list(int *err, char *err_str)
464 gint nonloopback_pos = 0;
465 struct ifreq *ifr, *last;
467 struct ifreq ifrflags;
468 int sock = socket(AF_INET, SOCK_DGRAM, 0);
469 struct search_user_data user_data;
473 sprintf(err_str, "Error opening socket: %s",
479 * Since we have to grab the interface list all at once, we'll
480 * make plenty of room.
482 ifc.ifc_len = 1024 * sizeof(struct ifreq);
483 ifc.ifc_buf = malloc(ifc.ifc_len);
485 if (ioctl(sock, SIOCGIFCONF, &ifc) < 0 ||
486 ifc.ifc_len < sizeof(struct ifreq)) {
487 sprintf(err_str, "SIOCGIFCONF error getting list of interfaces: %s",
492 ifr = (struct ifreq *) ifc.ifc_req;
493 last = (struct ifreq *) ((char *) ifr + ifc.ifc_len);
496 * Skip addresses that begin with "dummy", or that include
497 * a ":" (the latter are Solaris virtuals).
499 if (strncmp(ifr->ifr_name, "dummy", 5) == 0 ||
500 strchr(ifr->ifr_name, ':') != NULL)
504 * If we already have this interface name on the list,
505 * don't add it (SIOCGIFCONF returns, at least on
506 * BSD-flavored systems, one entry per interface *address*;
507 * if an interface has multiple addresses, we get multiple
510 user_data.name = ifr->ifr_name;
511 user_data.found = FALSE;
512 g_list_foreach(il, search_for_if_cb, &user_data);
517 * Get the interface flags.
519 memset(&ifrflags, 0, sizeof ifrflags);
520 strncpy(ifrflags.ifr_name, ifr->ifr_name,
521 sizeof ifrflags.ifr_name);
522 if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifrflags) < 0) {
525 sprintf(err_str, "SIOCGIFFLAGS error getting flags for interface %s: %s",
526 ifr->ifr_name, strerror(errno));
531 * Skip interfaces that aren't up.
533 if (!(ifrflags.ifr_flags & IFF_UP))
537 * Skip interfaces that we can't open with "libpcap".
538 * Open with the minimum packet size - it appears that the
539 * IRIX SIOCSNOOPLEN "ioctl" may fail if the capture length
540 * supplied is too large, rather than just truncating it.
542 pch = pcap_open_live(ifr->ifr_name, MIN_PACKET_SIZE, 0, 0,
549 * If it's a loopback interface, add it at the end of the
550 * list, otherwise add it after the last non-loopback
551 * interface, so all loopback interfaces go at the end - we
552 * don't want a loopback interface to be the default capture
553 * device unless there are no non-loopback devices.
555 if ((ifrflags.ifr_flags & IFF_LOOPBACK) ||
556 strncmp(ifr->ifr_name, "lo", 2) == 0)
557 il = g_list_insert(il, g_strdup(ifr->ifr_name), -1);
559 il = g_list_insert(il, g_strdup(ifr->ifr_name),
562 * Insert the next non-loopback interface after this
570 ifr = (struct ifreq *) ((char *) ifr + ifr->ifr_addr.sa_len + IFNAMSIZ);
572 ifr = (struct ifreq *) ((char *) ifr + sizeof(struct ifreq));
581 * No interfaces found.
583 *err = NO_INTERFACES_FOUND;
589 g_list_foreach(il, free_if_cb, NULL);
594 *err = CANT_GET_INTERFACE_LIST;
599 search_for_if_cb(gpointer data, gpointer user_data)
601 struct search_user_data *search_user_data = user_data;
603 if (strcmp((char *)data, search_user_data->name) == 0)
604 search_user_data->found = TRUE;
608 get_interface_list(int *err, char *err_str) {
615 names = (wchar_t *)pcap_lookupdev(err_str);
620 /* If names[0] is less than 256 it means the first byte is 0
621 This implies that we are using unicode characters */
625 while (names[i] != 0)
626 newname[j++] = names[i++];
631 il = g_list_append(il, g_strdup(newname));
635 /* Otherwise we are in Windows 95/98 and using ascii(8 bit)
641 while (win95names[i] != 0)
642 newname[j++] = win95names[i++];
644 if (win95names[i] == 0)
647 il = g_list_append(il, g_strdup(newname));
656 free_if_cb(gpointer data, gpointer user_data)
662 free_interface_list(GList *if_list)
664 while (if_list != NULL) {
665 g_free(if_list->data);
666 if_list = g_list_remove_link(if_list, if_list);
670 #endif /* HAVE_LIBPCAP */
675 static const char *home = NULL;
677 char *homedrive, *homepath;
684 /* Return the cached value, if available */
689 * XXX - should we use USERPROFILE anywhere in this process?
690 * Is there a chance that it might be set but one or more of
691 * HOMEDRIVE or HOMEPATH isn't set?
693 homedrive = getenv("HOMEDRIVE");
694 if (homedrive != NULL) {
695 homepath = getenv("HOMEPATH");
696 if (homepath != NULL) {
698 * This is cached, so we don't need to worry about
699 * allocating multiple ones of them.
702 g_malloc(strlen(homedrive) + strlen(homepath) + 1);
703 strcpy(homestring, homedrive);
704 strcat(homestring, homepath);
707 * Trim off any trailing slash or backslash.
709 lastsep = find_last_pathname_separator(homestring);
710 if (lastsep != NULL && *(lastsep + 1) == '\0') {
712 * Last separator is the last character
713 * in the string. Nuke it.
727 home = getenv("HOME");
730 * Get their home directory from the password file.
731 * If we can't even find a password file entry for them,
734 pwd = getpwuid(getuid());
737 * This is cached, so we don't need to worry
738 * about allocating multiple ones of them.
740 home = g_strdup(pwd->pw_dir);