[Gd-chatter] r10926 - in trunk/libraries/packetizer: . packetizer-test

hannes at gwydiondylan.org hannes at gwydiondylan.org
Mon Oct 16 23:53:18 CEST 2006


Author: hannes
Date: Mon Oct 16 23:53:14 2006
New Revision: 10926

Modified:
   trunk/libraries/packetizer/dns.dylan
   trunk/libraries/packetizer/fields.dylan
   trunk/libraries/packetizer/leaf-frames.dylan
   trunk/libraries/packetizer/module.dylan
   trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan
   trunk/libraries/packetizer/packetizer-test/stretchy-byte-vector-test.dylan
   trunk/libraries/packetizer/packetizer.dylan
   trunk/libraries/packetizer/stretchy-byte-vector.dylan
Log:
Bug: 7299
*implement decode-integer
*element for <stretchy-byte-vector-subsequence-with-offset> was broken
*use decode-integer in parse-frame of <unsigned-integer-bit-frame> instead of element

Modified: trunk/libraries/packetizer/dns.dylan
==============================================================================
--- trunk/libraries/packetizer/dns.dylan	(original)
+++ trunk/libraries/packetizer/dns.dylan	Mon Oct 16 23:53:14 2006
@@ -65,16 +65,25 @@
           end;
         end;
   let dns-frame = find-dns-frame(label-offset);
-  dns-frame
-    & parse-frame(<domain-name>,
-                  assemble-frame(dns-frame).packet,
-                  start: label-offset.offset * 8,
-                  parent: dns-frame);
+  if (dns-frame)
+    let dns-frame-size = dns-frame.packet.size;
+    if (label-offset.offset < dns-frame-size)
+      parse-frame(<domain-name>,
+                  subsequence(dns-frame.packet, start: label-offset.offset * 8),
+                  parent: label-offset.parent)
+    end;
+  end;
 end;
 
 define method as (class == <string>, label-offset :: <label-offset>)
  => (res :: <string>)
-  as(<string>, find-label(label-offset));
+  let label = find-label(label-offset);
+  if (label)
+    as(<string>, label);
+  else
+    format-out("couldn't find label at %d\n", label-offset.offset);
+    integer-to-string(label-offset.offset)
+  end;
 end;
 
 define class <externally-delimited-string> (<variable-size-byte-vector>)

Modified: trunk/libraries/packetizer/fields.dylan
==============================================================================
--- trunk/libraries/packetizer/fields.dylan	(original)
+++ trunk/libraries/packetizer/fields.dylan	Mon Oct 16 23:53:14 2006
@@ -133,25 +133,3 @@
         rest);
 end;
 
-define generic assemble-field (frame :: <frame>, field :: <field>)
- => (packet :: <vector>);
-
-define method assemble-field (frame :: <frame>,
-                              field :: <statically-typed-field>)
- => (packet :: <vector>)
-  assemble-frame-as(field.type, field.getter(frame))
-end;
-
-define method assemble-field (frame :: <frame>,
-                              field :: <variably-typed-field>)
- => (packet :: <vector>)
-  assemble-frame(field.getter(frame))
-end;
-
-define method assemble-field (frame :: <frame>,
-                              field :: <repeated-field>)
- => (packet :: <vector>)
-  apply(concatenate, map(curry(assemble-frame-as, field.type), field.getter(frame)))
-end;
-
-

Modified: trunk/libraries/packetizer/leaf-frames.dylan
==============================================================================
--- trunk/libraries/packetizer/leaf-frames.dylan	(original)
+++ trunk/libraries/packetizer/leaf-frames.dylan	Mon Oct 16 23:53:14 2006
@@ -119,15 +119,9 @@
                            #key start :: <integer> = 0)
   => (value :: <integer>, next-unparsed :: <integer>)
   let result-size = frame-size(frame-type);
