[Gd-chatter] r10936 - in trunk/libraries: layer packetizer
andreas at gwydiondylan.org
andreas at gwydiondylan.org
Thu Oct 26 22:31:24 CEST 2006
Author: andreas
Date: Thu Oct 26 22:31:19 2006
New Revision: 10936
Added:
trunk/libraries/layer/udp.dylan (contents, props changed)
Modified:
trunk/libraries/layer/layer.dylan
trunk/libraries/layer/layer.hdp
trunk/libraries/layer/tcp.dylan
trunk/libraries/packetizer/dns.dylan
trunk/libraries/packetizer/fields.dylan
trunk/libraries/packetizer/module.dylan
trunk/libraries/packetizer/protocol-definer-macro.dylan
Log:
bug: 7299
* beginning of UDP layer
* simple DNS query
Modified: trunk/libraries/layer/layer.dylan
==============================================================================
--- trunk/libraries/layer/layer.dylan (original)
+++ trunk/libraries/layer/layer.dylan Thu Oct 26 22:31:19 2006
@@ -493,13 +493,15 @@
define function init-ethernet ()
- let int = make(<ethernet-interface>, name: "Intel");
+ let int = make(<ethernet-interface>, name: "Xtreme");
let ethernet-layer = make(<ethernet-layer>, ethernet-interface: int);
let arp-handler = make(<arp-handler>);
+/*
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-layer = make(<ip-layer>);
register-route(ip-layer, make(<next-hop-route>, cidr: as(<cidr>, "0.0.0.0/0"),
next-hop: ipv4-address("192.168.0.1")));
@@ -514,6 +516,7 @@
ip-layer: ip-layer,
icmp-handler: icmp-handler);
let thr = make(<thread>, function: curry(toplevel, int));
+/*
send(icmp-handler.ip-socket,
ipv4-address("213.73.91.29"),
make(<icmp-frame>,
@@ -534,6 +537,7 @@
payload: parse-frame(<raw-frame>, as(<byte-vector>, #(#x23, #x42, #x0, #x0)))));
format-out("Mac 192.168.2.1: %=\n", element(arp-handler.arp-table, ipv4-address("192.168.2.1"), default: #f));
+*/
ip-layer;
end;
Modified: trunk/libraries/layer/layer.hdp
==============================================================================
--- trunk/libraries/layer/layer.hdp (original)
+++ trunk/libraries/layer/layer.hdp Thu Oct 26 22:31:19 2006
@@ -4,3 +4,4 @@
cidr
layer
tcp
+ udp
\ No newline at end of file
Modified: trunk/libraries/layer/tcp.dylan
==============================================================================
--- trunk/libraries/layer/tcp.dylan (original)
+++ trunk/libraries/layer/tcp.dylan Thu Oct 26 22:31:19 2006
@@ -395,7 +395,7 @@
process-event-locked(tcp-connection, #"close")
end;
-define open generic listen-port (t :: <tcp-listener-socket>) => (res :: <integer>);
+define open generic listen-port (t :: <object>) => (res :: <integer>);
define open generic connections (t :: <tcp-listener-socket>) => (res :: <deque>);
define open generic listener-lock (t :: <tcp-listener-socket>) => (res :: <lock>);
@@ -473,27 +473,4 @@
end;
-begin
- let ip-layer = init-ethernet();
- let tcp = make(<tcp-layer>, ip-layer: ip-layer, default-ip-address: ip-layer.default-ip-address);
- let s = create-client-socket(tcp, ipv4-address("213.73.91.29"), 80);
- write(s, "GET / HTTP/1.1\r\nHost: www.ccc.de\r\nConnection: keep-alive\r\n\r\n");
- block(ret)
- while (#t)
- let res = read(s, 20, on-end-of-stream: #f);
- //if (res)
- //format-out("Read %s\n", map-as(<string>, curry(as, <character>), res))
- //else
- close(s);
- ret();
- //end;
- end;
- end;
- let ss = create-server-socket(tcp, 23);
- while (#t)
- let conn = accept(ss);
- write(conn, "fnord");
- close(conn);
- end;
- sleep(1000);
-end;
+
Added: trunk/libraries/layer/udp.dylan
==============================================================================
--- (empty file)
+++ trunk/libraries/layer/udp.dylan Thu Oct 26 22:31:19 2006
@@ -0,0 +1,74 @@
+module: layer
+
+define class <udp-layer> (<layer>)
+ constant slot ip-layer :: <ip-layer>, required-init-keyword: ip-layer:;
+ slot ip-send-socket :: <ip-socket>;
+end;
+
+define method initialize (layer :: <udp-layer>,
+ #next next-method, #rest rest, #key, #all-keys)
+ next-method();
+ let socket = create-socket(layer.ip-layer, 17);
+ connect(socket.decapsulator, layer.demultiplexer);
+ layer.ip-send-socket := socket;
+end;
+
+define class <udp-socket> (<socket>)
+ constant slot listen-port :: <integer>, required-init-keyword: port:;
+ constant slot listen-address :: false-or(<ipv4-address>), init-keyword: address:;
+end;
+
+define method create-socket (layer :: <udp-layer>, port :: <integer>, #key address)
+ => (socket :: <udp-socket>)
+ let socket = make(<udp-socket>, port: port, address: address);
+ let template-frame = make(<udp-frame>, source-port: port);
+ socket.completer := make(<completer>, template-frame: template-frame);
+ socket.demultiplexer-output
+ := create-output-for-filter(layer.demultiplexer,
+ format-to-string("udp.destination-port = %d", port));
+ connect(socket.demultiplexer-output, socket.decapsulator);
+ connect(socket.completer, layer.fan-in);
+ socket;
+end;
+
+define method send (socket :: <udp-socket>, destination :: <ipv4-address>, payload :: <container-frame>);
+end;
+
+begin
+ let ip-layer = init-ethernet();
+ let udp = make(<udp-layer>, ip-layer: ip-layer);
+ let socket = create-socket(udp, 53);
+ connect(socket.decapsulator, make(<verbose-printer>, stream: *standard-output*));
+ send(udp.ip-send-socket,
+ ipv4-address("141.1.1.1"),
+ make(<udp-frame>, source-port: 53, destination-port: 53,
+ payload: make(<dns-frame>,
+ questions: vector(make(<dns-question>,
+ question-type: 1, // A
+ question-class: 1, // THE INTERNET
+ domainname: as(<domain-name>, "www.ccc.de"))))));
+ sleep(10000);
+/*
+ let tcp = make(<tcp-layer>, ip-layer: ip-layer, default-ip-address: ip-layer.default-ip-address);
+ let s = create-client-socket(tcp, ipv4-address("213.73.91.29"), 80);
+ write(s, "GET / HTTP/1.1\r\nHost: www.ccc.de\r\nConnection: keep-alive\r\n\r\n");
+ block(ret)
+ while (#t)
+ let res = read(s, 20, on-end-of-stream: #f);
+ //if (res)
+ //format-out("Read %s\n", map-as(<string>, curry(as, <character>), res))
+ //else
+ close(s);
+ ret();
+ //end;
+ end;
+ end;
+ let ss = create-server-socket(tcp, 23);
+ while (#t)
+ let conn = accept(ss);
+ write(conn, "fnord");
+ close(conn);
+ end;
+ sleep(1000);
+*/
+end;
Modified: trunk/libraries/packetizer/dns.dylan
==============================================================================
--- trunk/libraries/packetizer/dns.dylan (original)
+++ trunk/libraries/packetizer/dns.dylan Thu Oct 26 22:31:19 2006
@@ -6,15 +6,15 @@
define protocol dns-frame (container-frame)
summary "DNS ID=%=, %= questions, %= answers",
identifier, question-count, answer-count;
- field identifier :: <2byte-big-endian-unsigned-integer>;
- field query-or-response :: <1bit-unsigned-integer> = 1;
- field opcode :: <4bit-unsigned-integer>;
- field authoritative-answer :: <1bit-unsigned-integer>;
+ field identifier :: <2byte-big-endian-unsigned-integer> = 2342;
+ field query-or-response :: <1bit-unsigned-integer> = 0;
+ field opcode :: <4bit-unsigned-integer> = 0;
+ field authoritative-answer :: <1bit-unsigned-integer> = 0;
field truncation :: <1bit-unsigned-integer> = 0;
field recursion-desired :: <1bit-unsigned-integer> = 1;
field recursion-available :: <1bit-unsigned-integer> = 0;
field reserved :: <3bit-unsigned-integer> = 0;
- field response-code :: <4bit-unsigned-integer>;
+ field response-code :: <4bit-unsigned-integer> = 0;
field question-count :: <2byte-big-endian-unsigned-integer>,
fixup: frame.questions.size;
field answer-count :: <2byte-big-endian-unsigned-integer>,
@@ -45,8 +45,15 @@
reduce1(method(a, b) concatenate(a, ".", b) end, strings);
end;
+define method as (class == <domain-name>, string :: <string>)
+ => (res :: <domain-name>)
+ let labels = split(string, '.');
+ labels := concatenate(labels, #(""));
+ make(<domain-name>, fragment: map(curry(as, <label>), labels));
+end;
+
define protocol domain-name-fragment (container-frame)
- field type-code :: <2bit-unsigned-integer>;
+ field type-code :: <2bit-unsigned-integer> = 0;
end;
define protocol label-offset (domain-name-fragment)
@@ -94,8 +101,17 @@
res;
end;
+define method as (class == <externally-delimited-string>, string :: <string>)
+ => (res :: <externally-delimited-string>)
+ let res = make(<externally-delimited-string>,
+ data: make(<byte-sequence>, capacity: string.size));
+ copy-bytes(string, 0, res.data, 0, string.size);
+ res;
+end;
+
define protocol label (domain-name-fragment)
- field length :: <6bit-unsigned-integer>;
+ field length :: <6bit-unsigned-integer>,
+ fixup: frame.raw-data.frame-size.byte-offset;
field raw-data :: <externally-delimited-string>,
length: frame.length * 8;
end;
@@ -105,6 +121,11 @@
as(<string>, label.raw-data);
end;
+define method as (class == <label>, string :: <string>)
+ => (res :: <label>)
+ make(<label>, raw-data: as(<externally-delimited-string>, string))
+end;
+
define method parse-frame (frame-type == <domain-name-fragment>,
packet :: <byte-sequence>,
#next next-method,
@@ -124,15 +145,16 @@
define protocol dns-question (container-frame)
field domainname :: <domain-name>;
field question-type :: <2byte-big-endian-unsigned-integer>;
- field question-class :: <2byte-big-endian-unsigned-integer>;
+ field question-class :: <2byte-big-endian-unsigned-integer> = 1;
end;
define protocol dns-resource-record (container-frame)
field domainname :: <domain-name>;
field rr-type :: <2byte-big-endian-unsigned-integer>;
- field rr-class :: <2byte-big-endian-unsigned-integer>;
+ field rr-class :: <2byte-big-endian-unsigned-integer> = 1;
field ttl :: <big-endian-unsigned-integer-4byte>;
- field rdlength :: <2byte-big-endian-unsigned-integer>;
+ field rdlength :: <2byte-big-endian-unsigned-integer>,
+ fixup: frame.rdata.frame-size.byte-offset;
variably-typed-field rdata,
type-function: select (frame.rr-type)
1 => <a-host-address>;
Modified: trunk/libraries/packetizer/fields.dylan
==============================================================================
--- trunk/libraries/packetizer/fields.dylan (original)
+++ trunk/libraries/packetizer/fields.dylan Thu Oct 26 22:31:19 2006
@@ -105,6 +105,7 @@
end;
define abstract class <repeated-field> (<statically-typed-field>)
+ inherited slot init-value = #(), init-keyword: init-value:;
end;
define class <self-delimited-repeated-field> (<repeated-field>)
Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan (original)
+++ trunk/libraries/packetizer/module.dylan Thu Oct 26 22:31:19 2006
@@ -20,6 +20,8 @@
<out-of-bound-error>,
encode-integer, decode-integer;
+ export <dns-frame>, <dns-question>, <domain-name>;
+
export <udp-frame>, source-port, destination-port, length, checksum;
export <tcp-frame>, sequence-number, acknowledgement-number,
Modified: trunk/libraries/packetizer/protocol-definer-macro.dylan
==============================================================================
--- trunk/libraries/packetizer/protocol-definer-macro.dylan (original)
+++ trunk/libraries/packetizer/protocol-definer-macro.dylan Thu Oct 26 22:31:19 2006
@@ -162,7 +162,7 @@
=> { slot ?name :: false-or(<frame>) = #f,
init-keyword: ?#"name" }
{ repeated field ?:name ?rest:* }
- => { slot ?name :: false-or(<stretchy-vector>) = #f,
+ => { slot ?name :: false-or(<collection>) = #f,
init-keyword: ?#"name" }
end;
More information about the chatter
mailing list