[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