Store pointers to previously displayed and captured packet, not nstime_t deltas.
[metze/wireshark/wip.git] / rawshark.c
index 27d4d7639de98e4be8d06bc1650b4bcb3ce0bf6b..d6f319ab76519b1823b4550868cdd09e1eb8ac5b 100644 (file)
@@ -23,7 +23,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 /*
@@ -34,9 +34,7 @@
  * - Prints a status line, followed by fields from a specified list.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 # include <sys/stat.h>
 #endif
 
-#ifdef NEED_STRERROR_H
-#include "wsutil/strerror.h"
-#endif
-
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
+#ifndef HAVE_GETOPT
 #include "wsutil/wsgetopt.h"
 #endif
 
@@ -85,7 +77,7 @@
 #include <epan/column.h>
 #include "print.h"
 #include <epan/addr_resolv.h>
-#include "util.h"
+#include "ui/util.h"
 #include "clopts_common.h"
 #include "cmdarg_err.h"
 #include "version_info.h"
 #include "pcapio.h"
 #ifdef _WIN32
 #include "capture-wpcap.h"
-#include "capture_errs.h"
 #endif /* _WIN32 */
 #endif /* HAVE_LIBPCAP */
 #include "log.h"
 
 #ifdef _WIN32
-#include <shellapi.h>
+#include <wsutil/unicode-utils.h>
 #endif /* _WIN32 */
 
 /*
@@ -129,8 +120,10 @@ static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_
 
 static guint32 cum_bytes;
 static nstime_t first_ts;
-static nstime_t prev_dis_ts;
-static nstime_t prev_cap_ts;
+static frame_data *prev_dis;
+static frame_data prev_dis_frame;
+static frame_data *prev_cap;
+static frame_data prev_cap_frame;
 
 /*
  * The way the packet decode is to be written.
@@ -213,14 +206,16 @@ print_usage(gboolean print_ver)
     fprintf(output, "  -F <field>               field to display\n");
     fprintf(output, "  -n                       disable all name resolution (def: all enabled)\n");
     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
-    fprintf(output, "  -p                       use the system's packet header format (which may have 64-bit timestamps)\n");
+    fprintf(output, "  -p                       use the system's packet header format\n");
+    fprintf(output, "                           (which may have 64-bit timestamps)\n");
     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
     fprintf(output, "  -s                       skip PCAP header on input\n");
 
-    /*fprintf(output, "\n");*/
+    fprintf(output, "\n");
     fprintf(output, "Output:\n");
     fprintf(output, "  -l                       flush output after each packet\n");
-    fprintf(output, "  -S                       format string for fields (%%D - name, %%S - stringval, %%N numval)\n");
+    fprintf(output, "  -S                       format string for fields\n");
+    fprintf(output, "                           (%%D - name, %%S - stringval, %%N numval)\n");
     fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");
 
     fprintf(output, "\n");
@@ -247,9 +242,9 @@ static int
 raw_pipe_open(const char *pipe_name)
 {
 #ifndef _WIN32
-    struct stat pipe_stat;
+    ws_statb64 pipe_stat;
 #else
-    char *pncopy, *pos;
+    char *pncopy, *pos = NULL;
     DWORD err;
     wchar_t *err_str;
     HANDLE hPipe = NULL;
@@ -272,9 +267,9 @@ raw_pipe_open(const char *pipe_name)
 #endif  /* _WIN32 */
     } else {
 #ifndef _WIN32
-        if (ws_stat(pipe_name, &pipe_stat) < 0) {
+        if (ws_stat64(pipe_name, &pipe_stat) < 0) {
             fprintf(stderr, "rawshark: The pipe %s could not be checked: %s\n",
-                    pipe_name, strerror(errno));
+                    pipe_name, g_strerror(errno));
             return -1;
         }
         if (! S_ISFIFO(pipe_stat.st_mode)) {
@@ -293,7 +288,7 @@ raw_pipe_open(const char *pipe_name)
         rfd = ws_open(pipe_name, O_RDONLY | O_NONBLOCK, 0000 /* no creation so don't matter */);
         if (rfd == -1) {
             fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
-                    pipe_name, strerror(errno));
+                    pipe_name, g_strerror(errno));
             return -1;
         }
 #else /* _WIN32 */
