[Gd-chatter] r11475 - in trunk/libraries: layer packetizer protocols

hannes at gwydiondylan.org hannes at gwydiondylan.org
Sun Oct 28 05:44:00 CET 2007


Author: hannes
Date: Sun Oct 28 05:43:59 2007
New Revision: 11475

Modified:
   trunk/libraries/layer/dhcp.dylan
   trunk/libraries/layer/layer.dylan
   trunk/libraries/layer/udp.dylan
   trunk/libraries/packetizer/fields.dylan
   trunk/libraries/packetizer/module.dylan
   trunk/libraries/packetizer/packetizer.dylan
   trunk/libraries/protocols/protocols-library.dylan
Log:
Job: 7299
*packetizer: fix assembly when static-length is provided

*layer: fix udp layer to actually send packets
*layer: broadcast-support
*dhcp: actually do a complete dhcp-handshake

Modified: trunk/libraries/layer/dhcp.dylan
==============================================================================
--- trunk/libraries/layer/dhcp.dylan	(original)
+++ trunk/libraries/layer/dhcp.dylan	Sun Oct 28 05:43:59 2007
@@ -13,6 +13,7 @@
       if (message-type-frame.message-type = 2)
         node.offer := frame;
         process-event(node, #"receive-offer");
+        process-event(node, #"send-request");
       end;
     end;
   end;
@@ -21,7 +22,7 @@
     if (frame.operation = 2)
       if (message-type-frame.message-type = 5) //ack
         process-event(node, #"receive-ack");
-        format-out("received ack %=\n", frame);
+        format-out("received ack %s\n", as(<string>, frame));
       elseif (message-type-frame.message-type = 6) //nak
         process-event(node, #"receive-nak")
       end
@@ -73,22 +74,23 @@
                     dhcp-options: list(make(<dhcp-message-type-option>,
                                             message-type: 3),
                                        make(<dhcp-requested-ip-address-option>,
-                                            requested-ip: offer.your-ip-address),
+                                            requested-ip: state.offer.your-ip-address),
                                        make(<dhcp-server-identifier-option>,
-                                            selected-server: server-option.server-ip-address)));
+                                            selected-server: server-option.selected-server)));
   send(state.send-socket, $broadcast-address, packet);
 //
 end;
 
 
 define method main()
