[Gd-chatter] r10847 - trunk/libraries/gui-sniffer

hannes at gwydiondylan.org hannes at gwydiondylan.org
Thu Aug 10 17:48:12 CEST 2006


Author: hannes
Date: Thu Aug 10 17:48:11 2006
New Revision: 10847

Modified:
   trunk/libraries/gui-sniffer/gui-sniffer.dylan
   trunk/libraries/gui-sniffer/library.dylan
   trunk/libraries/gui-sniffer/module.dylan
Log:
Bug: 7299
*integrate gui-sniffer into flow graph (<gui-sniffer-frame> is a <filter>)
*support for writing pcap files
*support for live capturing on interfaces
*refresh-packet-table is called on each received frame, which is bad for reading big pcap-files
 => maybe optional live updating like in ethereal?

Modified: trunk/libraries/gui-sniffer/gui-sniffer.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/gui-sniffer.dylan	(original)
+++ trunk/libraries/gui-sniffer/gui-sniffer.dylan	Thu Aug 10 17:48:11 2006
@@ -126,9 +126,10 @@
   *count* := *count* + 1;
   *count*;
 end;
-define frame <gui-sniffer-frame> (<simple-frame>)
+define frame <gui-sniffer-frame> (<simple-frame>, <filter>)
   slot network-frames = make(<stretchy-vector>);
   slot filter-expression = #f;
+  slot ethernet-interface = #f;
   pane filter-field (frame)
     make(<text-field>,
          label: "Filter expression",
@@ -165,22 +166,83 @@
 
 define command-table *file-command-table* (*global-command-table*)
   menu-item "Open pcap file" = open-pcap-file;
+  menu-item "Save to pcap file" = save-pcap-file;
+end;
+
+define command-table *interface-command-table* (*global-command-table*)
+  menu-item "Open ethernet interface" = open-interface;
+  menu-item "Stop capturing" = close-interface;
 end;
 
 define command-table *gui-sniffer-command-table* (*global-command-table*)
   menu-item "File" = *file-command-table*;
+  menu-item "Interface" = *interface-command-table*;
 end;
 
 define method open-pcap-file (frame :: <gui-sniffer-frame>)
   let file = choose-file(frame: frame, direction: #"input");
   if (file)
-    let packets = load-pcap-file(file);
-    if (packets)
-      frame.network-frames := packets;
-      refresh-packet-table(frame);
-    else
-      notify-user(format-to-string("Failed to open file %s", file), owner: frame)
-    end;
+    frame.network-frames := make(<stretchy-vector>);
+    let file-stream = make(<file-stream>, locator: file, direction: #"input");
+    let pcap-reader = make(<pcap-file-reader>, stream: file-stream);
+    connect(pcap-reader, frame);
+    toplevel(pcap-reader);
+    close(file-stream);
+    refresh-packet-table(frame);
+  end;
+end;
+
+define method save-pcap-file (frame :: <gui-sniffer-frame>)
+  let file = choose-file(frame: frame, direction: #"output");
+  if (file)
+    let file-stream = make(<file-stream>,
+                           locator: file,
+                           direction: #"output",
+                           if-exists: #"replace");
+    let pcap-writer = make(<pcap-file-writer>, stream: file-stream);
+    connect(frame, pcap-writer);
+    do(curry(push-data, frame.the-output), frame.network-frames);
+    //XXX: disconnect in flow graph, but disconnect is NYI
+    close(file-stream);
+  end;
+end;
+
+define method open-interface (frame :: <gui-sniffer-frame>)
+  let (interface, promiscious?) = prompt-for-interface(owner: frame);
+  if (interface)
+    let interface = make(<ethernet-interface>,
+                         name: interface,
+                         promiscious?: promiscious?);
+    connect(interface, frame);
+    frame.network-frames := make(<stretchy-vector>);
+    make(<thread>, function: curry(toplevel, interface));
+    frame.ethernet-interface := interface;
+  end;
+end;
+
+define method close-interface (frame :: <gui-sniffer-frame>)
+  frame.ethernet-interface.running? := #f;
+  //XXX: disconnect in flow graph, but disconnect is NYI
+end;
+
+define method prompt-for-interface
+  (#key title = "Please specify interface", owner)
+ => (interface-name :: false-or(<string>), promiscious? :: <boolean>)
+  let interface-text = make(<text-field>,
+                            label: "Interface:",
+                            activate-callback: exit-dialog);
+  let promiscious? = make(<check-box>, items: #("promiscious"), selection: #[0]);
+  let interface-selection-dialog
+    = make(<dialog-frame>,
+           title: title,
+           owner: owner,
+           layout: vertically()
+                     interface-text;
+                     promiscious?
+                   end,
+           input-focus: interface-text);
+  if (start-dialog(interface-selection-dialog))
+    values(gadget-value(interface-text), size(gadget-value(promiscious?)) > 0)
   end;
 end;
 
@@ -196,24 +258,19 @@
     update-gadget(frame.packet-table)
   else
     gadget-items(frame.packet-table) := shown-packets;
+    show-packet-tree(frame);
   end;
-  show-packet-tree(frame);
 end;
-define method load-pcap-file (file :: <string>) => (res :: false-or(<collection>))
-  let file-content
-    = as(<byte-vector>, 
-         with-open-file (stream = file,
-                         direction: #"input")
-           stream-contents(stream);
-         end);
-  let pcap-file = make(unparsed-class(<pcap-file>),
-                       packet: file-content);
-  //now check for real pcap-header... and return worst case #f
-  map(payload, packets(pcap-file));
+
+define method push-data-aux (input :: <push-input>,
+                             node :: <gui-sniffer-frame>,
+                             frame :: <frame>)
+  add!(node.network-frames, frame);
+  refresh-packet-table(node);
 end;
 begin
-  let gui-sniffer-frame = make(<gui-sniffer-frame>);
-  start-frame(gui-sniffer-frame); 
+  let gui-sniffer = make(<gui-sniffer-frame>);
+  start-frame(gui-sniffer);
 end;
 
 

Modified: trunk/libraries/gui-sniffer/library.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/library.dylan	(original)
+++ trunk/libraries/gui-sniffer/library.dylan	Thu Aug 10 17:48:11 2006
@@ -8,4 +8,7 @@
   use io;
   use system;
   use packetizer;
+  use flow;
+  use network-flow;
+  use interfaces;
 end library gui-sniffer;

Modified: trunk/libraries/gui-sniffer/module.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/module.dylan	(original)
+++ trunk/libraries/gui-sniffer/module.dylan	Thu Aug 10 17:48:11 2006
@@ -15,7 +15,9 @@
   use operating-system;
   use packetizer;
   use packet-filter;
-
+  use network-flow;
+  use flow;
+  use interfaces;
   // Add binding exports here.
 
 end module gui-sniffer;



More information about the chatter mailing list