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/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 /* ASCII/EBCDIC conversion tables from
214 * http://www.room42.com/store/computer_center/code_tables.shtml
217 static guint8 ASCII_translate_EBCDIC [ 256 ] = {
218 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
219 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
220 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
221 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
222 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D,
223 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
224 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8,
225 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
226 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8,
227 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
228 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
229 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
230 0x7D, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
231 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
232 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
233 0xA8, 0xA9, 0xC0, 0x6A, 0xD0, 0xA1, 0x4B,
234 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
235 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
236 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
237 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
238 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
239 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
240 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
241 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
242 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
243 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
244 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
245 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
246 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
247 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
248 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B,
249 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B, 0x4B
253 ASCII_to_EBCDIC(guint8 *buf, guint bytes)
260 for (i = 0; i < bytes; i++, bufptr++) {
261 *bufptr = ASCII_translate_EBCDIC[*bufptr];
266 ASCII_to_EBCDIC1(guint8 c)
268 return ASCII_translate_EBCDIC[c];
272 static guint8 EBCDIC_translate_ASCII [ 256 ] = {
273 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
274 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
275 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
276 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
277 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
278 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
279 0x2E, 0x2E, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
280 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x2E, 0x3F,
281 0x20, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
282 0x2E, 0x2E, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
283 0x26, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
284 0x2E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
285 0x2D, 0x2F, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
286 0x2E, 0x7C, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
287 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
288 0x2E, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
289 0x2E, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
290 0x69, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
291 0x2E, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
292 0x72, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
293 0x2E, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
294 0x7A, 0x2E, 0x2E, 0x2E, 0x5B, 0x2E, 0x2E,
295 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
296 0x2E, 0x2E, 0x2E, 0x2E, 0x5D, 0x2E, 0x2E,
297 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
298 0x49, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
299 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51,
300 0x52, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
301 0x5C, 0x2E, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
302 0x5A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E,
303 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
304 0x39, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E
308 EBCDIC_to_ASCII(guint8 *buf, guint bytes)
315 for (i = 0; i < bytes; i++, bufptr++) {
316 *bufptr = EBCDIC_translate_ASCII[*bufptr];
321 EBCDIC_to_ASCII1(guint8 c)
323 return EBCDIC_translate_ASCII[c];
326 /* Compute the difference between two seconds/microseconds time stamps. */
328 compute_timestamp_diff(gint *diffsec, gint *diffusec,
329 guint32 sec1, guint32 usec1, guint32 sec2, guint32 usec2)
332 /* The seconds part of the first time is the same as the seconds
333 part of the second time, so if the microseconds part of the first
334 time is less than the microseconds part of the second time, the
335 first time is before the second time. The microseconds part of
336 the delta should just be the difference between the microseconds
337 part of the first time and the microseconds part of the second
338 time; don't adjust the seconds part of the delta, as it's OK if
339 the microseconds part is negative. */
341 *diffsec = sec1 - sec2;
342 *diffusec = usec1 - usec2;
343 } else if (sec1 <= sec2) {
344 /* The seconds part of the first time is less than the seconds part
345 of the second time, so the first time is before the second time.
347 Both the "seconds" and "microseconds" value of the delta
348 should have the same sign, so if the difference between the
349 microseconds values would be *positive*, subtract 1,000,000
350 from it, and add one to the seconds value. */
351 *diffsec = sec1 - sec2;
352 if (usec2 >= usec1) {
353 *diffusec = usec1 - usec2;
355 *diffusec = (usec1 - 1000000) - usec2;
359 /* Oh, good, we're not caught in a chronosynclastic infindibulum. */
360 *diffsec = sec1 - sec2;
361 if (usec2 <= usec1) {
362 *diffusec = usec1 - usec2;
364 *diffusec = (usec1 + 1000000) - usec2;
370 /* Decode a base64 string in-place - simple and slow algorithm.
371 Return length of result. Taken from rproxy/librsync/base64.c by
374 size_t epan_base64_decode(char *s)
376 static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
377 int bit_offset, byte_offset, idx, i, n;
378 unsigned char *d = (unsigned char *)s;
383 while (*s && (p=strchr(b64, *s))) {
384 idx = (int)(p - b64);
385 byte_offset = (i*6)/8;
386 bit_offset = (i*6)%8;
387 d[byte_offset] &= ~((1<<(8-bit_offset))-1);
388 if (bit_offset < 3) {
389 d[byte_offset] |= (idx << (2-bit_offset));
392 d[byte_offset] |= (idx >> (bit_offset-2));
393 d[byte_offset+1] = 0;
394 d[byte_offset+1] |= (idx << (8-(bit_offset-2))) & 0xFF;
403 /* Try to figure out if we're remotely connected, e.g. via ssh or
404 Terminal Server, and create a capture filter that matches aspects of the
405 connection. We match the following environment variables:
407 SSH_CONNECTION (ssh): <remote IP> <remote port> <local IP> <local port>
408 SSH_CLIENT (ssh): <remote IP> <remote port> <local port>
409 REMOTEHOST (tcsh, others?): <remote name>
410 DISPLAY (x11): [remote name]:<display num>
411 CLIENTNAME (terminal server): <remote name>
414 gchar *get_conn_cfilter(void) {
415 static GString *filter_str = NULL;
416 gchar *env, **tokens;
418 if (filter_str == NULL) {
419 filter_str = g_string_new("");
421 if ((env = getenv("SSH_CONNECTION")) != NULL) {
422 tokens = g_strsplit(env, " ", 4);
424 g_string_sprintf(filter_str, "not (tcp port %s and %s host %s "
425 "and tcp port %s and %s host %s)", tokens[1], host_ip_af(tokens[0]), tokens[0],
426 tokens[3], host_ip_af(tokens[2]), tokens[2]);
427 return filter_str->str;
429 } else if ((env = getenv("SSH_CLIENT")) != NULL) {
430 tokens = g_strsplit(env, " ", 3);
431 g_string_sprintf(filter_str, "not (tcp port %s and %s host %s "
432 "and tcp port %s)", tokens[1], host_ip_af(tokens[0]), tokens[0], tokens[2]);
433 return filter_str->str;
434 } else if ((env = getenv("REMOTEHOST")) != NULL) {
435 if (strcasecmp(env, "localhost") == 0 || strcmp(env, "127.0.0.1") == 0) {
438 g_string_sprintf(filter_str, "not %s host %s", host_ip_af(env), env);
439 return filter_str->str;
440 } else if ((env = getenv("DISPLAY")) != NULL) {
441 tokens = g_strsplit(env, ":", 2);
442 if (tokens[0] && tokens[0][0] != 0) {
443 if (strcasecmp(tokens[0], "localhost") == 0 ||
444 strcmp(tokens[0], "127.0.0.1") == 0) {
447 g_string_sprintf(filter_str, "not %s host %s",
448 host_ip_af(tokens[0]), tokens[0]);
449 return filter_str->str;
451 } else if ((env = getenv("CLIENTNAME")) != NULL) {
452 if (g_strcasecmp("console", env) != 0) {
453 g_string_sprintf(filter_str, "not %s host %s", host_ip_af(env), env);
454 return filter_str->str;