Ethereal-dev: [Ethereal-dev] [patch] save & load hostname-cache
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Matthijs Melchior <mmelchior@xxxxxxxxx>
Date: Mon, 20 Oct 2003 23:56:33 +0200
Hi, To make it easy on myself when looking at traces from networks without names I have created the following feature. The "Edit>Preferences>Name Resolution" dialog is extended with 2 lines, one to show the file name and one to "Clear", "Load" or "Save" the hostname-cache in a file. This allows you to preload the hostname-cache with names of your choise and not having to remember the IP numbers. And collected IP numbers [with names, if any] can be written to a file for adding hostnames and reloading. There may be a need to connect this to some preferences, but that has not yet been done. Please apply. Thanks. -- Regards, ---------------------------------------------------------------- -o) Matthijs Melchior Maarssen /\\ mmelchior@xxxxxxxxx Netherlands _\_v ---------------------------------------------------------------- ----
diff -u epan/resolv.c-ORG epan/resolv.c
--- epan/resolv.c-ORG 2003-08-28 01:01:21.000000000 +0200
+++ epan/resolv.c 2003-10-18 23:14:59.000000000 +0200
@@ -1887,3 +1887,77 @@
return FALSE;
}
+
+/*
+ * Clear, Save and Load the contants of the hostname-cache.
+ * Useful for traces from dedicated networks without nameservers:
+ * clear the name cache, load the trace, save name cache,
+ * add names to that file, load that file into the cache again.
+ */
+
+void clear_host_cache()
+{
+ int i;
+ hashname_t *p, *q;
+
+ for(i=0; i<HASHHOSTSIZE; i++) {
+ p = host_table[i];
+ while(p) {
+ q = p;
+ p = p->next;
+ g_free(q);
+ }
+ host_table[i] = NULL;
+ }
+}
+
+int save_host_cache(char *file)
+{
+ FILE *hosts;
+ hashname_t *p;
+ int i;
+ char *n;
+
+ hosts = fopen(file, "w");
+ if (hosts == 0) {
+ return -1;
+ }
+ fprintf(hosts, "# hostname-cache for ethereal\n\n");
+ for(i=0; i<HASHHOSTSIZE; i++) {
+ p = host_table[i];
+ while(p) {
+ n = p->name;
+ if (p->is_dummy_entry)
+ n = "#"; /* create invalid entry ... */
+ fprintf(hosts, "%s\t%s\n", ip_to_str((guchar *)&(p->addr)), n);
+ p = p->next;
+ }
+ }
+ fclose(hosts);
+ return 0;
+}
+
+int load_host_cache(char *file)
+{
+ static char sep[] = " \t\r\n";
+ FILE *hosts;
+ int size = 0;
+ char *buf = NULL;
+ struct in_addr a;
+ char *cp;
+
+ hosts = fopen(file, "r");
+ if (hosts == 0) {
+ return -1;
+ }
+ while(fgetline(&buf, &size, hosts) >= 0) {
+ if ((cp = strchr(buf, '#')))
+ *cp = '\0';
+ if ((cp = strtok(buf, sep)))
+ if (inet_aton(cp, &a))
+ if ((cp = strtok(NULL, sep)))
+ add_host_name(a.s_addr, cp);
+ }
+
+ g_free(buf);
+}
diff -u gtk/nameres_prefs.c-ORG gtk/nameres_prefs.c
--- gtk/nameres_prefs.c-ORG 2003-07-22 05:14:31.000000000 +0200
+++ gtk/nameres_prefs.c 2003-10-20 22:49:45.000000000 +0200
@@ -45,17 +45,137 @@
# define C_RESOLVE_KEY "c_resolve"
# define RESOLVE_CONCURRENCY_KEY "resolve_concurrency"
#endif /* HAVE_GNU_ADNS */
+#define CACHE_FILE_KEY "cache_file_name"
+#define E_FS_CALLER_PTR_KEY "fs_caller_ptr"
+#define E_FILE_SEL_DIALOG_PTR_KEY "file_sel_dialog_ptr"
+#define CACHE_FILE_ACTION_FU "cache_file_action_fu"
#ifdef HAVE_GNU_ADNS
-# define RESOLV_TABLE_ROWS 5
+# define RESOLV_TABLE_ROWS 7
#else
-# define RESOLV_TABLE_ROWS 3
+# define RESOLV_TABLE_ROWS 5
#endif /* HAVE_GNU_ADNS */
+
+void dlg_set_cancel(GtkWidget *widget, GtkWidget *cancel_button);
+char* get_persconffile_path(const char *filename, gboolean for_writing);
+
+typedef int (*actionfu)(gchar *file); /* for function pointers as parameter */
+
+int load_host_cache(gchar *file);
+int save_host_cache(gchar *file);
+int clear_host_cache();
+
+/* This could be a preference */
+static gchar *hosts_cache_filename = 0;
+
+static void
+cache_fs_cancel_cb(GtkWidget *w _U_, gpointer data)
+{
+ gtk_widget_destroy(GTK_WIDGET(data));
+}
+
+static void
+cache_fs_ok_cb(GtkWidget *w, gpointer data)
+{
+ gchar * name = (gchar *)gtk_file_selection_get_filename(GTK_FILE_SELECTION(data));
+ actionfu action = OBJECT_GET_DATA(data, CACHE_FILE_ACTION_FU);
+
+ gtk_entry_set_text(GTK_ENTRY(OBJECT_GET_DATA(data, CACHE_FILE_KEY)), name);
+ cache_fs_cancel_cb(w, data);
+
+ action(name); /* do it */
+}
+
+static void
+cache_fs_destroy_cb(GtkWidget *win, gpointer data _U_)
+{
+ GtkWidget *caller;
+
+ /* Get the widget that requested that we be popped up.
+ (It should arrange to destroy us if it's destroyed, so
+ that we don't get a pointer to a non-existent window here.) */
+ caller = OBJECT_GET_DATA(win, E_FS_CALLER_PTR_KEY);
+
+ /* Tell it we no longer exist. */
+ OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, NULL);
+
+ /* Now nuke this window. */
+ gtk_grab_remove(GTK_WIDGET(win));
+ gtk_widget_destroy(GTK_WIDGET(win));
+}
+
+
+static void
+handle_hostname_cache(GtkWidget *w, gpointer data, actionfu action, gchar *title)
+{
+ GtkWidget *caller = gtk_widget_get_toplevel(w);
+ GtkWidget *fs;
+
+ /* Has a file selection dialog box already been opened for that top-level
+ widget? */
+ fs = OBJECT_GET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY);
+
+ if (fs != NULL) {
+ /* Yes. Just re-activate that dialog box. */
+ reactivate_window(fs);
+ return;
+ }
+
+ fs = gtk_file_selection_new (title);
+ OBJECT_SET_DATA(fs, CACHE_FILE_KEY, data);
+ OBJECT_SET_DATA(fs, CACHE_FILE_ACTION_FU, action);
+
+ /* Set the E_FS_CALLER_PTR_KEY for the new dialog to point to our caller. */
+ OBJECT_SET_DATA(fs, E_FS_CALLER_PTR_KEY, caller);
+
+ /* Set the E_FILE_SEL_DIALOG_PTR_KEY for the caller to point to us */
+ OBJECT_SET_DATA(caller, E_FILE_SEL_DIALOG_PTR_KEY, fs);
+
+ gtk_file_selection_set_filename(GTK_FILE_SELECTION(fs), gtk_entry_get_text(GTK_ENTRY(data)));
+
+ /* Call a handler when the file selection box is destroyed, so we can inform
+ our caller, if any, that it's been destroyed. */
+ SIGNAL_CONNECT(fs, "destroy", cache_fs_destroy_cb, NULL);
+
+ SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->ok_button, "clicked",
+ cache_fs_ok_cb, fs);
+
+ /* Connect the cancel_button to destroy the widget */
+ SIGNAL_CONNECT(GTK_FILE_SELECTION(fs)->cancel_button, "clicked",
+ cache_fs_cancel_cb, fs);
+
+ /* Catch the "key_press_event" signal in the window, so that we can catch
+ the ESC key being pressed and act as if the "Cancel" button had
+ been selected. */
+ dlg_set_cancel(fs, GTK_FILE_SELECTION(fs)->cancel_button);
+
+ gtk_widget_show(fs);
+}
+
+static void
+load_cache_cb(GtkWidget *w, gpointer data)
+{
+ handle_hostname_cache(w, data, load_host_cache, "Ethereal: Load hostname cache from File");
+}
+static void
+save_cache_cb(GtkWidget *w, gpointer data)
+{
+ handle_hostname_cache(w, data, save_host_cache, "Ethereal: Save hostname cache in File");
+}
+
+static void
+clear_cache_cb(GtkWidget *w _U_, gpointer data _U_)
+{
+ clear_host_cache();
+}
+
GtkWidget*
nameres_prefs_show(void)
{
GtkWidget *main_tb, *main_vb;
GtkWidget *m_resolv_cb, *n_resolv_cb, *t_resolv_cb;
+ GtkWidget *cache_hb, *clear_bt, *save_bt, *load_bt, *file_te;
+ GtkWidget *label, *event_box;
#ifdef HAVE_GNU_ADNS
GtkWidget *c_resolv_cb, *resolv_concurrency_te;
char concur_str[10+1];
@@ -115,6 +235,66 @@
#endif /* HAVE_GNU_ADNS */
+ label = gtk_label_new("Ethereal hostname-cache filename:");
+ gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
+ gtk_widget_show(label);
+
+ event_box = gtk_event_box_new();
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), event_box, 0, 1, 5, 6);
+ gtk_container_add(GTK_CONTAINER(event_box), label);
+ gtk_widget_show(event_box);
+
+ label = gtk_label_new("Ethereal hostname-cache operations:");
+ gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5);
+ gtk_widget_show(label);
+
+ event_box = gtk_event_box_new();
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), event_box, 0, 1, 6, 7);
+ gtk_container_add(GTK_CONTAINER(event_box), label);
+ gtk_widget_show(event_box);
+
+ file_te = gtk_entry_new();
+ OBJECT_SET_DATA(main_tb, CACHE_FILE_KEY, file_te);
+ if (hosts_cache_filename == 0) /* this could be a preference */
+ hosts_cache_filename = get_persconffile_path("hostname-cache", TRUE);
+ gtk_entry_set_text(GTK_ENTRY(file_te), hosts_cache_filename);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), file_te, 1, 2, 5, 6);
+ gtk_widget_show(file_te);
+
+ cache_hb = gtk_hbox_new(TRUE, 8);
+ gtk_table_attach_defaults(GTK_TABLE(main_tb), cache_hb, 1, 2, 6, 7);
+ gtk_widget_show(cache_hb);
+
+#if GTK_MAJOR_VERSION < 2
+ clear_bt = gtk_button_new_with_label("Clear");
+#else
+ clear_bt = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
+#endif
+ gtk_widget_set_sensitive(clear_bt, TRUE);
+ SIGNAL_CONNECT(clear_bt, "clicked", clear_cache_cb, NULL);
+ gtk_box_pack_start(GTK_BOX(cache_hb), clear_bt, TRUE, TRUE, 0);
+ gtk_widget_show(clear_bt);
+
+#if GTK_MAJOR_VERSION < 2
+ load_bt = gtk_button_new_with_label("Load");
+#else
+ load_bt = gtk_button_new_from_stock(GTK_STOCK_OPEN); /* don't have GTK_STOCK_LOAD ... ? */
+#endif
+ gtk_widget_set_sensitive(load_bt, TRUE);
+ SIGNAL_CONNECT(load_bt, "clicked", load_cache_cb, file_te);
+ gtk_box_pack_start(GTK_BOX(cache_hb), load_bt, TRUE, TRUE, 0);
+ gtk_widget_show(load_bt);
+
+#if GTK_MAJOR_VERSION < 2
+ save_bt = gtk_button_new_with_label("Save");
+#else
+ save_bt = gtk_button_new_from_stock(GTK_STOCK_SAVE);
+#endif
+ gtk_widget_set_sensitive(save_bt, TRUE);
+ SIGNAL_CONNECT(save_bt, "clicked", save_cache_cb, file_te);
+ gtk_box_pack_start(GTK_BOX(cache_hb), save_bt, TRUE, TRUE, 0);
+ gtk_widget_show(save_bt);
+
/* Show 'em what we got */
gtk_widget_show_all(main_vb);
- Follow-Ups:
- Re: [Ethereal-dev] [patch] save & load hostname-cache
- From: Ronnie Sahlberg
- Re: [Ethereal-dev] [patch] save & load hostname-cache
- From: Guy Harris
- Re: [Ethereal-dev] [patch] save & load hostname-cache
- Prev by Date: Re: [Ethereal-dev] Time for the next release?
- Next by Date: Re: [Ethereal-dev] Time for the next release?
- Previous by thread: Re: [Ethereal-dev] Discussion of A Common Representation of Protocols
- Next by thread: Re: [Ethereal-dev] [patch] save & load hostname-cache
- Index(es):





