[Gd-chatter] r10852 - in trunk/libraries: gui-sniffer network-flow packetizer

hannes at gwydiondylan.org hannes at gwydiondylan.org
Fri Aug 11 23:59:48 CEST 2006


Author: hannes
Date: Fri Aug 11 23:59:46 2006
New Revision: 10852

Modified:
   trunk/libraries/gui-sniffer/gui-sniffer.dylan
   trunk/libraries/network-flow/network-flow.dylan
   trunk/libraries/packetizer/module.dylan
   trunk/libraries/packetizer/pcap.dylan
Log:
Bug: 7299
*fix date stuff (timestamp is unix time_t)

Modified: trunk/libraries/gui-sniffer/gui-sniffer.dylan
==============================================================================
--- trunk/libraries/gui-sniffer/gui-sniffer.dylan	(original)
+++ trunk/libraries/gui-sniffer/gui-sniffer.dylan	Fri Aug 11 23:59:46 2006
@@ -100,9 +100,10 @@
   frame.number;
 end;
 
-define method print-time (frame :: <frame-with-metadata>)
+define method print-time (gui :: <gui-sniffer-frame>, frame :: <frame-with-metadata>)
+  let diff = frame.receive-time - gui.first-packet-arrived;
   let (days, hours, minutes, seconds, microseconds)
-    = decode-duration(frame.receive-time);
+    = decode-duration(diff);
   let secs = (((days * 24 + hours) * 60) + minutes) * 60 + seconds;
   secs + as(<float>, microseconds) / 1000000
 end;
@@ -179,7 +180,7 @@
   slot network-frames :: <stretchy-vector> = make(<stretchy-vector>);
   slot filter-expression = #f;
   slot ethernet-interface = #f;
-  slot started-capturing-at :: <date> = current-date();
+  slot first-packet-arrived :: false-or(<date>) = #f;
 
   pane filter-field (frame)
     make(<text-field>,
@@ -196,7 +197,7 @@
     make(<table-control>,
          headings: #("No", "Time", "Source", "Destination", "Protocol", "Info"),
          generators: list(print-number,
-                          print-time,
+                          curry(print-time, frame),
                           print-source,
                           print-destination,
                           print-protocol,
@@ -274,11 +275,9 @@
     connect(frame, pcap-writer);
     do(curry(push-data, frame.the-output),
        map(method(x)
+             let time-diff = x.receive-time - make(<date>, year: 1970, month: 1, day: 1);
              make(<pcap-packet>,
-                  timestamp: make-unix-time(x.receive-time),
-                  //XXX: should be absolute time since 1.1.1970, but
-                  //getting integer overflows, so use relative time since
-                  //packet capturing for now
+                  timestamp: make-unix-time(time-diff),
                   payload: x.real-frame)
            end, frame.network-frames));
     //XXX: disconnect in flow graph, but disconnect is NYI
@@ -297,7 +296,6 @@
     reinit-gui(frame);
     make(<thread>, function: curry(toplevel, interface));
     frame.ethernet-interface := interface;
-    frame.started-capturing-at := current-date();
     gadget-label(frame.sniffer-status-bar) := concatenate("Capturing ", interface-name);
   end;
 end;
@@ -330,6 +328,7 @@
 end;
 
 define method reinit-gui (frame :: <gui-sniffer-frame>)
+  frame.first-packet-arrived := #f;
   *count* := 0;
   frame.network-frames := make(<stretchy-vector>);
   gadget-items(frame.packet-table) := frame.network-frames;
@@ -339,14 +338,23 @@
 define class <frame-with-metadata> (<object>)
   constant slot real-frame :: <ethernet-frame>, required-init-keyword: frame:;
   constant slot number :: <integer> = counter();
-  slot receive-time :: <day/time-duration>, required-init-keyword: receive-time:;
+  constant slot receive-time :: <date> = current-date(), init-keyword: receive-time:;
 end;
 
 define method push-data-aux (input :: <push-input>,
                              node :: <gui-sniffer-frame>,
                              frame :: <frame>)
-  let duration = current-date() - node.started-capturing-at;
-  let frame-with-meta = make(<frame-with-metadata>, frame: frame, receive-time: duration);
+  let frame-with-meta =
+    if (frame.parent & instance?(frame.parent, <pcap-packet>))
+      make(<frame-with-metadata>,
+           frame: frame,
+           receive-time: decode-unix-time(frame.parent.timestamp))
+    else
+      make(<frame-with-metadata>, frame: frame);
+    end;
+  unless (node.first-packet-arrived)
+    node.first-packet-arrived := frame-with-meta.receive-time;
+  end;
   add!(node.network-frames, frame-with-meta);
   if (~ node.filter-expression | matches?(frame, node.filter-expression))
     add-item(node.packet-table, make-item(node.packet-table, frame-with-meta))

Modified: trunk/libraries/network-flow/network-flow.dylan
==============================================================================
--- trunk/libraries/network-flow/network-flow.dylan	(original)
+++ trunk/libraries/network-flow/network-flow.dylan	Fri Aug 11 23:59:46 2006
@@ -150,13 +150,15 @@
                      method (r, f)
                        push-data(r.the-output,
                                  make(unparsed-class(<ethernet-frame>),
-                                      packet: assemble-frame(f.payload)));
+                                      packet: assemble-frame(f.payload),
+                                      parent: f));
                      end method;
                    $DLT-PRISM-HEADER =>
                      method (r, f)
                        push-data(r.the-output,
                                  make(unparsed-class(<prism2-frame>),
-                                      packet: assemble-frame(f.payload)));
+                                      packet: assemble-frame(f.payload),
+                                      parent: f));
                      end method;
                  end select;
   for(frame in pcap-file.packets)

Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan	(original)
+++ trunk/libraries/packetizer/module.dylan	Fri Aug 11 23:59:46 2006
@@ -34,7 +34,7 @@
     <repeated-field>;
 
   export <pcap-file>, <pcap-file-header>, <pcap-packet>, header, packets,