@@ -326,7 +321,7 @@ raw_pipe_open(const char *pipe_name)
 
             err = GetLastError();
             if (err != ERROR_PIPE_BUSY) {
-                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
                               NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
                 fprintf(stderr, "rawshark: \"%s\" could not be opened: %s (error %d)\n",
                         pipe_name, utf_16to8(err_str), err);
@@ -336,7 +331,7 @@ raw_pipe_open(const char *pipe_name)
 
             if (!WaitNamedPipe(utf_8to16(pipe_name), 30 * 1000)) {
                 err = GetLastError();
-                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+                FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
                               NULL, err, 0, (LPTSTR) &err_str, 0, NULL);
                 fprintf(stderr, "rawshark: \"%s\" could not be waited for: %s (error %d)\n",
                         pipe_name, utf_16to8(err_str), err);
@@ -348,7 +343,7 @@ raw_pipe_open(const char *pipe_name)
         rfd = _open_osfhandle((long) hPipe, _O_RDONLY);
         if (rfd == -1) {
             fprintf(stderr, "rawshark: \"%s\" could not be opened: %s\n",
-                    pipe_name, strerror(errno));
+                    pipe_name, g_strerror(errno));
             return -1;
         }
 #endif /* _WIN32 */
@@ -435,8 +430,6 @@ main(int argc, char *argv[])
 
 #ifdef _WIN32
     WSADATA              wsaData;
-    LPWSTR              *wc_argv;
-    int                  wc_argc;
 #endif  /* _WIN32 */
 
     char                *gpf_path, *pf_path;
@@ -460,13 +453,7 @@ main(int argc, char *argv[])
     static const char    optstring[] = OPTSTRING_INIT;
 
 #ifdef _WIN32
-    /* Convert our arg list to UTF-8. */
-    wc_argv = CommandLineToArgvW(GetCommandLineW(), &wc_argc);
-    if (wc_argv && wc_argc == argc) {
-        for (i = 0; i < argc; i++) {
-            argv[i] = g_utf16_to_utf8(wc_argv[i], -1, NULL, NULL, NULL);
-        }
-    } /* XXX else bail because something is horribly, horribly wrong? */
+    arg_list_utf_16to8(argc, argv);
 #endif /* _WIN32 */
 
     /*
@@ -527,10 +514,6 @@ main(int argc, char *argv[])
               failure_message, open_failure_message, read_failure_message,
               write_failure_message);
 
-    /* Now register the preferences for any non-dissector modules.
-       We must do that before we read the preferences as well. */
-    prefs_register_modules();
-
     /* Set the C-language locale to the native environment. */
     setlocale(LC_ALL, "");
 
@@ -539,40 +522,37 @@ main(int argc, char *argv[])
     if (gpf_path != NULL) {
         if (gpf_open_errno != 0) {
             cmdarg_err("Can't open global preferences file \"%s\": %s.",
-                       pf_path, strerror(gpf_open_errno));
+                       pf_path, g_strerror(gpf_open_errno));
         }
         if (gpf_read_errno != 0) {
             cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
-                       pf_path, strerror(gpf_read_errno));
+                       pf_path, g_strerror(gpf_read_errno));
         }
     }
     if (pf_path != NULL) {
         if (pf_open_errno != 0) {
             cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
-                       strerror(pf_open_errno));
+                       g_strerror(pf_open_errno));
         }
         if (pf_read_errno != 0) {
             cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
-                       pf_path, strerror(pf_read_errno));
+                       pf_path, g_strerror(pf_read_errno));
         }
         g_free(pf_path);
         pf_path = NULL;
     }
 
-    /* Set the name resolution code's flags from the preferences. */
-    gbl_resolv_flags = prefs_p->name_resolve;
-
     /* Read the disabled protocols file. */
     read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
                               &dp_path, &dp_open_errno, &dp_read_errno);
     if (gdp_path != NULL) {
         if (gdp_open_errno != 0) {
             cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
-                       gdp_path, strerror(gdp_open_errno));
+                       gdp_path, g_strerror(gdp_open_errno));
         }
         if (gdp_read_errno != 0) {
             cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
-                       gdp_path, strerror(gdp_read_errno));
+                       gdp_path, g_strerror(gdp_read_errno));
         }
         g_free(gdp_path);
     }
