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 {
ipv4 :: Client m IPv4.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)
case t of
IPv4 -> conv toIPv4
ARP -> conv toARP
_ -> debug $ show t++" packet dropped"
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}