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 #include "file_util.h"
42 #include <epan/address.h>
43 #include <epan/addr_resolv.h>
46 * This has to come after the include of <pcap.h>, as the include of
47 * <pcap.h> might cause <winsock2.h> to be included, and if we've
48 * already included <winsock.h> as a result of including <windows.h>,
49 * we get a bunch of redefinitions.
58 * Collect command-line arguments as a string consisting of the arguments,
59 * separated by spaces.
62 get_args_as_string(int argc, char **argv, int optind)
69 * Find out how long the string will be.
72 for (i = optind; i < argc; i++) {
73 len += strlen(argv[i]);
74 len++; /* space, or '\0' if this is the last argument */
78 * Allocate the buffer for the string.
80 argstring = g_malloc(len);
83 * Now construct the string.
85 strcpy(argstring, "");
88 strcat(argstring, argv[i]);
92 strcat(argstring, " ");
98 setup_tmpdir(const char *dir)
100 size_t len = strlen(dir);
103 /* Append path separator if necessary */
104 if (len != 0 && dir[len - 1] == G_DIR_SEPARATOR) {
108 newdir = g_malloc(len + 2);
110 strcat(newdir, G_DIR_SEPARATOR_S);
116 try_tempfile(char *namebuf, int namebuflen, const char *dir, const char *pfx)
118 static const char suffix[] = "XXXXXXXXXX";
119 int namelen = strlen(dir) + strlen(pfx) + sizeof suffix;
123 if (namebuflen < namelen) {
124 /* Stick in a truncated name, so that if this error is
125 reported with the file name, you at least get
127 g_snprintf(namebuf, namebuflen, "%s%s%s", dir, pfx, suffix);
128 errno = ENAMETOOLONG;
131 strcpy(namebuf, dir);
132 strcat(namebuf, pfx);
133 strcat(namebuf, suffix);
135 /* The Single UNIX Specification doesn't say that "mkstemp()"
136 creates the temporary file with mode rw-------, so we
137 won't assume that all UNIXes will do so; instead, we set
138 the umask to 0077 to take away all group and other
139 permissions, attempt to create the file, and then put
141 old_umask = umask(0077);
142 tmp_fd = eth_mkstemp(namebuf);
147 static const char *tmpdir = NULL;
149 static char *temp = NULL;
151 static const char *E_tmpdir;
154 #define P_tmpdir "/var/tmp"
158 create_tempfile(char *namebuf, int namebuflen, const char *pfx)
162 static gboolean initialized;
165 if ((dir = getenv("TMPDIR")) != NULL)
166 tmpdir = setup_tmpdir(dir);
168 if ((dir = getenv("TEMP")) != NULL)
169 temp = setup_tmpdir(dir);
172 E_tmpdir = setup_tmpdir(P_tmpdir);
176 if (tmpdir != NULL) {
177 fd = try_tempfile(namebuf, namebuflen, tmpdir, pfx);
184 fd = try_tempfile(namebuf, namebuflen, temp, pfx);
190 fd = try_tempfile(namebuf, namebuflen, E_tmpdir, pfx);
194 return try_tempfile(namebuf, namebuflen, G_DIR_SEPARATOR_S "tmp", pfx);
197 /* Compute the difference between two seconds/microseconds time stamps. */
199 compute_timestamp_diff(gint *diffsec, gint *diffusec,
200 guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
203 /* The seconds part of the first time is the same as the seconds
204 part of the second time, so if the microseconds part of the first
205 time is less than the microseconds part of the second time, the
206 first time is before the second time. The microseconds part of
207 the delta should just be the difference between the microseconds
208 part of the first time and the microseconds part of the second
209 time; don't adjust the seconds part of the delta, as it's OK if
210 the microseconds part is negative. */
212 *diffsec = sec1 - sec2;
213 *diffusec = usec1 - usec2;
214 } else if (sec1 <= sec2) {
215 /* The seconds part of the first time is less than the seconds part
216 of the second time, so the first time is before the second time.
218 Both the "seconds" and "microseconds" value of the delta
219 should have the same sign, so if the difference between the
220 microseconds values would be *positive*, subtract 1,000,000
221 from it, and add one to the seconds value. */
222 *diffsec = sec1 - sec2;
223 if (usec2 >= usec1) {
224 *diffusec = usec1 - usec2;
226 *diffusec = (usec1 - 1000000) - usec2;
230 /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
231 *diffsec = sec1 - sec2;
232 if (usec2 <= usec1) {
233 *diffusec = usec1 - usec2;
235 *diffusec = (usec1 + 1000000) - usec2;
241 /* Try to figure out if we're remotely connected, e.g. via ssh or
242 Terminal Server, and create a capture filter that matches aspects of the
243 connection. We match the following environment variables:
245 SSH_CONNECTION (ssh): <remote IP> <remote port> <local IP> <local port>
246 SSH_CLIENT (ssh): <remote IP> <remote port> <local port>
247 REMOTEHOST (tcsh, others?): <remote name>
248 DISPLAY (x11): [remote name]:<display num>
249 CLIENTNAME (terminal server): <remote name>
252 const gchar *get_conn_cfilter(void) {
253 static GString *filter_str = NULL;
254 gchar *env, **tokens;
256 if (filter_str == NULL) {
257 filter_str = g_string_new("");
259 if ((env = getenv("SSH_CONNECTION")) != NULL) {
260 tokens = g_strsplit(env, " ", 4);
262 g_string_sprintf(filter_str, "not (tcp port %s and %s host %s "
263 "and tcp port %s and %s host %s)", tokens[1], host_ip_af(tokens[0]), tokens[0],
264 tokens[3], host_ip_af(tokens[2]), tokens[2]);
265 return filter_str->str;
267 } else if ((env = getenv("SSH_CLIENT")) != NULL) {
268 tokens = g_strsplit(env, " ", 3);
269 g_string_sprintf(filter_str, "not (tcp port %s and %s host %s "
270 "and tcp port %s)", tokens[1], host_ip_af(tokens[0]), tokens[0], tokens[2]);
271 return filter_str->str;
272 } else if ((env = getenv("REMOTEHOST")) != NULL) {
273 if (strcasecmp(env, "localhost") == 0 || strcmp(env, "127.0.0.1") == 0) {
276 g_string_sprintf(filter_str, "not %s host %s", host_ip_af(env), env);
277 return filter_str->str;
278 } else if ((env = getenv("DISPLAY")) != NULL) {
279 tokens = g_strsplit(env, ":", 2);
280 if (tokens[0] && tokens[0][0] != 0) {
281 if (strcasecmp(tokens[0], "localhost") == 0 ||
282 strcmp(tokens[0], "127.0.0.1") == 0) {
285 g_string_sprintf(filter_str, "not %s host %s",
286 host_ip_af(tokens[0]), tokens[0]);
287 return filter_str->str;
289 } else if ((env = getenv("CLIENTNAME")) != NULL) {
290 if (g_strcasecmp("console", env) != 0) {
291 g_string_sprintf(filter_str, "not %s host %s", host_ip_af(env), env);
292 return filter_str->str;