@@ -580,12 +560,12 @@ main(int argc, char *argv[])
         if (dp_open_errno != 0) {
             cmdarg_err(
                 "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
-                strerror(dp_open_errno));
+                g_strerror(dp_open_errno));
         }
         if (dp_read_errno != 0) {
             cmdarg_err(
                 "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
-                strerror(dp_read_errno));
+                g_strerror(dp_read_errno));
         }
         g_free(dp_path);
     }
@@ -636,11 +616,12 @@ main(int argc, char *argv[])
                 line_buffered = TRUE;
                 break;
             case 'n':        /* No name resolution */
-                gbl_resolv_flags = RESOLV_NONE;
+                gbl_resolv_flags.mac_name = FALSE;
+                gbl_resolv_flags.network_name = FALSE;
+                gbl_resolv_flags.transport_name = FALSE;
+                gbl_resolv_flags.concurrent_dns = FALSE;
                 break;
             case 'N':        /* Select what types of addresses/port #s to resolve */
-                if (gbl_resolv_flags == RESOLV_ALL)
-                    gbl_resolv_flags = RESOLV_NONE;
                 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
                 if (badopt != '\0') {
                     cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'm', 'n', and 't'",
@@ -703,6 +684,10 @@ main(int argc, char *argv[])
                     timestamp_set_type(TS_DELTA_DIS);
                 else if (strcmp(optarg, "e") == 0)
                     timestamp_set_type(TS_EPOCH);
+                else if (strcmp(optarg, "u") == 0)
+                    timestamp_set_type(TS_UTC);
+                else if (strcmp(optarg, "ud") == 0)
+                    timestamp_set_type(TS_UTC_WITH_DATE);
                 else {
                     cmdarg_err("Invalid time stamp type \"%s\"",
                                optarg);
@@ -947,7 +932,7 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, const gchar **err
     printf("len: %d (%04x)\n", hdr.len, hdr.len);
 #endif
     if (bytes_needed > WTAP_MAX_PACKET_SIZE) {
-        *err = WTAP_ERR_BAD_RECORD;
+        *err = WTAP_ERR_BAD_FILE;
         g_snprintf(err_str, 100, "Bad packet length: %d (%04x)", bytes_needed, bytes_needed);
         *err_info = err_str;
         return FALSE;
@@ -990,27 +975,32 @@ load_cap_file(capture_file *cf)
         switch (err) {
 
             case WTAP_ERR_UNSUPPORTED_ENCAP:
-                cmdarg_err("\"%s\" has a packet with a network type that Rawshark doesn't support.\n(%s)",
+                cmdarg_err("The file \"%s\" has a packet with a network type that Rawshark doesn't support.\n(%s)",
                            cf->filename, err_info);
                 break;
 
             case WTAP_ERR_CANT_READ:
-                cmdarg_err("An attempt to read from \"%s\" failed for some unknown reason.",
+                cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
                            cf->filename);
                 break;
 
             case WTAP_ERR_SHORT_READ:
-                cmdarg_err("\"%s\" appears to have been cut short in the middle of a packet.",
+                cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
                            cf->filename);
                 break;
 
-            case WTAP_ERR_BAD_RECORD:
-                cmdarg_err("\"%s\" appears to be damaged or corrupt.\n(%s)",
+            case WTAP_ERR_BAD_FILE:
+                cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
+                           cf->filename, err_info);
+                break;
+
+            case WTAP_ERR_DECOMPRESS:
+                cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n(%s)",
                            cf->filename, err_info);
                 break;
 
             default:
-                cmdarg_err("An error occurred while reading \"%s\": %s.",
+                cmdarg_err("An error occurred while reading the file \"%s\": %s.",
                            cf->filename, wtap_strerror(err));
                 break;
         }
@@ -1075,7 +1065,7 @@ process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
     printf("%lu", (unsigned long int) cf->count);
 
     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
-                                  &first_ts, &prev_dis_ts, &prev_cap_ts);
+                                  &first_ts, prev_dis, prev_cap);
 
     /* We only need the columns if we're printing packet info but we're
      *not* verbose; in verbose mode, we print the protocol tree, not
@@ -1084,7 +1074,12 @@ process_packet(capture_file *cf, gint64 offset, const struct wtap_pkthdr *whdr,
 
     tap_push_tapped_queue(&edt);
 
-    frame_data_set_after_dissect(&fdata, &cum_bytes, &prev_dis_ts);
+    frame_data_set_after_dissect(&fdata, &cum_bytes);
+    prev_dis_frame = fdata;
+    prev_dis = &prev_dis_frame;
+
+    prev_cap_frame = fdata;
+    prev_cap = &prev_cap_frame;
 
     for(i = 0; i < n_rfilters; i++) {
         /* Run the read filter if we have one. */
@@ -1333,6 +1328,8 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
                                 svalue = fvalue_get_sinteger(&finfo->value);
                                 if (hfinfo->display & BASE_RANGE_STRING) {
                                     g_string_append(label_s, rval_to_str(svalue, RVALS(hfinfo->strings), "Unknown"));
+                                } else if (hfinfo->display & BASE_EXT_STRING) {
+                                    g_string_append(label_s, val_to_str_ext(svalue, (const value_string_ext *) hfinfo->strings, "Unknown"));
                                 } else {
                                     g_string_append(label_s, val_to_str(svalue, cVALS(hfinfo->strings), "Unknown"));
                                 }
@@ -1344,6 +1341,8 @@ static gboolean print_field_value(field_info *finfo, int cmd_line_index)
                                 uvalue = fvalue_get_uinteger(&finfo->value);
                                 if (!hfinfo->bitmask && hfinfo->display & BASE_RANGE_STRING) {
                                     g_string_append(label_s, rval_to_str(uvalue, RVALS(hfinfo->strings), "Unknown"));
+                                } else if (hfinfo->display & BASE_EXT_STRING) {
+                                    g_string_append(label_s, val_to_str_ext(uvalue, (const value_string_ext *) hfinfo->strings, "Unknown"));
                                 } else {
                                     g_string_append(label_s, val_to_str(uvalue, cVALS(hfinfo->strings), "Unknown"));
                                 }
@@ -1425,7 +1424,6 @@ protocolinfo_init(char *field)
                    ftenum_to_string(hfi),
                    absolute_time_display_e_to_string(hfi->display));
             break;
-            break;
 
         default:
             printf("%u %s %s - ",
@@ -1545,7 +1543,7 @@ show_print_file_io_error(int err)
 
         default:
             cmdarg_err("An error occurred while printing packets: %s.",
-                       strerror(err));
+                       g_strerror(err));
             break;
     }
 }
