module Hans (
NetworkStack(), Config(..), defaultConfig,
newNetworkStack,
processPackets,
DeviceName,
Device(), DeviceConfig(..), defaultDeviceConfig,
addDevice,
listDevices,
closeDevice,
startDevice,
Addr(), sameFamily,
NetworkAddr(..),
Network(..),
RouteInfo(..),
IP4.IP4(), IP4.packIP4, IP4.unpackIP4,
IP4.IP4Mask(..),
IP4.Route(..), IP4.RouteType(Direct,Indirect),
addIP4Route,
) where
import Hans.Addr (NetworkAddr(..),Addr(),sameFamily)
import Hans.Config
import Hans.Device
import Hans.Device.Loopback
import qualified Hans.IP4.State as IP4
import qualified Hans.IP4.Packet as IP4
import qualified Hans.IP4.RoutingTable as IP4 (Route(..),RouteType(..))
import qualified Hans.IP4.Output as IP4 (responder)
import Hans.Input
import Hans.Network
import Hans.Threads (forkNamed)
import Hans.Types
import qualified Hans.Tcp.Output as Tcp (responder)
import qualified Hans.Tcp.Timers as Tcp
import qualified Hans.Udp.Output as Udp (responder)
import Control.Concurrent.BoundedChan (newBoundedChan)
import Data.IORef (newIORef,atomicModifyIORef')
#ifdef HANS_TARGET_XEN
import Hypervisor.XenStore (XenStore)
#endif
newNetworkStack :: Config -> IO NetworkStack
newNetworkStack nsConfig =
do nsInput <- newBoundedChan (cfgInputQueueSize nsConfig)
nsNat <- newNatState nsConfig
nsDevices <- newIORef []
nsIP4State <- newIP4State nsConfig
nsUdpState <- newUdpState nsConfig
nsTcpState <- newTcpState nsConfig
nsNameServers4 <- newIORef []
rec nsIP4Responder <- forkNamed "IP4.responder" (IP4.responder ns)
nsTcpTimers <- forkNamed "Tcp.tcpTimers" (Tcp.tcpTimers ns)
nsTcpResponder <- forkNamed "Tcp.responder" (Tcp.responder ns)
nsUdpResponder <- forkNamed "Udp.responder" (Udp.responder ns)
let ns = NetworkStack { .. }
registerLoopback ns
return ns
registerLoopback :: NetworkStack -> IO ()
registerLoopback ns =
do lo <- newLoopbackDevice ns
atomicModifyIORef' (nsDevices ns) (\devs -> (lo : devs, ()))
addIP4Route ns False
IP4.Route { routeNetwork = IP4.IP4Mask (IP4.packIP4 127 0 0 1) 8
, routeType = IP4.Direct
, routeDevice = lo }
#ifdef HANS_TARGET_XEN
addDevice :: XenStore -> NetworkStack -> DeviceName -> DeviceConfig -> IO Device
addDevice xs ns devName devConfig =
do dev <- openDevice xs ns devName devConfig
atomicModifyIORef' (nsDevices ns) (\devs -> (dev : devs, ()))
return dev
#else
addDevice :: NetworkStack -> DeviceName -> DeviceConfig -> IO Device
addDevice ns devName devConfig =
do dev <- openDevice ns devName devConfig
atomicModifyIORef' (nsDevices ns) (\devs -> (dev : devs, ()))
return dev
#endif
addIP4Route :: NetworkStack -> Bool -> IP4.Route -> IO ()
addIP4Route NetworkStack { .. } = IP4.addRoute nsIP4State