-  let eth = build-ethernet-layer("ath0", promiscuous?: #t);
+  let eth = build-ethernet-layer("Intel", promiscuous?: #t);
   let ip-layer = build-ip-layer(eth);
   let udp = make(<udp-layer>, ip-layer: ip-layer);
-  let socket = create-socket(udp, 67);
+  let socket = create-socket(udp, 67, client-port: 68);
   let dhcp = make(<dhcp-client>, send-socket: socket);
   connect(socket.decapsulator, dhcp);
   process-event(dhcp, #"send-discover");
+  sleep(10000);
 end;
 
-//main();
\ No newline at end of file
+//main();

Modified: trunk/libraries/layer/layer.dylan
==============================================================================
--- trunk/libraries/layer/layer.dylan	(original)
+++ trunk/libraries/layer/layer.dylan	Sun Oct 28 05:43:59 2007
@@ -180,13 +180,13 @@
   constant slot ip-layer :: <ip-layer>, required-init-keyword: ip-layer:;
   constant slot ethernet-layer :: <ethernet-layer>, required-init-keyword: ethernet:;
   constant slot arp-handler :: <arp-handler>, required-init-keyword: arp:;
-  constant slot v4-address :: <ipv4-address>, required-init-keyword: ipv4-address:;
-  constant slot netmask :: <integer>, required-init-keyword: netmask:;
+  slot v4-address :: <ipv4-address>, required-init-keyword: ipv4-address:;
+  slot netmask :: <integer>, required-init-keyword: netmask:;
   slot ip-send-socket :: <ethernet-socket>;
 end;
 
 define method send (socket :: <ip-over-ethernet-adapter>, destination :: <ipv4-address>, payload :: <container-frame>);
-  if (broadcast-address(make(<cidr>, network-address: socket.v4-address, netmask: socket.netmask)) = destination)
+  if (destination = broadcast-address(make(<cidr>, network-address: socket.v4-address, netmask: socket.netmask)))
     send(socket.ip-send-socket, $broadcast-ethernet-address, payload);
   else
     let arp-entry = element(socket.arp-handler.arp-table, destination, default: #f);
@@ -241,11 +241,12 @@
 
   ip-over-ethernet.arp-handler.send-socket := arp-socket;
 
-  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);
-
+  unless (ip-over-ethernet.v4-address = ipv4-address("0.0.0.0"))
+    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;
 
   let ip-socket = create-socket(ip-over-ethernet.ethernet-layer, #x800);
   let ip-broadcast-socket = create-socket(ip-over-ethernet.ethernet-layer,
@@ -386,7 +387,8 @@
                             let (adapter, next-hop)
                               = find-adapter-for-forwarding(ip-layer, x.destination-address);
                             /* let mtu = find-mtu-for-destination(adapter, x.destination-address) * 8;
-                            let full-payload = assemble-frame(x.payload).packet;
+                            let unparsed-ip = assemble-frame(x);
+                            let full-payload = unparsed-ip.payload.packet;
                             let data-size = frame-size(x.payload);
                             if (mtu < data-size)
                               x.more-fragments := 1;
@@ -403,9 +405,9 @@
                             x.payload := parse-frame(<raw-frame>, subsequence(full-payload,
                                                                               start: x.fragment-offset * 8 * 8,
                                                                               length: modulo(data-size, mtu)));
-                            x.total-length := #f;
-                            let ip-frame = assemble-frame(x);
-                            fixup!(ip-frame); */
+                            x.total-length := #f; */
+                            //let ip-frame = assemble-frame(x);
+                            //fixup!(ip-frame);
                             send(adapter, next-hop, x);
                           end);
   connect(ip-layer.fan-in, cls);
@@ -488,8 +490,12 @@
                            template-frame: template-frame);
   socket.demultiplexer-output
     := create-output-for-filter(ip-layer.demultiplexer,
-                                format-to-string("(ipv4.destination-address = %s) & (ipv4.protocol = %s)",
-                                                 source-address, protocol));
+                                if (source-address = ipv4-address("0.0.0.0"))
+                                  format-to-string("ipv4.protocol = %s", protocol);
+                                else
+                                  format-to-string("(ipv4.destination-address = %s) & (ipv4.protocol = %s)",
+                                                   source-address, protocol)
+                                end);
   connect(socket.demultiplexer-output, socket.decapsulator);
   connect(socket.completer, ip-layer.fan-in);
   socket;
@@ -705,9 +711,9 @@
                                     
 
 define function build-ip-layer (ethernet-layer,
-                               #key ip-address :: <ipv4-address> = ipv4-address("192.168.0.69"),
-                               default-gateway :: <ipv4-address> = ipv4-address("192.168.0.1"),
-                               netmask :: <integer> = 24)
+                               #key ip-address :: false-or(<ipv4-address>),
+                               default-gateway :: false-or(<ipv4-address>),
+                               netmask :: <integer> = 0)
   let arp-handler = make(<arp-handler>);
   arp-handler.arp-table[ipv4-address("255.255.255.255")]
     := make(<static-arp-entry>,
@@ -718,12 +724,16 @@
                               ethernet: ethernet-layer,
                               arp: arp-handler,
                               ip-layer: ip-layer,
-                              ipv4-address: ip-address,
+                              ipv4-address: ip-address | ipv4-address("0.0.0.0"),
                               netmask: netmask);
-  register-route(ip-layer, make(<next-hop-route>,
-                                next-hop: default-gateway,
-                                cidr: make(<cidr>, network-address: ipv4-address("0.0.0.0"), netmask: 0)));
-  send-gratitious-arp(arp-handler, ip-address);
+  if (default-gateway)
+    register-route(ip-layer, make(<next-hop-route>,
+                                  next-hop: default-gateway,
+                                  cidr: make(<cidr>, network-address: ipv4-address("0.0.0.0"), netmask: 0)));
+  end;
+  if (ip-address)
+    send-gratitious-arp(arp-handler, ip-address);
+  end;
   //let icmp-handler = make(<icmp-handler>);
   //let icmp-over-ip = make(<icmp-over-ip-adapter>,
   //                        ip-layer: ip-layer,

Modified: trunk/libraries/layer/udp.dylan
==============================================================================
--- trunk/libraries/layer/udp.dylan	(original)
+++ trunk/libraries/layer/udp.dylan	Sun Oct 28 05:43:59 2007
@@ -14,28 +14,42 @@
 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:;
+  constant slot udp-layer :: <udp-layer>, required-init-keyword: layer:;
+  constant slot server-port :: <integer>, required-init-keyword: server-port:;
+  constant slot client-port :: <integer>, required-init-keyword: client-port:;
+  constant slot client-address :: false-or(<ipv4-address>), init-keyword: client-address:;
+  constant slot server-address :: false-or(<ipv4-address>), init-keyword: server-address:;
 end;
 
-define method create-socket (layer :: <udp-layer>, port :: <integer>, #key address)
+define method create-socket (layer :: <udp-layer>,
+                             server-port :: <integer>,
+                             #key client-port,
+                                  client-address,
+                                  server-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);
+  let cport = client-port | random(2 ^ 16 - 1);
+  let socket = make(<udp-socket>,
+                    client-port: cport,
+                    server-port: server-port,
+                    client-address: client-address,
+                    server-address: server-address,
+                    layer: layer);
   socket.demultiplexer-output
     := create-output-for-filter(layer.demultiplexer,
-                                format-to-string("udp.destination-port = %d", port));
+                                format-to-string("udp.destination-port = %d", cport));
   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>);
