/* Returns whether the node in question should be displayed in the * diagram or not */ static gboolean display_node (node_t * node) { double diffms; if (!node) return FALSE; diffms = substract_times_ms(&appdata.now, &node->node_stats.stats.last_time); /* There are problems if a canvas_node is deleted if it still * has packets, so we have to check that as well */ /* Remove canvas_node if node is too old */ if (diffms >= pref.gui_node_timeout_time && pref.gui_node_timeout_time && !node->node_stats.pkt_list.length) return FALSE; #if 1 if ((pref.gui_node_timeout_time == 1) && !node->node_stats.pkt_list.length) g_my_critical ("Impossible situation in display node"); #endif return TRUE; } /* display_node */
/* This function is called to discard packets from the list * of packets beloging to a node or a link, and to calculate * the average traffic for that node or link */ gboolean node_update(node_id_t * node_id, node_t *node, gpointer delete_list_ptr) { double diffms; g_assert(delete_list_ptr); if (traffic_stats_update(&node->node_stats, pref.averaging_time, pref.proto_node_timeout_time)) { /* packet(s) active, update the most used protocols for this link */ guint i = STACK_SIZE; while (i + 1) { if (node->main_prot[i]) g_free (node->main_prot[i]); node->main_prot[i] = protocol_stack_sort_most_used(&node->node_stats.stats_protos, i); i--; } node_name_update (node); } else { /* no packets remaining on node - if node expiration active, see if the * node is expired */ if (pref.node_timeout_time) { diffms = substract_times_ms(&appdata.now, &node->node_stats.stats.last_time); if (diffms >= pref.node_timeout_time) { /* node expired, remove */ GList **delete_list = (GList **)delete_list_ptr; if (DEBUG_ENABLED) { gchar *msg = node_id_dump(&node->node_id); g_my_debug(_("Queuing node '%s' for remove"), msg); g_free(msg); } /* First thing we do is delete the node from the list of new_nodes, * if it's there */ new_nodes_remove(node); /* adds current to list of nodes to be delete */ *delete_list = g_list_prepend( *delete_list, node_id); } } } return FALSE; }
static gint update_link(link_id_t* link_id, link_t * link, gpointer delete_list_ptr) { double diffms; g_assert(delete_list_ptr); /* update stats - returns true if there are active packets */ if (traffic_stats_update(&link->link_stats, pref.averaging_time, pref.proto_link_timeout_time)) { /* packet(s) active, update the most used protocols for this link */ guint i = STACK_SIZE; while (i + 1) { if (link->main_prot[i]) g_free (link->main_prot[i]); link->main_prot[i] = protocol_stack_sort_most_used(&link->link_stats.stats_protos, i); i--; } } else { /* no packets remaining on link - if link expiration active, see if the * link is expired */ if (pref.link_timeout_time) { diffms = substract_times_ms(&appdata.now, &link->link_stats.stats.last_time); if (diffms >= pref.link_timeout_time) { /* link expired, remove */ GList **delete_list = (GList **)delete_list_ptr; /* adds current to list of links to delete */ *delete_list = g_list_prepend( *delete_list, link_id); g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,_("Queuing link for remove")); } } } return FALSE; }
/* Refreshes the diagram. Called each refresh_period ms * 1. Checks for new protocols and displays them * 2. Updates nodes looks * 3. Updates links looks */ guint update_diagram(GtkWidget * canvas) { static struct timeval last_refresh_time = { 0, 0 }; double diffms; enum status_t status; /* if requested and enabled, dump to xml */ if (appdata.request_dump && appdata.export_file_signal) { g_warning (_("SIGUSR1 received: exporting to %s"), appdata.export_file_signal); dump_xml(appdata.export_file_signal); appdata.request_dump = FALSE; } status = get_capture_status(); if (status == PAUSE) return FALSE; if (status == CAP_EOF) { gui_eof_capture (); return FALSE; } /* * It could happen that during an intensive calculation, in order * to update the GUI and make the application responsive gtk_main_iteration * is called. But that could also trigger this very function's timeout. * If we let it run twice many problems could come up. Thus, * we are preventing it with the already_updating variable */ if (already_updating) { g_my_debug ("update_diagram called while already updating"); return FALSE; } already_updating = TRUE; gettimeofday (&appdata.now, NULL); /* update nodes */ diagram_update_nodes(canvas); /* update links */ diagram_update_links(canvas); /* Update protocol information */ protocol_summary_update_all(); /* update proto legend */ update_legend(); /* Now update info windows */ update_info_windows (); /* With this we make sure that we don't overload the * CPU with redraws */ if ((last_refresh_time.tv_sec == 0) && (last_refresh_time.tv_usec == 0)) last_refresh_time = appdata.now; /* Force redraw */ while (gtk_events_pending ()) gtk_main_iteration (); gettimeofday (&appdata.now, NULL); diffms = substract_times_ms(&appdata.now, &last_refresh_time); last_refresh_time = appdata.now; already_updating = FALSE; if (!is_idle) { if (diffms > pref.refresh_period * 1.2) return FALSE; /* Removes the timeout */ } else { if (diffms < pref.refresh_period) return FALSE; /* removes the idle */ } if (stop_requested) gui_stop_capture(); return TRUE; /* Keep on calling this function */ } /* update_diagram */
/* - calls update_links, so that the related link updates its average * traffic and main protocol, and old links are deleted * - caculates link size and color fading */ static gint canvas_link_update(link_id_t * link_id, canvas_link_t * canvas_link, GList **delete_list) { const link_t *link; const canvas_node_t *canvas_dst; const canvas_node_t *canvas_src; guint32 scaledColor; double xs, ys, xd, yd, scale; /* We used to run update_link here, but that was a major performance penalty, * and now it is done in update_diagram */ link = links_catalog_find(link_id); if (!link) { *delete_list = g_list_prepend( *delete_list, link_id); g_my_debug ("Queing canvas link to remove."); return FALSE; } /* If either source or destination has disappeared, we hide the link * until it can be show again */ /* We get coords for the destination node */ canvas_dst = g_tree_lookup (canvas_nodes, &link_id->dst); if (!canvas_dst || !canvas_dst->shown) { gnome_canvas_item_hide (canvas_link->src_item); gnome_canvas_item_hide (canvas_link->dst_item); return FALSE; } /* We get coords from source node */ canvas_src = g_tree_lookup (canvas_nodes, &link_id->src); if (!canvas_src || !canvas_src->shown) { gnome_canvas_item_hide (canvas_link->src_item); gnome_canvas_item_hide (canvas_link->dst_item); return FALSE; } /* What if there never is a protocol? * I have to initialize canvas_link->color to a known value */ if (link->main_prot[pref.stack_level]) { double diffms; canvas_link->color = protohash_color(link->main_prot[pref.stack_level]); /* scale color down to 10% at link timeout */ diffms = substract_times_ms(&appdata.now, &link->link_stats.stats.last_time); scale = pow(0.10, diffms / pref.gui_link_timeout_time); scaledColor = (((int) (scale * canvas_link->color.red) & 0xFF00) << 16) | (((int) (scale * canvas_link->color.green) & 0xFF00) << 8) | ((int) (scale * canvas_link->color.blue) & 0xFF00) | 0xFF; } else { guint32 black = 0x000000ff; scaledColor = black; } /* retrieve coordinates of node centers */ g_object_get (G_OBJECT (canvas_src->group_item), "x", &xs, "y", &ys, NULL); g_object_get (G_OBJECT (canvas_dst->group_item), "x", &xd, "y", &yd, NULL); /* first draw triangle for src->dst */ draw_oneside_link(xs, ys, xd, yd, &(link->link_stats.stats_out), scaledColor, canvas_link->src_item); /* then draw triangle for dst->src */ draw_oneside_link(xd, yd, xs, ys, &(link->link_stats.stats_in), scaledColor, canvas_link->dst_item); return FALSE; } /* update_canvas_links */