-  if (packet.size * 8 < start + result-size)
-    signal(make(<malformed-packet-error>))
-  else
-    let result = 0;
-    for (i from 0 below size(packet))
-      result := ash(result, 8) + packet[i];
-    end;
-    values(result, result-size + start);
-  end;
+  let subseq = subsequence(packet, start: start, length: result-size);
+  let value = decode-integer(subseq, result-size);
+  values(value, result-size + start);
 end;
 
 define method assemble-frame (frame :: <unsigned-integer-bit-frame>)

Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan	(original)
+++ trunk/libraries/packetizer/module.dylan	Mon Oct 16 23:53:14 2006
@@ -18,7 +18,7 @@
     <stretchy-byte-vector-subsequence>,
     subsequence,
     <out-of-bound-error>,
-    encode-integer;
+    encode-integer, decode-integer;
 
   export <udp-frame>, source-port, destination-port, length, checksum;
 
@@ -61,7 +61,8 @@
     <2byte-big-endian-unsigned-integer>,
     <3byte-little-endian-unsigned-integer>,
     <externally-delimited-string>, <1bit-unsigned-integer>,
-    <4bit-unsigned-integer>, <7bit-unsigned-integer>;
+    <4bit-unsigned-integer>, <7bit-unsigned-integer>,
+    <2bit-unsigned-integer>, <14bit-unsigned-integer>;
 
   export <fixed-size-translated-leaf-frame>, <byte-sequence>;
 

Modified: trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan	(original)
+++ trunk/libraries/packetizer/packetizer-test/packetizer-test.dylan	Mon Oct 16 23:53:14 2006
@@ -398,6 +398,16 @@
   check-equal("assembling is correct", 84, as.packet[0]);
 end;
 