-  //push-data-aux(socket.completer.the-input, socket.completer, payload)
-end;                                  
+  let udp = make(<udp-frame>,
+                 payload: payload,
+                 source-port: socket.client-port,
+                 destination-port: socket.server-port);
+  send(socket.udp-layer.ip-send-socket, destination, udp);
+end;
 
 define function udp-begin()
   let ip-layer = init-ip-layer();

Modified: trunk/libraries/packetizer/fields.dylan
==============================================================================
--- trunk/libraries/packetizer/fields.dylan	(original)
+++ trunk/libraries/packetizer/fields.dylan	Sun Oct 28 05:43:59 2007
@@ -104,7 +104,11 @@
 end;
 
 define method static-field-size (field :: <single-field>) => (res :: <integer-or-unknown>)
-  field.type.field-size
+  if (field.static-length ~= $unknown-at-compile-time)
+    field.static-length
+  else
+    field.type.field-size
+  end
 end;
 
 define class <variably-typed-field> (<field>)

Modified: trunk/libraries/packetizer/module.dylan
==============================================================================
--- trunk/libraries/packetizer/module.dylan	(original)
+++ trunk/libraries/packetizer/module.dylan	Sun Oct 28 05:43:59 2007
@@ -17,7 +17,7 @@
   export <stretchy-vector-subsequence>,
     <stretchy-byte-vector-subsequence>,
     subsequence,
-    start-index,
+    start-index, end-index,
     <out-of-bound-error>,
     encode-integer, decode-integer;
 

Modified: trunk/libraries/packetizer/packetizer.dylan
==============================================================================
--- trunk/libraries/packetizer/packetizer.dylan	(original)
+++ trunk/libraries/packetizer/packetizer.dylan	Sun Oct 28 05:43:59 2007
@@ -486,13 +486,6 @@
     end;
     let length = offset + assemble-field-into(field, frame, subsequence(packet, start: offset));
     frame.concrete-frame-fields[field.index].%start-offset := offset;
-    if (instance?(field.getter(frame), <decoded-container-frame>))
-      let unparsed = make(unparsed-class(field.getter(frame).object-class),
-                          cache: field.getter(frame),
-                          packet: subsequence(packet, start: offset, length: length),
-                          parent: frame);
-      field.setter(unparsed, frame);
-    end;
     if (field.dynamic-end)
       let real-frame-end = field.dynamic-end(frame);
       if (real-frame-end ~= length)
@@ -502,10 +495,21 @@
       end;
       length := real-frame-end;
     end;
+    if ((field.static-length ~= $unknown-at-compile-time) & (field.static-length + offset ~= length))
+      length := offset + field.static-length;
+    end;
     if ((field.static-end ~= $unknown-at-compile-time) & (field.static-end ~= length))
       //format-out("Need static padding at end of %s : %d ~= %d\n",
       //           field.field-name, field.static-end, length);
-      offset := field.static-end;
+      length := field.static-end;
+    end;
+    frame.concrete-frame-fields[field.index].%end-offset := length;
+    if (instance?(field.getter(frame), <decoded-container-frame>))
+      let unparsed = make(unparsed-class(field.getter(frame).object-class),
+                          cache: field.getter(frame),
+                          packet: subsequence(packet, start: offset, length: length),
+                          parent: frame);
+      field.setter(unparsed, frame);
     end;
     offset := length;
   end;
@@ -713,7 +717,11 @@
                                       field :: <single-field>,
                                       frame-type :: subclass(<variable-size-untranslated-frame>))
  => (res :: <integer>)
-  frame-size(field.getter(frame))
+  if (field.static-length ~= $unknown-at-compile-time)
+    field.static-length
+  else
+    frame-size(field.getter(frame))
+  end
 end;
 
 define method get-field-size-aux-aux (frame :: <frame>,

Modified: trunk/libraries/protocols/protocols-library.dylan
==============================================================================
--- trunk/libraries/protocols/protocols-library.dylan	(original)
+++ trunk/libraries/protocols/protocols-library.dylan	Sun Oct 28 05:43:59 2007
@@ -313,7 +313,7 @@
 define module dhcp
   use common-dylan;
   use packetizer;
-  use ipv4, import: { <ipv4-address>, <udp-frame>, ipv4-address };
+  use ipv4, import: { <ipv4-address>, <udp-frame>, ipv4-address, operation };
   export <dhcp-message>,
     <dhcp-message-type-option>,
     <dhcp-requested-ip-address-option>,
@@ -321,7 +321,8 @@
     message-type,
     dhcp-options,
     your-ip-address,
-    server-ip-address;
+    server-ip-address,
+    selected-server;
 end;
 
 define module dns



More information about the chatter mailing list