-    $DLT-EN10MB, $DLT-PRISM-HEADER, make-unix-time;
+    $DLT-EN10MB, $DLT-PRISM-HEADER, make-unix-time, decode-unix-time, timestamp;
 
   export <icmp-frame>, code, type, checksum;
 

Modified: trunk/libraries/packetizer/pcap.dylan
==============================================================================
--- trunk/libraries/packetizer/pcap.dylan	(original)
+++ trunk/libraries/packetizer/pcap.dylan	Fri Aug 11 23:59:46 2006
@@ -32,31 +32,74 @@
 
 define function int-to-byte-vector (int :: <integer>) => (res :: <byte-vector>)
   let res = make(<byte-vector>, size: 4);
-  for (ele in res,
-       i from 0)
+  for (i from 0 below 4)
     res[i] := logand(#xff, ash(int, - i * 8));
   end;
   res;
 end;
 
+define function float-to-byte-vector (float :: <float>) => (res :: <byte-vector>)
+  let res = make(<byte-vector>, size: 4, fill: 0);
+  let r = float;
+  for (i from 0 below 4)
+    let (this, remainder) = floor/(r, 256);
+    r := this;
+    res[i] := floor(remainder);
+  end;
+  res;
+end;
+
 define protocol unix-time-value (container-frame)
-  field seconds :: <little-endian-unsigned-integer-4byte>
-   = little-endian-unsigned-integer-4byte(get-seconds());
-  field microseconds :: <little-endian-unsigned-integer-4byte>
-   = little-endian-unsigned-integer-4byte(#(#x00, #x00, #x00, #x00));
+  field seconds :: <little-endian-unsigned-integer-4byte>;
+  field microseconds :: <little-endian-unsigned-integer-4byte>;
+end;
+
+define function byte-vector-to-float (bv :: <byte-vector>) => (res :: <float>)
+  let res = 0.0d0;
+  for (ele in reverse(bv))
+    res := ele + 256 * res;
+  end;
+  res;
+end;
+
+define function byte-vector-to-int (bv :: <byte-vector>) => (res :: <integer>)
+  let res = 0;
+  let first? = #t;
+  for (ele in reverse(bv))
+    if (first?)
+      first? := #f
+    else
+      res := ele + 256 * res;
+    end;
+  end;
+  res;
+end;
+
+define method decode-unix-time (unix-time :: <unix-time-value>)
+ => (res :: <date>)
+ let secs = byte-vector-to-float(unix-time.seconds.data);
+ format-out("Seconds %=\n", secs);
+ let (days, rem0) = floor/(secs, 86400);
+ let (hours, rem1) = floor/(rem0, 3600);
+ let (minutes, seconds) = floor/(rem1, 60);
+ format-out("microseconds %=\n", unix-time.microseconds);
+ encode-day/time-duration(days, hours, minutes, round(seconds),
+                          byte-vector-to-int(unix-time.microseconds.data))
+  + make(<date>, year: 1970, month: 1, day: 1)
 end;
 
 define method make-unix-time (dur :: <day/time-duration>)
   => (res :: <unix-time-value>)
   let (days, hours, minutes, seconds, microseconds) = decode-duration(dur);
-  let secs = (((days * 24 + hours) * 60) + minutes) * 60 + seconds;
+  let secs = ((as(<double-float>, days) * 24 + hours) * 60 + minutes) * 60 + seconds;
   make(<unix-time-value>,
-       seconds: little-endian-unsigned-integer-4byte(int-to-byte-vector(secs)),
+       seconds: little-endian-unsigned-integer-4byte(float-to-byte-vector(secs)),
        microseconds: little-endian-unsigned-integer-4byte(int-to-byte-vector(microseconds)));
 end;
 
 define protocol pcap-packet (header-frame)
-  field timestamp :: <unix-time-value> = make(<unix-time-value>);
+  field timestamp :: <unix-time-value>
+    = make-unix-time(current-date() - make(<date>, year: 1970, month: 1, day: 1));
   field capture-length :: <3byte-little-endian-unsigned-integer>,
    fixup: byte-offset(frame-size(frame.payload));
   field last-capture-length :: <unsigned-byte> = 0;



More information about the chatter mailing list