6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
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.
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.
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.
40 #ifdef HAVE_SYS_STAT_H
44 #ifdef NEED_SNPRINTF_H
45 # include "snprintf.h"
55 typedef int mode_t; /* for win32 */
56 #endif /* __MINGW32__ */
57 #endif /* HAVE_IO_H */
59 #include <epan/addr_resolv.h>
62 * This has to come after the include of <pcap.h>, as the include of
63 * <pcap.h> might cause <winsock2.h> to be included, and if we've
64 * already included <winsock.h> as a result of including <windows.h>,
65 * we get a bunch of redefinitions.
74 * Collect command-line arguments as a string consisting of the arguments,
75 * separated by spaces.
78 get_args_as_string(int argc, char **argv, int optind)
85 * Find out how long the string will be.
88 for (i = optind; i < argc; i++) {
89 len += strlen(argv[i]);
90 len++; /* space, or '\0' if this is the last argument */
94 * Allocate the buffer for the string.
96 argstring = g_malloc(len);
99 * Now construct the string.
101 strcpy(argstring, "");
104 strcat(argstring, argv[i]);
108 strcat(argstring, " ");
114 setup_tmpdir(char *dir)
116 int len = strlen(dir);
119 /* Append path separator if necessary */
120 if (dir[len - 1] == G_DIR_SEPARATOR) {
124 newdir = g_malloc(len + 2);
126 strcat(newdir, G_DIR_SEPARATOR_S);
132 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
134 static const char suffix[] = "XXXXXXXXXX";
135 int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
139 if (namebuflen < namelen) {
140 /* Stick in a truncated name, so that if this error is
141 reported with the file name, you at least get
143 snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
144 errno = ENAMETOOLONG;
147 strcpy(namebuf, dir);
148 strcat(namebuf, pfx);
149 strcat(namebuf, suffix);
151 /* The Single UNIX Specification doesn't say that "mkstemp()"
152 creates the temporary file with mode rw-------, so we
153 won't assume that all UNIXes will do so; instead, we set
154 the umask to 0077 to take away all group and other
155 permissions, attempt to create the file, and then put
157 old_umask = umask(0077);
158 tmp_fd = mkstemp(namebuf);
163 static char *tmpdir = NULL;
165 static char *temp = NULL;
167 static char *E_tmpdir;
170 #define P_tmpdir "/var/tmp"
174 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
178 static gboolean initialized;
181 if ((dir = getenv("TMPDIR")) != NULL)
182 tmpdir = setup_tmpdir(dir);
184 if ((dir = getenv("TEMP")) != NULL)
185 temp = setup_tmpdir(dir);
188 E_tmpdir = setup_tmpdir(P_tmpdir);
192 if (tmpdir != NULL) {
193 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
200 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
206 fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
210 return try_tempfile(namebuf, namebuflen, G_DIR_SEPARATOR_S "tmp", pfx);
213 /* Compute the difference between two seconds/microseconds time stamps. */
215 compute_timestamp_diff(gint *diffsec, gint *diffusec,
216 guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
219 /* The seconds part of the first time is the same as the seconds
220 part of the second time, so if the microseconds part of the first
221 time is less than the microseconds part of the second time, the
222 first time is before the second time. The microseconds part of
223 the delta should just be the difference between the microseconds
224 part of the first time and the microseconds part of the second
225 time; don't adjust the seconds part of the delta, as it's OK if
226 the microseconds part is negative. */
228 *diffsec = sec1 - sec2;
229 *diffusec = usec1 - usec2;
230 } else if (sec1 <= sec2) {
231 /* The seconds part of the first time is less than the seconds part
232 of the second time, so the first time is before the second time.
234 Both the "seconds" and "microseconds" value of the delta
235 should have the same sign, so if the difference between the
236 microseconds values would be *positive*, subtract 1,000,000
237 from it, and add one to the seconds value. */
238 *diffsec = sec1 - sec2;
239 if (usec2 >= usec1) {
240 *diffusec = usec1 - usec2;
242 *diffusec = (usec1 - 1000000) - usec2;
246 /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
247 *diffsec = sec1 - sec2;
248 if (usec2 <= usec1) {
249 *diffusec = usec1 - usec2;
251 *diffusec = (usec1 + 1000000) - usec2;
257 /* Try to figure out if we're remotely connected, e.g. via ssh or
258 Terminal Server, and create a capture filter that matches aspects of the
259 connection. We match the following environment variables:
261 SSH_CONNECTION (ssh): <remote IP> <remote port> <local IP> <local port>
262 SSH_CLIENT (ssh): <remote IP> <remote port> <local port>
263 REMOTEHOST (tcsh, others?): <remote name>
264 DISPLAY (x11): [remote name]:<display num>
265 CLIENTNAME (terminal server): <remote name>
268 gchar *get_conn_cfilter(void) {
269 static GString *filter_str = NULL;
270 gchar *env, **tokens;
272 if (filter_str == NULL) {
273 filter_str = g_string_new("");
275 if ((env = getenv("SSH_CONNECTION")) != NULL) {
276 tokens = g_strsplit(env, " ", 4);
278 g_string_sprintf(filter_str, "not (tcp port %s and %s host %s "
279 "and tcp port %s and %s host %s)", tokens[1], host_ip_af(tokens[0]), tokens[0],
280 tokens[3], host_ip_af(tokens[2]), tokens[2]);
281 return filter_str->str;
283 } else if ((env = getenv("SSH_CLIENT")) != NULL) {
284 tokens = g_strsplit(env, " ", 3);
285 g_string_sprintf(filter_str, "not (tcp port %s and %s host %s "
286 "and tcp port %s)", tokens[1], host_ip_af(tokens[0]), tokens[0], tokens[2]);
287 return filter_str->str;
288 } else if ((env = getenv("REMOTEHOST")) != NULL) {
289 if (strcasecmp(env, "localhost") == 0 || strcmp(env, "127.0.0.1") == 0) {
292 g_string_sprintf(filter_str, "not %s host %s", host_ip_af(env), env);
293 return filter_str->str;
294 } else if ((env = getenv("DISPLAY")) != NULL) {
295 tokens = g_strsplit(env, ":", 2);
296 if (tokens[0] && tokens[0][0] != 0) {
297 if (strcasecmp(tokens[0], "localhost") == 0 ||
298 strcmp(tokens[0], "127.0.0.1") == 0) {
301 g_string_sprintf(filter_str, "not %s host %s",
302 host_ip_af(tokens[0]), tokens[0]);
303 return filter_str->str;
305 } else if ((env = getenv("CLIENTNAME")) != NULL) {
306 if (g_strcasecmp("console", env) != 0) {
307 g_string_sprintf(filter_str, "not %s host %s", host_ip_af(env), env);
308 return filter_str->str;