module Hans.Network (
module Hans.Network,
module Hans.Network.Types
) where
import Hans.Addr (NetworkAddr)
import Hans.Addr.Types (Addr(..))
import Hans.Checksum (PartialChecksum)
import Hans.Device.Types (Device)
import qualified Hans.IP4 as IP4
import qualified Hans.IP4.State as IP4
import Hans.Lens
import Hans.Network.Types
import Hans.Types
import qualified Data.ByteString.Lazy as L
class NetworkAddr addr => Network addr where
pseudoHeader :: addr -> addr -> NetworkProtocol -> Int -> PartialChecksum
lookupRoute :: HasNetworkStack ns => ns -> addr -> IO (Maybe (RouteInfo addr))
sendDatagram' :: HasNetworkStack ns
=> ns
-> Device
-> addr
-> addr
-> addr
-> Bool
-> NetworkProtocol
-> L.ByteString
-> IO ()
sendDatagram :: (HasNetworkStack ns, Network addr)
=> ns -> RouteInfo addr -> addr
-> Bool -> NetworkProtocol -> L.ByteString
-> IO ()
sendDatagram ns RouteInfo { .. } = \ dst ->
sendDatagram' ns riDev riSource dst riNext
routeDatagram :: (HasNetworkStack ns, Network addr)
=> ns -> addr -> Bool -> NetworkProtocol -> L.ByteString -> IO Bool
routeDatagram ns dst df prot bytes =
do mbRoute <- lookupRoute ns dst
case mbRoute of
Just route -> do sendDatagram ns route dst df prot bytes
return True
Nothing -> return False
findNextHop :: (HasNetworkStack ns, Network addr)
=> ns
-> Maybe Device
-> Maybe addr
-> addr
-> IO (Maybe (RouteInfo addr))
findNextHop ns mbDev mbSrc dst =
do mbRoute <- lookupRoute ns dst
case mbRoute of
Just ri | maybe True (== riDev ri) mbDev
&& maybe True (== riSource ri) mbSrc -> return (Just ri)
_ -> return Nothing
instance Network Addr where
pseudoHeader (Addr4 src) (Addr4 dst) = \ prot len -> pseudoHeader src dst prot len
lookupRoute ns (Addr4 dst) =
do ri <- lookupRoute ns dst
return (fmap (fmap Addr4) ri)
sendDatagram' ns dev (Addr4 src) (Addr4 dst) (Addr4 next) =
sendDatagram' ns dev src dst next
instance Network IP4.IP4 where
pseudoHeader = IP4.ip4PseudoHeader
lookupRoute ns ip4 =
do mb <- IP4.lookupRoute4 (view networkStack ns) ip4
case mb of
Just (riSource,riNext,riDev) -> return $! Just RouteInfo { .. }
Nothing -> return Nothing
sendDatagram' ns dev src dst df next =
IP4.primSendIP4 (view networkStack ns) dev src dst df next