@@ -1585,8 +1583,8 @@ raw_cf_open(capture_file *cf, const char *fname)
     /* Indicate whether it's a permanent or temporary file. */
     cf->is_tempfile = FALSE;
 
-    /* If it's a temporary capture buffer file, mark it as not saved. */
-    cf->user_saved = FALSE;
+    /* No user changes yet. */
+    cf->unsaved_changes = FALSE;
 
     cf->cd_t      = WTAP_FILE_UNKNOWN;
     cf->count     = 0;
@@ -1596,8 +1594,8 @@ raw_cf_open(capture_file *cf, const char *fname)
     cf->snap = WTAP_MAX_PACKET_SIZE;
     nstime_set_zero(&cf->elapsed_time);
     nstime_set_unset(&first_ts);
-    nstime_set_unset(&prev_dis_ts);
-    nstime_set_unset(&prev_cap_ts);
+    prev_dis = NULL;
+    prev_cap = NULL;
 
     return CF_OK;
 }
@@ -1621,7 +1619,7 @@ static void
 read_failure_message(const char *filename, int err)
 {
     cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
-               filename, strerror(err));
+               filename, g_strerror(err));
 }
 
 /*
@@ -1631,7 +1629,7 @@ static void
 write_failure_message(const char *filename, int err)
 {
     cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
-               filename, strerror(err));
+               filename, g_strerror(err));
 }
 
 /*
@@ -1673,6 +1671,6 @@ cmdarg_err_cont(const char *fmt, ...)
  * indent-tabs-mode: nil
  * End:
  *
- * ex: set shiftwidth=4 tabstop=8 expandtab
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
  * :indentSize=4:tabSize=8:noTabs=true:
  */