[Gd-chatter] r10824 - in trunk/libraries: layer packetizer
andreas at gwydiondylan.org
andreas at gwydiondylan.org
Sat Jul 15 00:54:20 CEST 2006
Author: andreas
Date: Sat Jul 15 00:54:18 2006
New Revision: 10824
Modified:
trunk/libraries/layer/layer.dylan
trunk/libraries/layer/library.dylan
trunk/libraries/layer/module.dylan
trunk/libraries/packetizer/ethernet.dylan
Log:
Bug: 7299
*improved arp-layer
Modified: trunk/libraries/layer/layer.dylan
==============================================================================
--- trunk/libraries/layer/layer.dylan (original)
+++ trunk/libraries/layer/layer.dylan Sat Jul 15 00:54:18 2006
@@ -100,7 +100,7 @@
//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:;
+ slot v4-address :: <ipv4-address>, required-init-keyword: ipv4-address:;
end;
define method initialize (ip-over-ethernet :: <ip-over-ethernet-adapter>,
@@ -118,6 +118,10 @@
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;
+ ip-over-ethernet.arp-handler.arp-table[ip-over-ethernet.v4-address]
+ := make(<advertised-arp-entry>,
+ ip-address: ip-over-ethernet.v4-address,
+ mac-address: ip-over-ethernet.ethernet-layer.default-mac-address);
end;
/*
@@ -137,18 +141,14 @@
end;
*/
-define generic arp-cache (object :: <arp-handler>) => (res :: <vector-table>);
-define generic pending-arp-requests (object :: <arp-handler>) => (res :: <vector-table>);
+define generic arp-table (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 arp-table :: <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>);
@@ -159,13 +159,31 @@
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>)
+define abstract class <arp-entry> (<object>)
+ constant slot ip-address :: <ipv4-address>, required-init-keyword: ip-address:;
+end;
+
+define class <outstanding-arp-request> (<arp-entry>)
constant slot original-request :: <frame>, required-init-keyword: request:;
slot notification :: <notification>;
slot timer :: <timer>;
slot counter = 0;
end;
+define abstract class <known-arp-entry> (<arp-entry>)
+ constant slot arp-mac-address :: <mac-address>, required-init-keyword: mac-address:;
+end;
+
+define class <static-arp-entry> (<known-arp-entry>)
+end;
+
+define class <advertised-arp-entry> (<static-arp-entry>)
+end;
+
+define class <dynamic-arp-entry> (<known-arp-entry>)
+ constant slot timestamp :: <date> = current-date()
+end;
+
define method try-again (request :: <outstanding-arp-request>, handler :: <arp-handler>)
with-lock(handler.lock)
if (request.counter > 3)
@@ -188,70 +206,116 @@
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)
+ & frame.target-mac-address = mac-address("00:00:00:00:00:00"))
+ let arp-entry = element(node.arp-table, frame.target-ip-address, default: #f);
+ if (arp-entry & instance?(arp-entry, <advertised-arp-entry>))
+ 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: arp-entry.arp-mac-address,
+ source-ip-address: arp-entry.ip-address);
+ push-data(node.the-output, make(<ethernet-frame>,
+ payload: arp-response,
+ destination-address: frame.source-mac-address));
+ end;
+ elseif (frame.operation = 2)
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);
+ let old-entry = element(node.arp-table, frame.source-ip-address, default: #f);
+ maybe-add-response-to-table(old-entry, node, frame)
end
end;
end;
+define method add-response-to-table (node :: <arp-handler>, frame :: <arp-frame>)
+ node.arp-table[frame.source-ip-address]
+ := make(<dynamic-arp-entry>,
+ ip-address: frame.source-ip-address,
+ mac-address: frame.source-mac-address);
+end;
+
+define method maybe-add-response-to-table
+ (old-entry == #f, node :: <arp-handler>, frame :: <arp-frame>)
+ add-response-to-table(node, frame)
+end;
+
+define method maybe-add-response-to-table
+ (old-entry :: <outstanding-arp-request>, node :: <arp-handler>, frame :: <arp-frame>)
+ cancel(old-entry.timer);
+ add-response-to-table(node, frame);
+ release-all(old-entry.notification);
+end;
+
+define method maybe-add-response-to-table
+ (old-entry :: <static-arp-entry>, node :: <arp-handler>, frame :: <arp-frame>)
+ ignore(old-entry, node, frame);
+end;
+
+define method maybe-add-response-to-table
+ (old-entry :: <dynamic-arp-entry>, node :: <arp-handler>, frame :: <arp-frame>)
+ if (frame.source-mac-address ~= old-entry.arp-mac-address)
+ format-out("ARP: IP %= moved from %= to %=\n",
+ old-entry.ip-address,
+ old-entry.arp-mac-address,
+ frame.source-mac-address);
+ end;
+ add-response-to-table(node, frame)
+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
+ let arp-entry = element(arp-handler.arp-table, ip, default: #f);
+ if (instance?(arp-entry, <known-arp-entry>))
+ arp-entry.arp-mac-address;
+ else
+ with-lock(arp-handler.lock)
+ unless(arp-entry)
+ 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.ip-over-ethernet-adapter.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,
+ ip-address: ip);
+ let timer* = make(<timer>, in: 5, event: curry(try-again, outstanding-request, arp-handler));
+ outstanding-request.timer := timer*;
+ arp-handler.arp-table[ip] := outstanding-request;
+ arp-entry := outstanding-request;
+ end;
+ wait-for(arp-entry.notification);
+ let entry = element(arp-handler.arp-table, ip, default: #f);
+ if (entry & instance?(entry, <known-arp-entry>))
+ entry.arp-mac-address;
+ else
+ remove-key!(arp-handler.arp-table, ip);
+ #f
+ end;
+ end;
+ end;
end;
begin
- format-out("FFFFF\n");
- let int = make(<ethernet-interface>, name: "Intel");
- format-out("Opened interface\n");
+ let int = make(<ethernet-interface>, name: "NetXtreme");
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);
+ arp-handler.arp-table[ipv4-address("192.168.0.23")]
+ := make(<advertised-arp-entry>,
+ mac-address: mac-address("00:de:ad:be:ef:00"),
+ ip-address: ipv4-address("192.168.0.23"));
+ let ip-over-ethernet = make(<ip-over-ethernet-adapter>,
+ ethernet: ethernet-layer,
+ arp: arp-handler,
+ ipv4-address: ipv4-address("192.168.0.24"));
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")));
+ //format-out("Mac 192.168.0.1: %=\n", find-mac-address(arp-handler, ipv4-address("192.168.0.1")));
+ sleep(1200);
end;
Modified: trunk/libraries/layer/library.dylan
==============================================================================
--- trunk/libraries/layer/library.dylan (original)
+++ trunk/libraries/layer/library.dylan Sat Jul 15 00:54:18 2006
@@ -11,6 +11,7 @@
use timer;
use interfaces;
use vector-table;
+ use system, import: { date };
// Add any more module exports here.
export layer;
Modified: trunk/libraries/layer/module.dylan
==============================================================================
--- trunk/libraries/layer/module.dylan (original)
+++ trunk/libraries/layer/module.dylan Sat Jul 15 00:54:18 2006
@@ -14,6 +14,7 @@
use flow;
use interfaces;
use vector-table;
+ use date, import: {<date>, current-date };
// Add binding exports here.
Modified: trunk/libraries/packetizer/ethernet.dylan
==============================================================================
--- trunk/libraries/packetizer/ethernet.dylan (original)
+++ trunk/libraries/packetizer/ethernet.dylan Sat Jul 15 00:54:18 2006
@@ -41,5 +41,12 @@
source-address, destination-address, compose(summary, payload);
field destination-address :: <mac-address>;
field source-address :: <mac-address>;
- field payload :: <logical-link-control>;
+ field type-code :: <2byte-big-endian-unsigned-integer>;
+ variably-typed-field payload,
+ type-function:
+ select (frame.type-code)
+ #x800 => <ipv4-frame>;
+ #x806 => <arp-frame>;
+ otherwise <raw-frame>;
+ end;
end;
More information about the chatter
mailing list