[Gd-chatter] r10815 - in trunk/libraries: layer packetizer registry/generic timer

hannes at gwydiondylan.org hannes at gwydiondylan.org
Thu Jul 6 01:22:37 CEST 2006


Author: hannes
Date: Thu Jul  6 01:22:35 2006
New Revision: 10815

Added:
   trunk/libraries/layer/
   trunk/libraries/layer/layer.dylan   (contents, props changed)
   trunk/libraries/layer/layer.hdp   (contents, props changed)
   trunk/libraries/layer/library.dylan   (contents, props changed)
   trunk/libraries/layer/module.dylan   (contents, props changed)
   trunk/libraries/registry/generic/layer   (contents, props changed)
Modified:
   trunk/libraries/packetizer/module.dylan
   trunk/libraries/timer/timer-test.dylan
Log:
Bug: 7299
added a layer library, which works completing <ethernet-frames>

Added: trunk/libraries/layer/layer.dylan
==============================================================================
--- (empty file)
+++ trunk/libraries/layer/layer.dylan	Thu Jul  6 01:22:35 2006
@@ -0,0 +1,257 @@
+Module:    layer
+Author:    Andreas Bogk, Hannes Mehnert
+Copyright: (C) 2006,  All rights reserved.
+
+define class <undefined-field-error> (<error>)
+end;
+
+define generic ethernet-fan-in (object :: <ethernet-layer>) => (res :: <fan-in>);
+define generic demultiplexer (object :: <ethernet-layer>) => (res :: <demultiplexer>);
+define generic ethernet-interface (object :: <ethernet-layer>) => (res :: <ethernet-interface>);
+define generic ethernet-interface-setter (object :: <ethernet-interface>, object2 :: <ethernet-layer>) => (res :: <ethernet-interface>);
+define generic default-mac-address (object :: <ethernet-layer>) => (res :: <mac-address>);
+define generic default-mac-address-setter (object :: <mac-address>, object2 :: <ethernet-layer>) => (res :: <mac-address>);
+
+define class <ethernet-layer> (<object>)
+  constant slot ethernet-fan-in :: <fan-in> = make(<fan-in>);
+  constant slot demultiplexer :: <demultiplexer> = make(<demultiplexer>);
+  //slot sockets :: <collection> = make(<stretchy-vector>);
+  slot ethernet-interface :: <ethernet-interface>,
+    required-init-keyword: ethernet-interface:;
+  slot default-mac-address :: <mac-address> = mac-address("00:de:ad:be:ef:01"),
+    init-keyword: default-mac-address:;
+end;
+
+define method initialize (layer :: <ethernet-layer>,
+                          #rest rest, #key, #all-keys);
+  connect(layer.ethernet-fan-in, layer.ethernet-interface);
+  connect(layer.ethernet-interface, layer.demultiplexer);
+end;
+
+define generic template-frame (object :: <completer>) => (res :: <frame>);
+define class <completer> (<filter>)
+  constant slot template-frame :: <frame>, required-init-keyword: template-frame:;
+end;
+
+define method push-data-aux (input :: <push-input>,
+                             node :: <completer>,
+                             frame :: <container-frame>);
+  for (field in node.template-frame.fields)
+    unless (field.getter(frame))
+      let default-field-value = field.getter(node.template-frame);
+      if (default-field-value)
+        field.setter(default-field-value, frame);
+      elseif (~ field.fixup-function)
+        signal(make(<undefined-field-error>));
+      end;
+    end;
+  end;
+  push-data(node.the-output, frame);
+end;
+
+define open generic ethernet-type-code (object :: <ethernet-socket>) => (res :: <integer>);
+define generic listen-address (object :: <ethernet-socket>) => (res :: false-or(<mac-address>));
+define open generic demultiplexer-output (object :: <ethernet-socket>) => (res :: <object>);
+define open generic demultiplexer-output-setter (value :: <object>, object :: <ethernet-socket>) => (res :: <object>);
+define generic decapsulator (object :: <ethernet-socket>) => (res :: <decapsulator>);
+define generic completer (object :: <ethernet-socket>) => (res :: <completer>);
+define generic completer-setter (value :: <completer>, object :: <ethernet-socket>) => (res :: <completer>);
+define class <ethernet-socket> (<object>)
+  constant slot ethernet-type-code :: <integer>, init-keyword: type-code:;
+  constant slot listen-address :: false-or(<mac-address>) = #f, init-keyword: listen-address:;
+  slot demultiplexer-output;
+  constant slot decapsulator :: <decapsulator> = make(<decapsulator>);
+  slot completer :: <completer>;
+end;
+
+define method create-socket (layer :: <ethernet-layer>,
+                             type-code :: <integer>,
+                             #key mac-address)
+ => (socket :: <ethernet-socket>);
+  let source-address = mac-address | layer.default-mac-address;
+  let socket = make(<ethernet-socket>,
+                    type-code: type-code,
+                    listen-address: source-address);
+  let template-frame = make(cache-class(<ethernet-frame>),
+                            type-code: type-code,
+                            source-address: source-address);
+  socket.completer := make(<completer>,
+                           template-frame: template-frame);
+  socket.demultiplexer-output
+    := create-output-for-filter(layer.demultiplexer,
+                                format-to-string("(ethernet.destination-address = %s) & (ethernet.type-code = %s)",
+                                                 source-address, type-code));
+  connect(socket.demultiplexer-output, socket.decapsulator);
+  connect(socket.completer, layer.ethernet-fan-in);
+  socket;
+end;
+
+define method delete-socket (socket :: <ethernet-socket>, layer :: <ethernet-layer>)
+  disconnect(socket.demultiplexer-output, socket.decapsulator);
+  disconnect(socket.completer, layer.ethernet-fan-in);
+end;
+
+define open generic ethernet-layer (object :: <ip-over-ethernet-adapter>) => (res :: <ethernet-layer>);
+define open generic ethernet-layer-setter (value :: <ethernet-layer>, object :: <ip-over-ethernet-adapter>) => (res :: <ethernet-layer>);
+define generic arp-handler (object :: <ip-over-ethernet-adapter>) => (res :: <arp-handler>);
+define generic arp-handler-setter (value :: <arp-handler>, object :: <ip-over-ethernet-adapter>) => (res :: <arp-handler>);
+
+define class <ip-over-ethernet-adapter> (<object>)
+  //slot ip-layer :: <ip-layer>, required-init-keyword: ip-layer:;
+  slot ethernet-layer :: <ethernet-layer>, required-init-keyword: ethernet:;
+  slot arp-handler :: <arp-handler>, required-init-keyword: arp:;
+  //slot ipv4-address, init-keyword: ipv4-address:;
+end;
+
+define method initialize (ip-over-ethernet :: <ip-over-ethernet-adapter>,
+                          #rest rest, #key, #all-keys);
+  let ip-socket = create-socket(ip-over-ethernet.ethernet-layer, #x800);
+  let arp-socket = create-socket(ip-over-ethernet.ethernet-layer, #x806);
+  let arp-broadcast-socket = create-socket(ip-over-ethernet.ethernet-layer,
+                                           #x806,
+                                           mac-address: mac-address("ff:ff:ff:ff:ff:ff"));
+  let arp-fan-in = make(<fan-in>);
+  connect(arp-socket.decapsulator, arp-fan-in);
+  connect(arp-broadcast-socket.decapsulator, arp-fan-in);
+  //connect(ip-socket.decapsulator, ip-handler);
+  //connect(ip-handler, ip-socket.completer);
+  connect(arp-fan-in, ip-over-ethernet.arp-handler);
+  connect(ip-over-ethernet.arp-handler, arp-socket.completer);
+  ip-over-ethernet.arp-handler.ip-over-ethernet-adapter := ip-over-ethernet;
+end;
+
+/*
+define class <ip-layer> (<object>)
+  slot fan-in :: <fan-in> = make(<fan-in>);
+  slot demultiplexer :: <demultiplexer> = make(<demultiplexer>);
+  slot routing-table;
+end;
+define method add-static-route (ip-layer :: <ip-layer>, cidr :: <cidr>, adapter)
+end;
+
+define method find-route (ip-layer :: <ip-layer>, destination-address :: <ipv4-address>)
+ => (adapter, next-hop)
+end;
+
+define method delete-static-route (ip-layer :: <ip-layer>, cidr :: <cidr>)
+end;
+*/
+
+define generic arp-cache (object :: <arp-handler>) => (res :: <vector-table>);
+define generic pending-arp-requests (object :: <arp-handler>) => (res :: <vector-table>);
+define generic lock (object :: <arp-handler>) => (res :: <lock>);
+define generic ip-over-ethernet-adapter (object :: <arp-handler>) => (res :: <ip-over-ethernet-adapter>);
+define generic ip-over-ethernet-adapter-setter (value :: <ip-over-ethernet-adapter>, object :: <arp-handler>) => (res :: <ip-over-ethernet-adapter>);
+define generic v4-address (object :: <arp-handler>) => (res :: <ipv4-address>);
+define class <arp-handler> (<filter>)
+  constant slot arp-cache :: <vector-table> = make(<vector-table>);
+  constant slot pending-arp-requests :: <vector-table> = make(<vector-table>);
+  constant slot lock :: <lock> = make(<lock>);
+  slot ip-over-ethernet-adapter :: <ip-over-ethernet-adapter>;
+  constant slot v4-address :: <ipv4-address> = ipv4-address("192.168.0.24");
+end;
+
+define generic original-request (object :: <outstanding-arp-request>) => (res :: <frame>);
+define open generic notification (object :: <outstanding-arp-request>) => (res :: <notification>);
+define open generic notification-setter (value :: <notification>, object :: <outstanding-arp-request>) => (res :: <notification>);
+define open generic timer (object :: <outstanding-arp-request>) => (res :: <timer>);
+define open generic timer-setter (value :: <timer>, object :: <outstanding-arp-request>) => (res :: <timer>);
+define open generic counter (object :: <outstanding-arp-request>) => (res :: <object>);
+define open generic counter-setter (value :: <object>, object :: <outstanding-arp-request>) => (res :: <object>);
+
+define class <outstanding-arp-request> (<object>)
+  constant slot original-request :: <frame>, required-init-keyword: request:;
+  slot notification :: <notification>;
+  slot timer :: <timer>;
+  slot counter = 0;
+end;
+
+define method try-again (request :: <outstanding-arp-request>, handler :: <arp-handler>)
+  with-lock(handler.lock)
+    if (request.counter > 3)
+      release-all(request.notification)
+    else
+      push-data(handler.the-output, request.original-request);
+      request.timer := make(<timer>, in: 5, event: curry(try-again, request, handler));
+      request.counter := request.counter + 1;
+    end
+  end
+end;
+
+define method initialize (outstanding-arp-request :: <outstanding-arp-request>,
+                          #rest rest, #key handler :: <arp-handler>, #all-keys)
+  outstanding-arp-request.notification := make(<notification>, lock: handler.lock);
+end;
+   
+define method push-data-aux (input :: <push-input>,
+                             node :: <arp-handler>,
+                             frame :: <container-frame>)
+  format-out("received arp frame %=\n", frame);
+  if (frame.operation = 1
+      & frame.target-mac-address = mac-address("00:00:00:00:00:00")
+      & frame.target-ip-address = node.v4-address)
+    let arp-response = make(<arp-frame>,
+                            operation: 2,
+                            target-mac-address: frame.source-mac-address,
+                            target-ip-address: frame.source-ip-address,
+                            source-mac-address: node.ip-over-ethernet-adapter.ethernet-layer.default-mac-address,
+                            source-ip-address: node.v4-address);
+    push-data(node.the-output, make(<ethernet-frame>,
+                                    payload: arp-response,
+                                    destination-address: frame.source-mac-address));
+  elseif (frame.operation = 2
+          & frame.target-mac-address = node.ip-over-ethernet-adapter.ethernet-layer.default-mac-address
+          & frame.target-ip-address = node.v4-address)
+    with-lock(node.lock)
+      node.arp-cache[frame.source-ip-address] := frame.source-mac-address;
+      let arp-request = node.pending-arp-requests[frame.source-ip-address];
+      cancel(arp-request.timer);
+      remove-key!(node.pending-arp-requests, frame.source-ip-address);
+      release-all(arp-request.notification);
+    end
+  end;
+end;
+
+define method find-mac-address (arp-handler :: <arp-handler>, ip :: <ipv4-address>)
+ => (res :: false-or(<mac-address>))
+  element(arp-handler.arp-cache, ip, default: #f) |
+    begin
+      with-lock(arp-handler.lock)
+        unless (element(arp-handler.pending-arp-requests, ip, default: #f))
+          let arp-request = make(<arp-frame>,
+                                 operation: 1,
+                                 source-mac-address: arp-handler.ip-over-ethernet-adapter.ethernet-layer.default-mac-address,
+                                 source-ip-address: arp-handler.v4-address,
+                                 target-ip-address: ip,
+                                 target-mac-address: mac-address("00:00:00:00:00:00"));
+          let ethernet-frame = make(<ethernet-frame>,
+                                    destination-address: mac-address("ff:ff:ff:ff:ff:ff"),
+                                    payload: arp-request);
+          push-data(arp-handler.the-output, ethernet-frame);
+          let outstanding-request = make(<outstanding-arp-request>, handler: arp-handler, request: ethernet-frame);
+          let timer* = make(<timer>, in: 5, event: curry(try-again, outstanding-request, arp-handler));
+          outstanding-request.timer := timer*;
+          arp-handler.pending-arp-requests[ip] := outstanding-request;
+        end;
+        wait-for(arp-handler.pending-arp-requests[ip].notification);
+        element(arp-handler.arp-cache, ip, default: #f);
+      end
+    end
+end;
+
+
+begin
+  format-out("FFFFF\n");
+  let int = make(<ethernet-interface>, name: "Intel");
+  format-out("Opened interface\n");
+  let ethernet-layer = make(<ethernet-layer>, ethernet-interface: int);
+  format-out("Initialized ethernet layer\n");
+  let arp-handler = make(<arp-handler>);
+  format-out("Created arp handler\n");
+  let ip-over-ethernet = make(<ip-over-ethernet-adapter>, ethernet: ethernet-layer, arp: arp-handler);
+  format-out("Created ip-over-ethernet-adapter %=\n", ip-over-ethernet);
+  let thr = make(<thread>, function: curry(toplevel, int));
+  format-out("FOOOO\n");
+  format-out("Mac 192.168.0.1: %=\n", find-mac-address(arp-handler, ipv4-address("192.168.0.1")));
+end;
+

Added: trunk/libraries/layer/layer.hdp
==============================================================================
--- (empty file)
+++ trunk/libraries/layer/layer.hdp	Thu Jul  6 01:22:35 2006
@@ -0,0 +1,4 @@
+Library:          layer
+Files:            library
+	module
+	layer

Added: trunk/libraries/layer/library.dylan
==============================================================================
--- (empty file)
+++ trunk/libraries/layer/library.dylan	Thu Jul  6 01:22:35 2006
@@ -0,0 +1,17 @@
+Module:    dylan-user
+Author:    Andreas Bogk, Hannes Mehnert
+Copyright: (C) 2006,  All rights reserved.
+
+define library layer
+  use common-dylan;
+  use io;
+  use network-flow;
+  use flow;
+  use packetizer;
+  use timer;
+  use interfaces;
+  use vector-table;
+
+  // Add any more module exports here.
+  export layer;
+end library layer;

Added: trunk/libraries/layer/module.dylan
==============================================================================
--- (empty file)
+++ trunk/libraries/layer/module.dylan	Thu Jul  6 01:22:35 2006
@@ -0,0 +1,20 @@
+Module:    dylan-user
+Author:    Andreas Bogk, Hannes Mehnert
+Copyright: (C) 2006,  All rights reserved.
+
+define module layer
+  use common-dylan;
+  use standard-io;
+  use format;
+  use format-out;
+  use threads;
+  use network-flow;
+  use packetizer;
+  use timer;
+  use flow;
+  use interfaces;
+  use vector-table;
+
+  // Add binding exports here.
+
+end module layer;

Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan	(original)
+++ trunk/libraries/packetizer/module.dylan	Thu Jul  6 01:22:35 2006
@@ -20,7 +20,7 @@
   export <ethernet-frame>, <ipv4-frame>,
     <ipv4-address>, <mac-address>,
     operation, source-address, destination-address,
-    type-code, <arp-frame>,
+    type-code, <arp-frame>, target-mac-address,
     target-ip-address, source-ip-address, source-mac-address,
     mac-address, ipv4-address, 
     <decoded-arp-frame>, <decoded-ethernet-frame>,
@@ -55,6 +55,8 @@
     field-name,
     field-size,
     getter,
+    setter,
+    fixup-function,
     type;
 
   export <frame>,

Added: trunk/libraries/registry/generic/layer
==============================================================================
--- (empty file)
+++ trunk/libraries/registry/generic/layer	Thu Jul  6 01:22:35 2006
@@ -0,0 +1 @@
+abstract://dylan/layer/layer.hdp

Modified: trunk/libraries/timer/timer-test.dylan
==============================================================================
--- trunk/libraries/timer/timer-test.dylan	(original)
+++ trunk/libraries/timer/timer-test.dylan	Thu Jul  6 01:22:35 2006
@@ -18,5 +18,5 @@
 end;
 
 begin
-  main();
+ //main();
 end;



More information about the chatter mailing list