Store pointers to previously displayed and captured packet, not nstime_t deltas.
[metze/wireshark/wip.git] / epan / column-utils.c
index 02dbe1343770c38e0acef9fa8beb3ef5c475a1c2..7737ec99dc13fc8900604768a994e62c409b57f8 100644 (file)
  *
  * 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.
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <string.h>
 #include <time.h>
@@ -626,11 +624,14 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local)
   struct tm *tmp;
   time_t then;
 
-  then = fd->abs_ts.secs;
-  if (local)
-     tmp = localtime(&then);
-  else
-     tmp = gmtime(&then);
+  if (fd->flags.has_ts) {
+    then = fd->abs_ts.secs;
+    if (local)
+       tmp = localtime(&then);
+    else
+       tmp = gmtime(&then);
+  } else
+    tmp = NULL;
   if (tmp != NULL) {
       switch(timestamp_get_precision()) {
       case TS_PREC_FIXED_SEC:
@@ -726,7 +727,7 @@ col_set_utc_date_time(const frame_data *fd, column_info *cinfo, const int col)
   cinfo->col_data[col] = cinfo->col_buf[col];
 }
 
-static gint
+static void
 set_time_seconds(const nstime_t *ts, gchar *buf)
 {
   switch(timestamp_get_precision()) {
@@ -763,10 +764,9 @@ set_time_seconds(const nstime_t *ts, gchar *buf)
       default:
           g_assert_not_reached();
   }
-  return 1;
 }
 
-static gint
+static void
 set_time_hour_min_sec(const nstime_t *ts, gchar *buf)
 {
   time_t secs = ts->secs;
@@ -915,25 +915,25 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf)
   default:
     g_assert_not_reached();
   }
