module Net.EthernetClient where import Net.Concurrent(fork) import Net.Ethernet as Eth(Interface(..),Packet,PacketType(..),rx,tx,packType,content) import qualified Net.IPv4 as IPv4(Packet) import qualified Net.ARP as ARP(Packet) import Net.PacketParsing import Net.Wire import qualified Net.Interface as Net import Monad.Util(loop) type Client_ m p = Eth.Interface m p (Packet p) type Client m p = Eth.Interface m (p InPacket) (Packet (p OutPacket)) data Clients m = Clients { -- ethernet, -- unknown :: Client m Packet, ipv4 :: Client m IPv4.Packet, -- ipv6 :: Client m IPv6.Packet, arp :: Client_ m ARP.Packet } initialize debug eth = do Net.Interface{Net.rx=rxIPv4,Net.tx=toIPv4} <- newWire() Net.Interface{Net.rx=rxARP,Net.tx=toARP} <- newWire() let demultiplex = do p <- rx eth let t = packType p conv dest = maybe warning dest (doParse (content p)) warning = debug (show t++" packet parser failed "++show p) --debug (show t++" received") case t of --Ethernet n -> to' ethernet IPv4 -> conv toIPv4 --IPv6 -> return () -- not implemented yet ARP -> conv toARP --Unknown n -> to' unknown _ -> debug $ show t++" packet dropped" --client :: IO (...) -> Net.IOInterface ... ... client rx = eth {io=io} where io = Net.Interface {Net.rx=rx, Net.tx=tx eth . fmap doUnparse} fork $ loop demultiplex return Clients {ipv4 =client rxIPv4, arp=client rxARP} --return (client rxIPv4,client rxARP)