[Gd-chatter] r11016 - in trunk/libraries: gui-sniffer packetizer
hannes at gwydiondylan.org
hannes at gwydiondylan.org
Sat Dec 2 01:44:12 CET 2006
Author: hannes
Date: Sat Dec 2 01:44:08 2006
New Revision: 11016
Modified:
trunk/libraries/gui-sniffer/gui-sniffer.dylan
trunk/libraries/gui-sniffer/library.dylan
trunk/libraries/gui-sniffer/module.dylan
trunk/libraries/packetizer/filter-parser.dylan
Log:
Bug: 7299
*initial support for "Filter packet-source", "packet-destination" and "Follow Connection"
Modified: trunk/libraries/gui-sniffer/gui-sniffer.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/gui-sniffer.dylan (original)
+++ trunk/libraries/gui-sniffer/gui-sniffer.dylan Sat Dec 2 01:44:08 2006
@@ -238,7 +238,6 @@
filter-packet-table(frame);
end;
end;
-
define method filter-packet-table (frame :: <gui-sniffer-frame>)
let shown-packets
= if (frame.filter-expression)
@@ -530,7 +529,9 @@
end;
define command-table *popup-menu-command-table* (*global-command-table*)
- menu-item "Follow TCP Stream" = follow-tcp-stream;
+ menu-item "Filter packet-source" = filter-source;
+ menu-item "Filter packet-destination" = filter-destination;
+ menu-item "Follow connection" = follow-connection;
end;
define method display-popup-menu (sheet, object, #key x, y)
@@ -543,8 +544,128 @@
display-menu(menu);
end;
-define method follow-tcp-stream (frame :: <gui-sniffer-frame>)
- //
+define method filter-source (frame :: <gui-sniffer-frame>)
+ filter-by(source-address, frame);
+end;
+
+define method filter-destination (frame :: <gui-sniffer-frame>)
+ filter-by(destination-address, frame);
+end;
+
+define function filter-by (filter-method :: <function>, frame :: <gui-sniffer-frame>)
+ let current-packet = frame.packet-table.gadget-value;
+ if (current-packet) current-packet := real-frame(current-packet) end;
+ let layer = find-decent-layer(filter-method, current-packet);
+ let (field, frame-name) = find-protocol-field(frame-name(layer), filter-method.debug-name);
+ let filter = concatenate(frame-name, ".", filter-method.debug-name, " = ",
+ as(<string>, filter-method(layer)));
+ frame.filter-expression := make(<field-equals>,
+ frame: as(<symbol>, frame-name),
+ name: as(<symbol>, filter-method.debug-name),
+ value: filter-method(layer),
+ field: field);
+ filter-packet-table(frame);
+ gadget-value(frame.filter-field) := filter;
+end;
+
+define method find-decent-layer(filter-method :: <function>, frame :: <header-frame>)
+ find-decent-layer(filter-method, frame.payload) | next-method();
+end;
+
+define method find-decent-layer(filter-method :: <function>, frame :: type-union(<container-frame>, <raw-frame>))
+ if (filter-method(frame))
+ frame;
+ end;
+end;
+define method real-payload (f :: <header-frame>)
+ real-payload(f.payload)
+end;
+define method real-payload (f :: type-union(<container-frame>, <raw-frame>))
+ f;
+end;
+
+define method follow-connection (frame :: <gui-sniffer-frame>)
+ let current-packet = frame.packet-table.gadget-value;
+ if (current-packet) current-packet := real-frame(current-packet) end;
+ let filters = create-connection-filter(current-packet);
+ gadget-value(frame.filter-field) := filters;
+ apply-filter(frame);
+ let packets = map(real-frame, frame.packet-table.gadget-items);
+ let payloads = map(method(x) real-payload(x).data end, packets);
+ show-payloads(apply(concatenate, payloads), owner: frame);
+end;
+
+define method show-payloads
+ (text, #key title = "Following Connection", owner)
+ => ()
+ let stream = make(<string-stream>, direction: #"output");
+ let mytext = #f;
+ block()
+ for (byte in text)
+ if ((byte >= 32 & byte < 128) | (byte = #xa) | (byte = #xd)) // lame, I know
+ format(stream, "%s", as(<character>, byte))
+ else
+ format(stream, ".")
+ end;
+ end;
+ mytext := stream-contents(stream);
+ cleanup
+ close(stream)
+ end;
+ //format-out("Show patload %s\n", mytext);
+ let text-editor = make(<text-editor>,
+ read-only?: #t,
+ tab-stop?: #t,
+ lines: 60,
+ columns: 100,
+ scroll-bars: #"vertical",
+ text: mytext,
+ text-style: make(<text-style>, family: #"fix"));
+ let dialog = make(<dialog-frame>,
+ title: title,
+ owner: owner,
+ layout: text-editor);
+ start-dialog(dialog)
+end;
+
+define method create-connection-filter (frame :: <header-frame>)
+ create-connection-filter(frame.payload) | next-method();
+end;
+
+define function generate-filter (protocol, key1, value1, key2, value2)
+ concatenate("((", protocol, ".", key1, " = ", value1, ") & ",
+ "(", protocol, ".", key2, " = ", value2, ")) | ",
+ "((", protocol, ".", key2, " = ", value1, ") & ",
+ "(", protocol, ".", key1, " = ", value2, "))");
+end;
+define method create-connection-filter (frame :: <ethernet-frame>)
+ next-method() |
+ generate-filter(frame.frame-name,
+ "source-address", as(<string>, frame.source-address),
+ "destination-address", as(<string>, frame.destination-address));
+end;
+
+define method create-connection-filter (frame :: <ipv4-frame>)
+ let next-filter = create-connection-filter(frame.payload);
+ let ip-filter
+ = generate-filter(frame.frame-name,
+ "source-address", as(<string>, frame.source-address),
+ "destination-address", as(<string>, frame.destination-address));
+ if (next-filter)
+ concatenate("(", next-filter, ") & (", ip-filter, ")");
+ else
+ ip-filter;
+ end;
+end;
+
+define method create-connection-filter (frame :: type-union(<tcp-frame>, <udp-frame>))
+ generate-filter(frame.frame-name,
+ "source-port", integer-to-string(frame.source-port),
+ "destination-port", integer-to-string(frame.destination-port));
+end;
+
+define method create-connection-filter (frame)
+ #f;
end;
define method open-pcap-file (frame :: <gui-sniffer-frame>)
@@ -671,14 +792,14 @@
define constant $icons = make(<string-table>);
define function initialize-icons ()
- local method doit (name)
+ local method load-and-register-item (name)
$icons[as-lowercase(name)]
:= read-image-as(<win32-icon>, as(<byte-string>, name), #"icon", width: 16, height: 16);
end;
- doit("PLAY");
- doit("OPEN");
- doit("SAVE");
- doit("STOP");
+ load-and-register-item("PLAY");
+ load-and-register-item("OPEN");
+ load-and-register-item("SAVE");
+ load-and-register-item("STOP");
end;
begin
Modified: trunk/libraries/gui-sniffer/library.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/library.dylan (original)
+++ trunk/libraries/gui-sniffer/library.dylan Sat Dec 2 01:44:08 2006
@@ -3,6 +3,7 @@
Copyright: (C) 2005, 2006, All rights reserved. Free for non-commercial use.
define library gui-sniffer
+ use dylan;
use common-dylan;
use duim;
use win32-duim;
Modified: trunk/libraries/gui-sniffer/module.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/module.dylan (original)
+++ trunk/libraries/gui-sniffer/module.dylan Sat Dec 2 01:44:08 2006
@@ -15,6 +15,7 @@
define module gui-sniffer
use common-dylan, exclude: { format-to-string };
+ use dylan-extensions, import: { debug-name };
use threads;
use duim, exclude: { <frame>, frame-size };
use win32-duim;
@@ -35,6 +36,7 @@
use ethernet, import: { <ethernet-frame> };
use pcap, import: { make-unix-time, <pcap-packet>, decode-unix-time, timestamp };
use prism2, import: { <prism2-frame> };
+ use ipv4, import: { <ipv4-frame>, <tcp-frame>, <udp-frame>, source-port, destination-port };
// Add binding exports here.
use deuce-internals, prefix: "deuce/";
end module gui-sniffer;
Modified: trunk/libraries/packetizer/filter-parser.dylan
==============================================================================
--- trunk/libraries/packetizer/filter-parser.dylan (original)
+++ trunk/libraries/packetizer/filter-parser.dylan Sat Dec 2 01:44:08 2006
@@ -25,7 +25,7 @@
token RPAREN = "\\)";
token COLON = ":";
- token Name = "[a-zA-Z_0-9-]+",
+ token Name = "[a-zA-Z_0-9-<>]+",
semantic-value-function: extract-action;
end;
More information about the chatter
mailing list