module Network.BSD(
HostName
, getHostName
, HostEntry(..)
, getHostByName
, getHostByAddr
, hostAddress
, getHostEntries
, setHostEntry
, getHostEntry
, endHostEntry
, ServiceEntry(..)
, ServiceName
, getServiceByName
, getServiceByPort
, getServicePortNumber
, getServiceEntries
, getServiceEntry
, setServiceEntry
, endServiceEntry
, ProtocolName
, ProtocolNumber
, ProtocolEntry(..)
, getProtocolByName
, getProtocolByNumber
, getProtocolNumber
, getProtocolEntries
, setProtocolEntry
, getProtocolEntry
, endProtocolEntry
, PortNumber(..)
, NetworkAddr
, NetworkEntry(..)
, getNetworkByName
, getNetworkByAddr
, getNetworkEntries
, setNetworkEntry
, getNetworkEntry
, endNetworkEntry
, ifNameToIndex
)
where
import Control.Exception(throw)
import Data.Typeable(Typeable)
import Foreign.C.Types(CInt, CULong)
import Hans.IP4(packIP4)
import Network.BSD.ServiceDB(ServiceEntry(..), ServiceName, serviceDB)
import Network.Socket.Internal(PortNumber(..), HostAddress, Family(..))
import Network.Socket.Types(fromIP4)
type HostName = String
getHostName :: IO String
getHostName = undefined
data HostEntry = HostEntry {
hostName :: HostName
, hostAliases :: [HostName]
, hostFamily :: Family
, hostAddresses :: [HostAddress]
}
deriving (Read, Show, Typeable)
getHostByName :: HostName -> IO HostEntry
getHostByName = undefined
getHostByAddr :: Family -> HostAddress -> IO HostEntry
getHostByAddr = undefined
hostAddress :: HostEntry -> HostAddress
hostAddress = undefined
getHostEntries :: Bool -> IO [HostEntry]
getHostEntries = undefined
setHostEntry :: Bool -> IO ()
setHostEntry _ = return ()
getHostEntry :: IO HostEntry
getHostEntry = undefined
endHostEntry :: IO ()
endHostEntry = return ()
getServiceByName :: ServiceName -> ProtocolName -> IO ServiceEntry
getServiceByName sn pn = return (go serviceDB)
where
go [] = throw (userError "Service not found.")
go (f:rest)
| nameMatches f && (serviceProtocol f == pn) = f
| otherwise = go rest
nameMatches x = (serviceName x == sn) || (sn `elem` serviceAliases x)
getServiceByPort :: PortNumber -> ProtocolName -> IO ServiceEntry
getServiceByPort po pr = return (go serviceDB)
where
go [] = throw (userError "Service not found.")
go (f:rest)
| (servicePort f == po) && (serviceProtocol f == pr) = f
| otherwise = go rest
getServicePortNumber :: ServiceName -> IO PortNumber
getServicePortNumber sn = return (go serviceDB)
where
go [] = throw (userError "Service not found.")
go (f:rest)
| (serviceName f == sn) || (sn `elem` serviceAliases f) = servicePort f
| otherwise = go rest
getServiceEntries :: Bool -> IO [ServiceEntry]
getServiceEntries _ = return serviceDB
getServiceEntry :: IO ServiceEntry
getServiceEntry = return (head serviceDB)
setServiceEntry :: Bool -> IO ()
setServiceEntry _ = return ()
endServiceEntry :: IO ()
endServiceEntry = return ()
type ProtocolName = String
type ProtocolNumber = CInt
data ProtocolEntry = ProtocolEntry {
protoName :: ProtocolName
, protoAliases :: [ProtocolName]
, protoNumber :: ProtocolNumber
}
deriving (Read, Show, Typeable)
protocolDB :: [ProtocolEntry]
protocolDB = [
ProtocolEntry "udp" ["UDP"] 17
, ProtocolEntry "tcp" ["TCP"] 6
]
getProtocolByName :: ProtocolName -> IO ProtocolEntry
getProtocolByName nm = return (go protocolDB)
where
go [] = throw (userError "Protocol not found")
go (first:rest)
| (protoName first == nm) || (nm `elem` protoAliases first) = first
| otherwise = go rest
getProtocolByNumber :: ProtocolNumber -> IO ProtocolEntry
getProtocolByNumber num = return (go protocolDB)
where
go [] = throw (userError "Protocol not found")
go (first:rest)
| protoNumber first == num = first
| otherwise = go rest
getProtocolNumber :: ProtocolName -> IO ProtocolNumber
getProtocolNumber name = protoNumber `fmap` (getProtocolByName name)
getProtocolEntries :: Bool -> IO [ProtocolEntry]
getProtocolEntries _ = return protocolDB
setProtocolEntry :: Bool -> IO ()
setProtocolEntry _ = return ()
getProtocolEntry :: IO ProtocolEntry
getProtocolEntry = return (head protocolDB)
endProtocolEntry :: IO ()
endProtocolEntry = return ()
type NetworkName = String
type NetworkAddr = CULong
data NetworkEntry = NetworkEntry {
networkName :: NetworkName
, networkAliases :: [NetworkName]
, networkFamily :: Family
, networkAddress :: NetworkAddr
}
deriving (Read, Show, Typeable)
networkDB :: [NetworkEntry]
networkDB = [
NetworkEntry "default" [] AF_INET 0
, NetworkEntry "loopback" [] AF_INET (fromIP4' (packIP4 127 0 0 0))
, NetworkEntry "link-local" [] AF_INET (fromIP4' (packIP4 169 254 0 0))
]
where fromIP4' = fromIntegral . fromIP4
getNetworkByName :: NetworkName -> IO NetworkEntry
getNetworkByName nm = return (go networkDB)
where
go [] = throw (userError "Network not found")
go (first:rest)
| (networkName first == nm) || (nm `elem` networkAliases first) = first
| otherwise = go rest
getNetworkByAddr :: NetworkAddr -> Family -> IO NetworkEntry
getNetworkByAddr addr fam = return (go networkDB)
where
go [] = throw (userError "Network not found")
go (first:rest)
| (networkFamily first == fam) && (networkAddress first == addr) = first
| otherwise = go rest
getNetworkEntries :: Bool -> IO [NetworkEntry]
getNetworkEntries _ = return networkDB
setNetworkEntry :: Bool -> IO ()
setNetworkEntry _ = return ()
getNetworkEntry :: IO NetworkEntry
getNetworkEntry = return (head networkDB)
endNetworkEntry :: IO ()
endNetworkEntry = return ()
ifNameToIndex :: String -> IO (Maybe Int)
ifNameToIndex _ = return Nothing