+define protocol dns-foo (container-frame)
+  field typed :: <2bit-unsigned-integer>;
+  field pointer :: <14bit-unsigned-integer>;
+end;
+
+define test dns-foo-parsing ()
+  let frame = make(unparsed-class(<dns-foo>), packet: as(<byte-vector>, #(#xc0, #x4e)));
+  check-equal("type of frame is correct", 3, frame.typed);
+  check-equal("pointer of frame is correct", #x4e, frame.pointer);
+end;
 define suite packetizer-suite ()
   test packetizer-parser;
   test packetizer-dynamic-parser;
@@ -412,6 +422,7 @@
   test dyn-length;
   test dynamic-length;
   test half-byte-parsing;
+  test dns-foo-parsing;
 end;
 
 define suite packetizer-assemble-suite ()

Modified: trunk/libraries/packetizer/packetizer-test/stretchy-byte-vector-test.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer-test/stretchy-byte-vector-test.dylan	(original)
+++ trunk/libraries/packetizer/packetizer-test/stretchy-byte-vector-test.dylan	Mon Oct 16 23:53:14 2006
@@ -232,6 +232,29 @@
   encode-integer(1, sub1, 1);
   check-equal("encode integer in bit vector", 2, sbv[0]);
 end;
+
+define test decode-integer-test ()
+  let sbv = make(<stretchy-byte-vector-subsequence>);
+  sbv[0] := #x55;
+  sbv[1] := #xaa;
+  let sub1 = subsequence(sbv, start: 2);
+  check-equal("decode integer in bit vector 4", #x5, decode-integer(sub1, 4));
+  check-equal("decode integer in bit vector 1", #x0, decode-integer(sub1, 1));
+  check-equal("decode integer in bit vector 2", #x1, decode-integer(sub1, 2));
+  check-equal("decode integer in bit vector 8", #x56, decode-integer(sub1, 8));
+  check-equal("decode integer in bit vector 10", #x15a, decode-integer(sub1, 10));
+end;
+
+define test decode-and-encode-test ()
+  let sbv = make(<stretchy-byte-vector-subsequence>);
+  for (i from 1 below 10)
+    let sub = subsequence(sbv, start: i, length: i);
+    for (j from 0 below 2 ^ i - 1)
+      encode-integer(j, sub, i);
+      check-equal("decode-encode", j, decode-integer(sub, i));
+    end;
+  end;
+end;
 define suite stretchy-byte-vector-suite ()
   test byte-vector-subsequence-read;
   test byte-vector-subsequence-modify;
@@ -246,6 +269,8 @@
   test byte-vector-subsequence-with-offset-modify;
   test encode-integer-test;
   test encode-integer-test2;
+  test decode-integer-test;
+  test decode-and-encode-test;
 end;
 
 begin

Modified: trunk/libraries/packetizer/packetizer.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer.dylan	(original)
+++ trunk/libraries/packetizer/packetizer.dylan	Mon Oct 16 23:53:14 2006
@@ -256,7 +256,7 @@
 end;
 
 define method make (class :: subclass(<unparsed-container-frame>),
-                    #next next-method, #rest rest, #key packet, #all-keys)
+                    #next next-method, #rest rest, #key packet, parent, #all-keys)
  => (res :: <unparsed-container-frame>)
   if (instance?(packet, <byte-vector>))
     let packet = as(<stretchy-byte-vector-subsequence>, packet);
@@ -327,10 +327,6 @@
   reduce1(\+, map(curry(get-field-size-aux, frame), frame.fields));
 end;
 
-//define method frame-size (frame :: <unparsed-container-frame>) => (size :: <integer>)
-//  frame.packet.size * 8
-//end;
-
 define method assemble-frame (frame :: <container-frame>) => (packet :: <unparsed-container-frame>);
   let result = make(<stretchy-byte-vector-subsequence>, data: make(<stretchy-byte-vector>, capacity: 1548));
   assemble-frame-into(frame, result);
@@ -414,6 +410,7 @@
 define method assemble-frame-into (frame :: <unparsed-container-frame>,
                                    to-packet :: <stretchy-vector-subsequence>) => (res :: <integer>)
   copy-bytes(frame.packet, 0, to-packet, 0, frame.packet.size);
+  frame.packet.size * 8;
 end;
 
 define method assemble-field-into(field :: <single-field>,

Modified: trunk/libraries/packetizer/stretchy-byte-vector.dylan
==============================================================================
--- trunk/libraries/packetizer/stretchy-byte-vector.dylan	(original)
+++ trunk/libraries/packetizer/stretchy-byte-vector.dylan	Mon Oct 16 23:53:14 2006
@@ -379,6 +379,50 @@
   value;
 end;
 
+define inline method decode-integer (seq :: <stretchy-byte-vector-subsequence>, count :: <integer>)
+ => (res :: <integer>)
+  //assumption: count is always dividable by 8!
+  let res = 0;
+  for (i from 0 below truncate/(count, 8))
+    res := ash(res, 8) + seq.real-data[seq.start-index + i];
+  end;
+  res;
+end;
+
+define inline method encode-integer (value :: <integer>, seq :: <stretchy-byte-vector-subsequence>, count :: <integer>)
+  //assumption: count is always dividable by 8!
+  let bytes = truncate/(count, 8);
+  for (i from 0 below bytes)
+    seq.real-data[seq.start-index + i] := logand(#xff, ash(value, - (count - (i + 1) * 8)))
+  end;
+end;
+
+define inline method decode-integer (seq :: <stretchy-byte-vector-subsequence-with-offset>, count :: <integer>)
+ => (res :: <integer>)
+  if (seq.end-index & (((seq.end-index - seq.start-index) * 8 - seq.bit-start-index + seq.bit-end-index) < count))  
+    signal(make(<out-of-bound-error>));
+  end;
+  let (fullbytes, bits) = truncate/(count - 8 + seq.bit-start-index, 8);
+  let first-byte = seq.start-index;
+  if ((fullbytes = 0) & (bits < 0))
+    let mask = ash(ash(#xff, - (8 - count)), 8 - seq.bit-start-index - count);
+    ash(logand(seq.real-data[first-byte], mask), bits);
+  else
+    let res :: <integer> = 0;
+    if (seq.bit-start-index = 0)
+      res := seq.real-data[first-byte];
+    else
+      res := logand(ash(#xff, - seq.bit-start-index), seq.real-data[first-byte]);
+    end;
+    for (i from 1 below fullbytes + 1)
+      res := ash(res, 8) + seq.real-data[first-byte + i];
+    end;
+    if ((bits > 0) & (fullbytes >= 0))
+      res := ash(res, bits) + ash(seq.real-data[first-byte + fullbytes + 1], - (8 - bits));
+    end;
+    res;
+  end;
+end;
 
 define inline method encode-integer (value :: <integer>, seq :: <stretchy-byte-vector-subsequence-with-offset>, count :: <integer>)
   if (value > 2 ^ count - 1)



More information about the chatter mailing list