[Gd-chatter] r10863 - in trunk/libraries: gui-sniffer packetizer
hannes at gwydiondylan.org
hannes at gwydiondylan.org
Wed Aug 23 17:56:33 CEST 2006
Author: hannes
Date: Wed Aug 23 17:56:30 2006
New Revision: 10863
Modified:
trunk/libraries/gui-sniffer/gui-sniffer.dylan
trunk/libraries/packetizer/module.dylan
trunk/libraries/packetizer/packetizer.dylan
trunk/libraries/packetizer/protocol-definer-macro.dylan
Log:
Bug: 7299
*implement <rep-frame-field> (for frames in a <repeated-field>), containing a link to the frame and to the parent frame-field
*use a <vector> instead of a <table> for concrete-frame-fields in a <container-frame> (performance, each field has a field-index)
*implement highlighting for frames in hex-dump-pane ([ and ])
Modified: trunk/libraries/gui-sniffer/gui-sniffer.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/gui-sniffer.dylan (original)
+++ trunk/libraries/gui-sniffer/gui-sniffer.dylan Wed Aug 23 17:56:30 2006
@@ -22,6 +22,14 @@
frame-children-predicate(frame-field.value);
end;
+define method frame-children-predicate (frame-field :: <repeated-frame-field>)
+ frame-field.frame-field-list.size > 0
+end;
+
+define method frame-children-predicate (ff :: <rep-frame-field>)
+ frame-children-predicate(ff.frame)
+end;
+
define method frame-children-generator (collection :: <collection>)
collection
end;
@@ -39,6 +47,14 @@
frame-children-generator(frame-field.value);
end;
+define method frame-children-generator (frame-field :: <repeated-frame-field>)
+ frame-field.frame-field-list
+end;
+
+define method frame-children-generator (ff :: <rep-frame-field>)
+ frame-children-generator(ff.frame)
+end;
+
define method frame-root-generator (frame :: <ethernet-frame>)
add!(next-method(), frame);
end;
@@ -58,6 +74,9 @@
end;
end;
+define method frame-print-label (mframe :: <rep-frame-field>)
+ frame-print-label(mframe.frame);
+end;
define method frame-print-label (frame :: <collection>)
format-to-string("(%d elements)", frame.size)
end;
@@ -215,47 +234,62 @@
define method show-packet-hex-dump (frame :: <gui-sniffer-frame>, network-packet)
//XXX: this should be easier!
- frame.packet-hex-dump.gadget-value
- := if (network-packet)
- let out = make(<string-stream>, direction: #"output");
- block()
- hexdump(out, network-packet.packet); //XXX: once assemble-frame
- //on unparsed-container-frame works,
- //we can use assemble-frame here
- stream-contents(out);
- cleanup
- close(out)
- end
- else
- ""
- end;
+ frame.packet-hex-dump.gadget-value := get-hex-dump(network-packet);
end;
+define function get-hex-dump (network-packet) => (string :: <string>)
+ if (network-packet)
+ let out = make(<string-stream>, direction: #"output");
+ block()
+ hexdump(out, network-packet.packet); //XXX: once assemble-frame
+ //on unparsed-container-frame works,
+ //we can use assemble-frame here
+ stream-contents(out);
+ cleanup
+ close(out)
+ end
+ else
+ ""
+ end;
+end;
define method compute-absolute-offset (frame :: <ethernet-frame>)
=> (res :: <integer>)
0
end;
+define method find-frame-field (frame :: <container-frame>, search :: <container-frame>)
+ => (res :: false-or(<frame-field>))
+ block(ret)
+ for (ff in sorted-frame-fields(frame))
+ if (ff.value == search)
+ ret(ff)
+ end;
+ if (instance?(ff.value, <collection>))
+ for (ele in ff.value)
+ if (ele == search)
+ ret(ff)
+ end;
+ end;
+ end;
+ end;
+ #f;
+ end;
+end;
+
define method compute-absolute-offset (frame :: <container-frame>)
- => (res :: <integer>)
- format-out("START <container-frame> %s ", frame.frame-name);
if (frame.parent)
- format-out("%d\n", sorted-frame-fields(frame.parent).last.start-offset);
- compute-absolute-offset(frame.parent) +
- if (instance?(frame.parent, <header-frame>))
- sorted-frame-fields(frame.parent).last.start-offset;
- else
- 0
- end;
+ let ff = find-frame-field(frame.parent, frame);
+ compute-absolute-offset(frame.parent) + ff.start-offset;
else
- format-out("0\n");
0
end;
end;
-
+define method compute-absolute-offset (ff :: <rep-frame-field>)
+ => (res :: <integer>)
+ start-offset(ff) + compute-absolute-offset(ff.parent-frame-field);
+end;
define method compute-absolute-offset (frame-field :: <frame-field>)
=> (res :: <integer>)
- format-out("START <frame-field> %s %d\n", frame-field.field.field-name, start-offset(frame-field));
start-offset(frame-field) + compute-absolute-offset(frame-field.frame)
end;
@@ -267,6 +301,10 @@
frame-size(frame)
end;
+define method compute-length (frame-field :: <rep-frame-field>) => (res :: <integer>)
+ frame-field.length
+end;
+
define method compute-length (frame-field :: <frame-field>) => (res :: <integer>)
if (frame-field.field.field-name = #"payload")
compute-length(frame-field.value)
@@ -275,19 +313,64 @@
end
end;
+define method find-frame-at-offset (frame :: <container-frame>, offset :: <integer>)
+ => (result-frame)
+ block(ret)
+ for (ff in sorted-frame-fields(frame))
+ if ((start-offset(ff) <= offset) & (end-offset(ff) >= offset))
+ format-out("looking in %s, offset %d\n", ff.field.field-name, offset - start-offset(ff));
+ ret(find-frame-at-offset(ff.value, offset - start-offset(ff)));
+ end;
+ end;
+ end;
+end;
+
+define method find-frame-at-offset (frame :: <collection>, offset :: <integer>)
+ let start = 0;
+ block(ret)
+ for (ele in frame, i from 0)
+ if ((start <= offset) & (frame-size(ele) >= offset))
+ format-out("looking in %d, offset %d\n", i, offset - start);
+ ret(find-frame-at-offset(ele, offset - start));
+ end;
+ start := start + frame-size(ele);
+ end;
+ end;
+end;
+
+define method find-frame-at-offset (frame :: <leaf-frame>, offset :: <integer>)
+ frame;
+end;
+
define method highlight-hex-dump (mframe :: <gui-sniffer-frame>)
let packet = mframe.packet-table.gadget-value;
let tree = mframe.packet-tree-view;
let selected-packet = tree.gadget-items[tree.gadget-selection[0]];
-
- let off = compute-absolute-offset(selected-packet);
- let start-highlight = off;
- let end-highlight = off + compute-length(selected-packet);
+ let start-highlight = compute-absolute-offset(selected-packet);
+ let end-highlight = start-highlight + compute-length(selected-packet);
+
+ let (start-line, start-rest) = floor/(byte-offset(start-highlight), 16);
+ let (end-line, end-rest) = floor/(byte-offset(end-highlight + 7), 16);
- format-out("start %d end %d\n",
- start-highlight,
- end-highlight);
+ if (end-rest = 0)
+ end-rest := 16;
+ end-line := end-line - 1
+ end;
+
+ let hex-dump = split(get-hex-dump(packet.real-frame), '\n');
+
+ let start-pos = 6 + start-rest * 3 + if (start-rest >= 8) 1 else 0 end;
+ let end-pos = 6 + end-rest * 3 + if (end-rest > 8) 1 else 0 end;
+
+ hex-dump[start-line + 1][start-pos - 1] := '[';
+ if (end-pos >= hex-dump[end-line + 1].size)
+ hex-dump[end-line + 1] := add!(hex-dump[end-line + 1], ']');
+ else
+ hex-dump[end-line + 1][end-pos - 1] := ']';
+ end;
+ hex-dump := reduce1(method(a,b) concatenate(a, "\n", b) end, hex-dump);
+ mframe.packet-hex-dump.gadget-value := hex-dump;
end;
define variable *count* :: <integer> = 0;
@@ -332,7 +415,8 @@
make(<tree-control>,
label-key: frame-print-label,
children-generator: frame-children-generator,
- children-predicate: frame-children-predicate);
+ children-predicate: frame-children-predicate,
+ value-changed-callback: method(x) highlight-hex-dump(frame) end);
pane packet-hex-dump (frame)
make(<text-editor>,
Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan (original)
+++ trunk/libraries/packetizer/module.dylan Wed Aug 23 17:56:30 2006
@@ -52,6 +52,8 @@
export <frame-field>,
<repeated-frame-field>,
+ <rep-frame-field>,
+ parent-frame-field,
frame-field-list,
start-offset,
length,
Modified: trunk/libraries/packetizer/packetizer.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer.dylan (original)
+++ trunk/libraries/packetizer/packetizer.dylan Wed Aug 23 17:56:30 2006
@@ -283,8 +283,13 @@
define open abstract class <container-frame> (<variable-size-untranslated-frame>)
virtual constant slot frame-name :: <string>;
slot parent :: false-or(<container-frame>) = #f, init-keyword: parent:;
- constant slot concrete-frame-fields :: <table> = make(<table>),
- init-keyword: frame-fields:;
+ slot concrete-frame-fields :: <vector>;
+end;
+
+define method initialize (frame :: <container-frame>,
+ #rest rest, #key, #all-keys)
+ next-method();
+ frame.concrete-frame-fields := make(<vector>, size: field-count(frame.object-class), fill: #f);
end;
define open generic frame-name (frame :: <container-frame>) => (res :: <string>);
@@ -332,7 +337,7 @@
define method get-frame-field (field-index :: <integer>, frame :: <container-frame>)
=> (res :: <frame-field>)
- let res = element(frame.concrete-frame-fields, field-index, default: #f);
+ let res = frame.concrete-frame-fields[field-index];
if (res)
res;
else
@@ -540,14 +545,33 @@
define generic assemble-field (frame :: <frame>, field :: <field>)
=> (packet :: <vector>);
-define class <frame-field> (<object>)
- constant slot field :: <field>, init-keyword: field:;
- constant slot frame :: <container-frame>, init-keyword: frame:;
+
+define class <position-mixin> (<object>)
slot %start-offset :: false-or(<integer>) = #f, init-keyword: start:;
slot %end-offset :: false-or(<integer>) = #f, init-keyword: end:;
slot %length :: false-or(<integer>) = #f, init-keyword: length:;
end;
+define class <rep-frame-field> (<position-mixin>)
+ constant slot parent-frame-field :: <frame-field>, required-init-keyword: parent:;
+ constant slot frame :: <frame>, required-init-keyword: frame:;
+end;
+
+define method start-offset (ff :: <position-mixin>)
+ ff.%start-offset;
+end;
+define method end-offset (ff :: <position-mixin>)
+ ff.%end-offset;
+end;
+define method length (ff :: <position-mixin>)
+ ff.%length;
+end;
+
+define class <frame-field> (<position-mixin>)
+ constant slot field :: <field>, init-keyword: field:;
+ constant slot frame :: <container-frame>, init-keyword: frame:;
+end;
+
define class <repeated-frame-field> (<frame-field>)
slot frame-field-list :: <stretchy-vector> = make(<stretchy-vector>);
end;
Modified: trunk/libraries/packetizer/protocol-definer-macro.dylan
==============================================================================
--- trunk/libraries/packetizer/protocol-definer-macro.dylan (original)
+++ trunk/libraries/packetizer/protocol-definer-macro.dylan Wed Aug 23 17:56:30 2006
@@ -291,7 +291,8 @@
start :: <integer>,
packet :: <byte-sequence>)
let frames = make(<stretchy-vector>);
- let frame-fields = get-frame-field(field.index, frame).frame-field-list;
+ let ff = get-frame-field(field.index, frame);
+ let frame-fields = ff.frame-field-list;
let start = start;
if (packet.size > 0)
let (value, offset)
@@ -304,26 +305,30 @@
end;
frames := add!(frames, value);
frame-fields := add!(frame-fields,
- make(<frame-field>,
+ make(<rep-frame-field>,
start: start,
end: byte-offset(start) * 8 + offset,
- length: byte-offset(start) * 8 + offset - start));
+ length: byte-offset(start) * 8 + offset - start,
+ frame: value,
+ parent: ff));
start := byte-offset(start) * 8 + offset;
while ((~ field.reached-end?(frames.last)) & (byte-offset(start) < packet.size))
let (value, offset)
= parse-frame(field.type,
- subsequence(packet, start: byte-offset(start)),
- start: bit-offset(start),
- parent: frame);
+ subsequence(packet, start: byte-offset(start)),
+ start: bit-offset(start),
+ parent: frame);
unless (offset)
offset := end-offset(get-frame-field(field-count(value.object-class) - 1, value));
end;
frames := add!(frames, value);
frame-fields := add!(frame-fields,
- make(<frame-field>,
+ make(<rep-frame-field>,
start: start,
end: byte-offset(start) * 8 + offset,
- length: byte-offset(start) * 8 + offset - start));
+ length: byte-offset(start) * 8 + offset - start,
+ frame: value,
+ parent: ff));
start := byte-offset(start) * 8 + offset;
end;
end;
@@ -335,7 +340,8 @@
start :: <integer>,
packet :: <byte-sequence>)
let frames = make(<stretchy-vector>);
- let frame-fields = get-frame-field(field.index, frame).frame-field-list;
+ let ff = get-frame-field(field.index, frame);
+ let frame-fields = ff.frame-field-list;
let start = start;
if (packet.size > 0)
for (i from 0 below field.count(frame))
@@ -350,10 +356,12 @@
end;
frames := add!(frames, value);
frame-fields := add!(frame-fields,
- make(<frame-field>,
+ make(<rep-frame-field>,
start: start,
end: byte-offset(start) * 8 + offset,
- length: byte-offset(start) * 8 + offset - start));
+ length: byte-offset(start) * 8 + offset - start,
+ frame: value,
+ parent: ff));
start := byte-offset(start) * 8 + offset;
end;
end;
More information about the chatter
mailing list