-
-  return 1;
 }
 
 static void
 col_set_rel_time(const frame_data *fd, column_info *cinfo, const int col)
 {
+  if (!fd->flags.has_ts) {
+    cinfo->col_buf[col][0] = '\0';
+    return;
+  }
   switch (timestamp_get_seconds_type()) {
   case TS_SECONDS_DEFAULT:
-    if (set_time_seconds(&fd->rel_ts, cinfo->col_buf[col])) {
-      cinfo->col_expr.col_expr[col] = "frame.time_relative";
-      g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
-    }
+    set_time_seconds(&fd->rel_ts, cinfo->col_buf[col]);
+    cinfo->col_expr.col_expr[col] = "frame.time_relative";
+    g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
     break;
   case TS_SECONDS_HOUR_MIN_SEC:
-    if (set_time_hour_min_sec(&fd->rel_ts, cinfo->col_buf[col])) {
-      cinfo->col_expr.col_expr[col] = "frame.time_relative";
-      set_time_seconds(&fd->rel_ts, cinfo->col_expr.col_expr_val[col]);
-    }
+    set_time_hour_min_sec(&fd->rel_ts, cinfo->col_buf[col]);
+    cinfo->col_expr.col_expr[col] = "frame.time_relative";
+    set_time_seconds(&fd->rel_ts, cinfo->col_expr.col_expr_val[col]);
     break;
   default:
     g_assert_not_reached();
@@ -944,18 +944,20 @@ col_set_rel_time(const frame_data *fd, column_info *cinfo, const int col)
 static void
 col_set_delta_time(const frame_data *fd, column_info *cinfo, const int col)
 {
+  nstime_t del_cap_ts;
+
+  frame_delta_abs_time(fd, fd->prev_cap, &del_cap_ts);
+
   switch (timestamp_get_seconds_type()) {
   case TS_SECONDS_DEFAULT:
-    if (set_time_seconds(&fd->del_cap_ts, cinfo->col_buf[col])) {
-      cinfo->col_expr.col_expr[col] = "frame.time_delta";
-      g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
-    }
+    set_time_seconds(&del_cap_ts, cinfo->col_buf[col]);
+    cinfo->col_expr.col_expr[col] = "frame.time_delta";
+    g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
     break;
   case TS_SECONDS_HOUR_MIN_SEC:
-    if (set_time_hour_min_sec(&fd->del_cap_ts, cinfo->col_buf[col])) {
-      cinfo->col_expr.col_expr[col] = "frame.time_delta";
-      set_time_seconds(&fd->del_cap_ts, cinfo->col_expr.col_expr_val[col]);
-    }
+    set_time_hour_min_sec(&del_cap_ts, cinfo->col_buf[col]);
+    cinfo->col_expr.col_expr[col] = "frame.time_delta";
+    set_time_seconds(&del_cap_ts, cinfo->col_expr.col_expr_val[col]);
     break;
   default:
     g_assert_not_reached();
@@ -967,18 +969,25 @@ col_set_delta_time(const frame_data *fd, column_info *cinfo, const int col)
 static void
 col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col)
 {
+  nstime_t del_dis_ts;
+
+  if (!fd->flags.has_ts) {
+    cinfo->col_buf[col][0] = '\0';
+    return;
+  }
+
+  frame_delta_abs_time(fd, fd->prev_dis, &del_dis_ts);
+
   switch (timestamp_get_seconds_type()) {
   case TS_SECONDS_DEFAULT:
-    if (set_time_seconds(&fd->del_dis_ts, cinfo->col_buf[col])) {
-      cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
-      g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
-    }
+    set_time_seconds(&del_dis_ts, cinfo->col_buf[col]);
+    cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
+    g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN);
     break;
   case TS_SECONDS_HOUR_MIN_SEC:
-    if (set_time_hour_min_sec(&fd->del_dis_ts, cinfo->col_buf[col])) {
-      cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
-      set_time_seconds(&fd->del_dis_ts, cinfo->col_expr.col_expr_val[col]);
-    }
+    set_time_hour_min_sec(&del_dis_ts, cinfo->col_buf[col]);
+    cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed";
+    set_time_seconds(&del_dis_ts, cinfo->col_expr.col_expr_val[col]);
     break;
   default:
     g_assert_not_reached();
@@ -993,11 +1002,14 @@ set_abs_time(const frame_data *fd, gchar *buf, gboolean local)
   struct tm *tmp;
   time_t then;
 
-  then = fd->abs_ts.secs;
-  if (local)
-     tmp = localtime(&then);
-  else
-     tmp = gmtime(&then);
+  if (fd->flags.has_ts) {
+    then = fd->abs_ts.secs;
+    if (local)
+       tmp = localtime(&then);
+    else
+       tmp = gmtime(&then);
+  } else
+    tmp = NULL;
   if (tmp != NULL) {
       switch(timestamp_get_precision()) {
       case TS_PREC_FIXED_SEC:
@@ -1076,9 +1088,13 @@ col_set_utc_time(const frame_data *fd, column_info *cinfo, const int col)
   cinfo->col_data[col] = cinfo->col_buf[col];
 }
 
-static gint
+static gboolean
 set_epoch_time(const frame_data *fd, gchar *buf)
 {
+  if (!fd->flags.has_ts) {
+    buf[0] = '\0';
+    return FALSE;
+  }
   switch(timestamp_get_precision()) {
       case TS_PREC_FIXED_SEC:
       case TS_PREC_AUTO_SEC:
@@ -1113,7 +1129,7 @@ set_epoch_time(const frame_data *fd, gchar *buf)
       default:
           g_assert_not_reached();
   }
-  return 1;
+  return TRUE;
 }
 
 static void
@@ -1126,51 +1142,96 @@ col_set_epoch_time(const frame_data *fd, column_info *cinfo, const int col)
   cinfo->col_data[col] = cinfo->col_buf[col];
 }
 
-#if 0
-/* Set the format of the variable time format.
-   XXX - this is called from "file.c" when the user changes the time
-   format they want for "command-line-specified" time; it's a bit ugly
-   that we have to export it, but if we go to a CList-like widget that
-   invokes callbacks to get the text for the columns rather than
-   requiring us to stuff the text into the widget from outside, we
-   might be able to clean this up. */
 void
-set_cls_time(frame_data *fd, gchar *buf)
+set_fd_time(frame_data *fd, gchar *buf)
 {
-  COL_CHECK_REF_TIME(fd, cinfo->col_buf[col]);
 
   switch (timestamp_get_type()) {
     case TS_ABSOLUTE:
-      set_abs_time(fd, buf);
+      set_abs_time(fd, buf, TRUE);
       break;
 
     case TS_ABSOLUTE_WITH_DATE:
-      set_abs_date_time(fd, buf);
+      set_abs_date_time(fd, buf, TRUE);
       break;
 
     case TS_RELATIVE:
-      set_rel_time(fd, buf);
+      if (fd->flags.has_ts) {
+        switch (timestamp_get_seconds_type()) {
+        case TS_SECONDS_DEFAULT:
+          set_time_seconds(&fd->rel_ts, buf);
+          break;
+        case TS_SECONDS_HOUR_MIN_SEC:
+          set_time_seconds(&fd->rel_ts, buf);
+          break;
+        default:
+          g_assert_not_reached();
+        }
+      } else {
+        buf[0] = '\0';
+      }
       break;
 
     case TS_DELTA:
-      set_delta_time(fd, buf);
+      if (fd->flags.has_ts) {
+        nstime_t del_cap_ts;
+
+        frame_delta_abs_time(fd, fd->prev_cap, &del_cap_ts);
+
+        switch (timestamp_get_seconds_type()) {
+        case TS_SECONDS_DEFAULT:
+          set_time_seconds(&del_cap_ts, buf);
+          break;
+        case TS_SECONDS_HOUR_MIN_SEC:
+          set_time_hour_min_sec(&del_cap_ts, buf);
+          break;
+        default:
+          g_assert_not_reached();
+        }
+      } else {
+        buf[0] = '\0';
+      }
       break;
 
     case TS_DELTA_DIS:
-      set_delta_time_dis(fd, buf);
+      if (fd->flags.has_ts) {
+        nstime_t del_dis_ts;
+
+        frame_delta_abs_time(fd, fd->prev_dis, &del_dis_ts);
+
+        switch (timestamp_get_seconds_type()) {
+        case TS_SECONDS_DEFAULT:
+          set_time_seconds(&del_dis_ts, buf);
+          break;
+        case TS_SECONDS_HOUR_MIN_SEC:
+          set_time_hour_min_sec(&del_dis_ts, buf);
+          break;
+        default:
+          g_assert_not_reached();
+        }
+      } else {
+        buf[0] = '\0';
+      }
       break;
 
     case TS_EPOCH:
       set_epoch_time(fd, buf);
       break;
 
+    case TS_UTC:
+      set_abs_time(fd, buf, FALSE);
+      break;
+
+    case TS_UTC_WITH_DATE:
+      set_abs_date_time(fd, buf, FALSE);
+      break;
+
     case TS_NOT_SET:
-    /* code is missing for this case, but I don't know which [jmayer20051219] */
-    g_assert(FALSE);
-        break;
+      /* code is missing for this case, but I don't know which [jmayer20051219] */
+      g_assert(FALSE);
+      break;
   }
 }
-#endif
 
 static void
 col_set_cls_time(const frame_data *fd, column_info *cinfo, const gint col)
@@ -1215,14 +1276,8 @@ col_set_cls_time(const frame_data *fd, column_info *cinfo, const gint col)
   }
 }
 
-/* Set the format of the variable time format.
-   XXX - this is called from "file.c" when the user changes the time
-   format they want for "command-line-specified" time; it's a bit ugly
-   that we have to export it, but if we go to a CList-like widget that
-   invokes callbacks to get the text for the columns rather than
-   requiring us to stuff the text into the widget from outside, we
-   might be able to clean this up. */
-void
+/* Set the format of the variable time format. */
+static void
 col_set_fmt_time(const frame_data *fd, column_info *cinfo, const gint fmt, const gint col)
 {
   COL_CHECK_REF_TIME(fd, cinfo->col_buf[col]);
@@ -1252,11 +1307,11 @@ col_set_fmt_time(const frame_data *fd, column_info *cinfo, const gint fmt, const
       col_set_delta_time_dis(fd, cinfo, col);
       break;
 
-    case TS_UTC:
+    case COL_UTC_TIME:
       col_set_utc_time(fd, cinfo, col);
       break;
 
-    case TS_UTC_WITH_DATE:
+    case COL_UTC_DATE_TIME:
       col_set_utc_date_time(fd, cinfo, col);
       break;
 
@@ -1348,12 +1403,31 @@ col_set_addr(packet_info *pinfo, const int col, const address *addr, const gbool
 
   switch (addr->type) {
 
-  case AT_ETHER:
+  case AT_AX25:
     if (is_src)
-      pinfo->cinfo->col_expr.col_expr[col] = "eth.src";
+      pinfo->cinfo->col_expr.col_expr[col] = "ax25.src";
     else
-      pinfo->cinfo->col_expr.col_expr[col] = "eth.dst";
-    address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
+      pinfo->cinfo->col_expr.col_expr[col] = "ax25.dst";
+    g_strlcpy(pinfo->cinfo->col_expr.col_expr_val[col], ax25_to_str(addr->data), COL_MAX_LEN);
+    break;
+
+  case AT_ETHER:
+    switch(addr->subtype) {
+    default:
+      if (is_src)
+        pinfo->cinfo->col_expr.col_expr[col] = "eth.src";
+      else
+        pinfo->cinfo->col_expr.col_expr[col] = "eth.dst";
+      address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
+      break;
+    case AT_SUB_IEEE80211:
+      if (is_src)
+        pinfo->cinfo->col_expr.col_expr[col] = "wlan.sa";
+      else
+        pinfo->cinfo->col_expr.col_expr[col] = "wlan.da";
+      address_to_str_buf(addr, pinfo->cinfo->col_expr.col_expr_val[col], COL_MAX_LEN);
+      break;
+    }
     break;
 
   case AT_IPv4: