Index: include/ec_conntrack.h
===================================================================
RCS file: /cvsroot/ettercap/ettercap_ng/include/ec_conntrack.h,v
retrieving revision 1.14
diff -u -p -u -p -r1.14 ec_conntrack.h
--- include/ec_conntrack.h	24 Jul 2004 10:43:21 -0000	1.14
+++ include/ec_conntrack.h	6 Aug 2005 01:48:34 -0000
@@ -41,6 +41,9 @@ struct conn_object {
    /* connection status */
    int status;
 
+   /* connection age in seconds */
+   time_t time_start, time_end;
+
    /* flags for injection/modifications */
    int flags;
 
Index: src/ec_conntrack.c
===================================================================
RCS file: /cvsroot/ettercap/ettercap_ng/src/ec_conntrack.c,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 ec_conntrack.c
--- src/ec_conntrack.c	23 Jul 2004 07:25:27 -0000	1.23
+++ src/ec_conntrack.c	6 Aug 2005 01:48:34 -0000
@@ -193,6 +193,12 @@ static void conntrack_update(struct conn
    
    if (po->L4.flags & TH_RST)
       co->status = CONN_KILLED;
+
+   /* mark the finalization time */
+   if (!co->time_end &&
+       (co->status == CONN_KILLED || co->status == CONN_CLOSED)) {
+      time(&co->time_end);
+   }
       
    /* update the buffer */
    connbuf_add(&co->data, po);
@@ -272,6 +278,9 @@ static void conntrack_add(struct packet_
    cl->co->L4_addr1 = po->L4.src;
    cl->co->L4_addr2 = po->L4.dst;
    cl->co->L4_proto = po->L4.proto;
+
+   /* record start time */
+   time(&cl->co->time_start);
  
    /* initialize the connection buffer */
    connbuf_init(&cl->co->data, GBL_CONF->connection_buffer);
@@ -672,9 +681,10 @@ void * conntrack_print(int mode, void *l
       if (c->co->DISSECTOR.user)
          flags = '*';
       
-      snprintf(*desc, len, "%c %15s:%-5d - %15s:%-5d %c %s TX: %lu", flags, 
+      snprintf(*desc, len, "%c %15s:%-5d - %15s:%-5d %c %s TX: %lu age: %u", flags, 
                                            src, ntohs(c->co->L4_addr1), dst, ntohs(c->co->L4_addr2),
-                                           proto, status, (unsigned long)c->co->xferred);
+                                           proto, status, (unsigned long)c->co->xferred,
+                                           c->co->time_end ? (c->co->time_end - c->co->time_start) : (time(NULL) - c->co->time_start));
    }
   
    /* return the next/prev/current to the caller */
Index: src/interfaces/curses/ec_curses_view_connections.c
===================================================================
RCS file: /cvsroot/ettercap/ettercap_ng/src/interfaces/curses/ec_curses_view_connections.c,v
retrieving revision 1.23
diff -u -p -u -p -r1.23 ec_curses_view_connections.c
--- src/interfaces/curses/ec_curses_view_connections.c	30 Sep 2004 16:01:45 -0000	1.23
+++ src/interfaces/curses/ec_curses_view_connections.c	6 Aug 2005 01:48:34 -0000
@@ -203,11 +203,12 @@ static void curses_connection_detail(voi
    wdg_window_print(wdg_conn_detail, 1, 11, "Destination port        :  %-5d  %s", ntohs(c->co->L4_addr2), service_search(c->co->L4_addr2, c->co->L4_proto));
    
    wdg_window_print(wdg_conn_detail, 1, 13, "Transferred bytes       :  %d", c->co->xferred);
+   wdg_window_print(wdg_conn_detail, 1, 14, "Connection age          :  %u", c->co->time_end ? (c->co->time_end - c->co->time_start) : (time(NULL) - c->co->time_start) );
    
    if (c->co->DISSECTOR.user) {
-      wdg_window_print(wdg_conn_detail, 1, 15, "Account                 :  %s / %s", c->co->DISSECTOR.user, c->co->DISSECTOR.pass);
+      wdg_window_print(wdg_conn_detail, 1, 16, "Account                 :  %s / %s", c->co->DISSECTOR.user, c->co->DISSECTOR.pass);
       if (c->co->DISSECTOR.info)
-         wdg_window_print(wdg_conn_detail, 1, 16, "Additional Info         :  %s", c->co->DISSECTOR.info);
+         wdg_window_print(wdg_conn_detail, 1, 17, "Additional Info         :  %s", c->co->DISSECTOR.info);
    }
 }
 
Index: src/interfaces/gtk/ec_gtk_view_connections.c
===================================================================
RCS file: /cvsroot/ettercap/ettercap_ng/src/interfaces/gtk/ec_gtk_view_connections.c,v
retrieving revision 1.42
diff -u -p -u -p -r1.42 ec_gtk_view_connections.c
--- src/interfaces/gtk/ec_gtk_view_connections.c	10 Oct 2004 13:49:51 -0000	1.42
+++ src/interfaces/gtk/ec_gtk_view_connections.c	6 Aug 2005 01:48:34 -0000
@@ -189,6 +189,11 @@ void gtkui_show_connections(void)
    gtk_tree_view_column_set_sort_column_id (column, 8);
    gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
 
+   renderer = gtk_cell_renderer_text_new ();
+   column = gtk_tree_view_column_new_with_attributes ("Age", renderer, "text", 10, NULL);
+   gtk_tree_view_column_set_sort_column_id (column, 10);
+   gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
+
    hbox = gtk_hbox_new(TRUE, 5);
    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
    gtk_widget_show(hbox);
@@ -277,7 +282,7 @@ static gboolean refresh_connections(gpoi
    char *desc;                  /* holds line from conntrack_print */
    GtkTreeIter iter;            /* points to a specific row */
    char flags[2], status[8];
-   unsigned int xferred = 0;
+   unsigned int xferred = 0, age = 0;
    struct row_pairs *row = NULL, *nextrow = NULL, top, bottom;
 
    /* null terminate strings */
@@ -289,13 +294,15 @@ static gboolean refresh_connections(gpoi
       if (!GTK_WIDGET_VISIBLE(conns_window))
          return(FALSE);
    } else {
-      /* Columns:   Flags, Host, Port, "-",   Host, Port,
-                    Proto, State, Bytes, (hidden) pointer */
-      ls_conns = gtk_list_store_new (10, 
+      /* Columns:   Flags, Host, Port,
+                    "-",   Host, Port,
+                    Proto, State, Bytes,
+                    (hidden) pointer, Age*/
+      ls_conns = gtk_list_store_new (11, 
                     G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, 
                     G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, 
                     G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT, 
-                    G_TYPE_POINTER);
+                    G_TYPE_POINTER, G_TYPE_UINT);
       connections = NULL;
    }
 
@@ -359,9 +366,9 @@ static gboolean refresh_connections(gpoi
       /* extract changing values from conntrack_print string */
       flags[0] = desc[0];
       strncpy(status, desc+50, 7);
-      sscanf(desc+62, "%u", &xferred);
+      sscanf(desc+62, "%u age: %u", &xferred, &age);
 
-      gtk_list_store_set (ls_conns, &iter, 0, flags, 7, status, 8, xferred, -1);
+      gtk_list_store_set (ls_conns, &iter, 0, flags, 7, status, 8, xferred, 10, age, -1);
 
       /* when we reach the bottom of the visible part, stop updating */
       if(bottom.conn == list)
@@ -375,7 +382,7 @@ static struct row_pairs *gtkui_connectio
    GtkTreeIter iter;
    char flags[2], src[16], dst[16];
    char proto[2], status[8], *src_ptr = NULL, *dst_ptr = NULL;
-   unsigned int src_port = 0, dst_port = 0, xferred = 0;
+   unsigned int src_port = 0, dst_port = 0, xferred = 0, age = 0;
    struct row_pairs *row = NULL;
 
    /* even if list is empty, we need a pointer to the NULL pointer */
@@ -400,7 +407,7 @@ static struct row_pairs *gtkui_connectio
 
    sscanf(desc+18, "%u", &src_port);
    sscanf(desc+42, "%u", &dst_port);
-   sscanf(desc+62, "%u", &xferred);
+   sscanf(desc+62, "%u age: %u", &xferred, &age);
 
    /* trim off leading spaces */
    for(src_ptr = src; *src_ptr == ' '; src_ptr++);
@@ -412,7 +419,7 @@ static struct row_pairs *gtkui_connectio
                        0, flags, 1, src_ptr, 2, src_port,
                        3, "-",   4, dst_ptr, 5, dst_port,
                        6, proto, 7, status,  8, xferred,
-                       9, conn, -1);
+                       9, conn, 10, age, -1);
 
    /* and add it to our linked list */
    if(!*list) {
@@ -551,6 +558,9 @@ static void gtkui_connection_detail(void
    snprintf(line, 200, "Transferred bytes: %d\n\n", c->co->xferred);
    gtkui_details_print(textbuf, line);
 
+   snprintf(line, 200, "Connection age: %d\n\n", c->co->time_end ? ( c->co->time_end - c->co->time_start) : ( time(NULL) - c->co->time_start ) );
+   gtkui_details_print(textbuf, line);
+
    /* Login Information */
    if (c->co->DISSECTOR.user) {
       snprintf(line, 200, "Account: \t%s / %s", c->co->DISSECTOR.user, c->co->DISSECTOR.pass);
