[Gd-chatter] r11689 - in trunk/libraries: network/ip-stack/layers/physical/linux-live-interface registry/generic registry/x86-linux registry/x86-win32
hannes at gwydiondylan.org
hannes at gwydiondylan.org
Wed Feb 20 04:04:31 CET 2008
Author: hannes
Date: Wed Feb 20 04:04:30 2008
New Revision: 11689
Added:
trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/
trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/library.dylan (contents, props changed)
trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.dylan (contents, props changed)
trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.lid (contents, props changed)
trunk/libraries/registry/x86-linux/pcap-live-interface (contents, props changed)
trunk/libraries/registry/x86-win32/pcap-live-interface
- copied unchanged from r11688, trunk/libraries/registry/generic/pcap-live-interface
Removed:
trunk/libraries/registry/generic/pcap-live-interface
Log:
Job: 7299
* provide a new physical layer for linux
Added: trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/library.dylan
==============================================================================
--- (empty file)
+++ trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/library.dylan Wed Feb 20 04:04:30 2008
@@ -0,0 +1,42 @@
+module: dylan-user
+
+define library pcap-live-interface
+ use common-dylan;
+ use layer;
+ use physical-layer;
+ use c-ffi;
+ use network;
+ use system;
+ use io;
+ use collection-extensions;
+ use functional-dylan;
+ use flow;
+ use network;
+ use packetizer;
+ use protocols, import: { ethernet, prism2, ieee80211 };
+end;
+
+define module pcap-live-interface
+ use common-dylan, exclude: { format-to-string, close };
+ use new-layer;
+ use physical-layer;
+ use dylan-extensions;
+ use threads;
+ use common-extensions, exclude: { format-to-string, close };
+ use format-out, exclude: { close };
+ use subseq;
+ use format;
+ use standard-io;
+ use functional-dylan, import: { <byte-character> };
+ use dylan-extensions, import: { <byte> };
+ use unix-sockets, exclude: { send, connect };
+ use sockets, import: { interruptible-system-call };
+ use C-FFI;
+ use dylan-direct-c-ffi;
+ use flow;
+ use packetizer, import: { parse-frame, assemble-frame, packet };
+ use ethernet, import: { <ethernet-frame> };
+ use ieee80211, import: { <ieee80211-frame> };
+ use prism2, import: { <prism2-frame>, <bsd-80211-radio-frame> };
+
+end;
Added: trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.dylan
==============================================================================
--- (empty file)
+++ trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.dylan Wed Feb 20 04:04:30 2008
@@ -0,0 +1,184 @@
+module: pcap-live-interface
+Author: Andreas Bogk, Hannes Mehnert
+Copyright: (C) 2005, 2006, 2008, All rights reserved. Free for non-commercial use.
+
+define class <packet-flow-node> (<filter>)
+ slot unix-file-descriptor :: <integer>;
+end class;
+
+define constant $ethernet-buffer-size :: <integer> = 1548;
+define constant <buffer> = <byte-vector>;
+
+define layer phy (<physical-layer>)
+ property administrative-state :: <symbol> = #"down";
+ property promiscuous? :: <boolean> = #t;
+ system property running-state :: <symbol> = #"down";
+ system property device-name :: <string>;
+ slot packet-flow-node :: <packet-flow-node>;
+end;
+
+define method create-raw-socket (phy :: <phy-layer>) => (res :: <node>)
+ phy.packet-flow-node
+end;
+
+define method initialize-layer (layer :: <phy-layer>,
+ #key, #all-keys)
+ => ()
+ layer.packet-flow-node := make(<packet-flow-node>);
+ register-c-dylan-object(layer.packet-flow-node);
+ register-property-changed-event(layer, #"administrative-state",
+ toggle-administrative-state);
+end;
+
+define function toggle-administrative-state (event :: <property-changed-event>)
+ => ();
+ let property = event.property-changed-event-property;
+ let layer = property.property-owner;
+ if (property.property-value == #"up")
+ make(<thread>, function: curry(run-interface, layer));
+ else
+ layer. at running-state := #"down";
+ end;
+end;
+
+define method push-data-aux (input :: <push-input>,
+ node :: <packet-flow-node>,
+ frame :: <ethernet-frame>)
+ send(node.unix-file-descriptor,
+ as(<byte-vector>, assemble-frame(frame).packet));
+end;
+
+define function run-interface (layer :: <phy-layer>)
+ block(return)
+ let node = layer.packet-flow-node;
+ let handle = socket($PF-PACKET, $SOCK-RAW, htons($ETH-P-ALL));
+ if (handle == -1)
+ layer. at running-state := #"error";
+ return();
+ end;
+ node.unix-file-descriptor := handle;
+
+ with-stack-structure (ifreq :: <ifreq*>)
+ ifreq.ifr-name := layer. at device-name;
+ let res = ioctl(node.unix-file-descriptor, $SIOCGIFFLAGS, ifreq);
+ if (res == -1)
+ layer. at running-state := #"error";
+ return();
+ else
+ ifreq.ifr-flags := logior(ifreq.ifr-flags,
+ logior($IFF-UP, if (layer. at promiscuous?)
+ $IFF-PROMISC
+ else
+ 0
+ end));
+ let result = ioctl(node.unix-file-descriptor, $SIOCSIFFLAGS, ifreq);
+ if (result == -1)
+ layer. at running-state := #"error";
+ return();
+ end if;
+ end if;
+ end with-stack-structure;
+
+ with-stack-structure (sockaddr :: <sockaddr-ll*>)
+ sockaddr.sll-family := $AF-PACKET;
+ sockaddr.sll-protocol := htons($ETH-P-ALL);
+ sockaddr.sll-ifindex := name-to-index(node.unix-file-descriptor,
+ layer. at device-name);
+ if (bind(node.unix-file-descriptor, sockaddr, size-of(<sockaddr-ll>)) == -1)
+ layer. at running-state := #"error";
+ return();
+ end if;
+ end;
+ layer. at running-state := #"up";
+
+ while(layer. at running-state == #"up")
+ let (packet, type-code) = receive(node);
+ let type = select (type-code)
+ 1 => <ethernet-frame>;
+ 801 => <ieee80211-frame>;
+ 802 => <prism2-frame>;
+ 803 => <bsd-80211-radio-frame>;
+ end;
+ block()
+ let frame = parse-frame(type, packet);
+ push-data(node.the-output, frame);
+ exception (e :: <error>)
+ //format-out("Incoming packet broken beyond repair\n");
+ end
+ end while;
+ close(node.unix-file-descriptor);
+ end;
+end;
+
+define function name-to-index (socket, name)
+ with-stack-structure (ifreq :: <ifreq*>)
+ ifreq.ifr-name := name;
+ let rc = ioctl(socket, $SIOCGIFINDEX, ifreq);
+ if (rc == -1)
+ error("Error binding to interface %s\n", name);
+ end if;
+ ifreq.ifr-ifindex;
+ end with-stack-structure;
+end function name-to-index;
+
+define function start-packet ()
+ let packet-socket = socket($PF-PACKET, $SOCK-RAW, htons($ETH-P-ALL));
+ with-stack-structure (ifreq :: <ifreq*>)
+ for (i from 0 below 256)
+ ifreq.ifr-ifindex := i;
+ if (ioctl(packet-socket, $SIOCGIFNAME, ifreq) >= 0)
+ make(<phy-layer>, device-name: as(<byte-string>, ifreq.ifr-name));
+ end;
+ end;
+ end;
+ close(packet-socket);
+end;
+
+define method receive (interface :: <packet-flow-node>)
+ => (buffer, type)
+ let buffer = make(<buffer>, size: $ethernet-buffer-size);
+ local method unix-receive ()
+ with-stack-structure (sockaddr :: <sockaddr-ll*>)
+ with-stack-structure (sockaddr-size :: <socklen-t*>)
+ pointer-value(sockaddr-size) := size-of(<sockaddr-ll>);
+ let fd = interface.unix-file-descriptor;
+ let read-bytes =
+ interruptible-system-call(unix-recv-buffer-from(fd,
+ buffer-offset(buffer, 0),
+ $ethernet-buffer-size,
+ 0,
+ sockaddr,
+ sockaddr-size));
+ if (read-bytes == -1)
+ //Only want to catch $EINTR, but getting mps assertion failures
+ //this is now done via interruptible-system-call macro
+ #f;
+ else
+ values(subsequence(buffer, end: read-bytes), sockaddr.sll-hatype);
+ end if;
+ end
+ end
+ end method;
+ unix-receive();
+end method receive;
+
+define method send (interface :: <integer>, buffer :: <buffer>)
+ unix-send-buffer(interface,
+ buffer-offset(buffer, 0),
+ buffer.size,
+ 0);
+end method send;
+
+define function buffer-offset
+ (the-buffer :: <buffer>, data-offset :: <integer>)
+ => (result-offset :: <machine-word>)
+ u%+(data-offset,
+ primitive-wrap-machine-word
+ (primitive-repeated-slot-as-raw
+ (the-buffer, primitive-repeated-slot-offset(the-buffer))))
+end function;
+
+
+begin
+ register-startup-function(start-packet);
+end;
\ No newline at end of file
Added: trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.lid
==============================================================================
--- (empty file)
+++ trunk/libraries/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.lid Wed Feb 20 04:04:30 2008
@@ -0,0 +1,3 @@
+library: pcap-live-interface
+files: library
+ linux-live-interface
\ No newline at end of file
Added: trunk/libraries/registry/x86-linux/pcap-live-interface
==============================================================================
--- (empty file)
+++ trunk/libraries/registry/x86-linux/pcap-live-interface Wed Feb 20 04:04:30 2008
@@ -0,0 +1 @@
+abstract://dylan/network/ip-stack/layers/physical/linux-live-interface/linux-live-interface.lid
\ No newline at end of file
More information about the chatter
mailing list