-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Network Stack -- -- HaNS is a lightweight, pure Haskell network stack that can be used for -- Haskell networking in the context of the HaLVM, or with a Linux tap -- device. @package hans @version 3.0.2 module Hans.Udp.Packet type UdpPort = Word16 getUdpPort :: Get UdpPort putUdpPort :: Putter UdpPort data UdpHeader UdpHeader :: {-# UNPACK #-} !UdpPort -> {-# UNPACK #-} !UdpPort -> {-# UNPACK #-} !Word16 -> UdpHeader [udpSourcePort] :: UdpHeader -> {-# UNPACK #-} !UdpPort [udpDestPort] :: UdpHeader -> {-# UNPACK #-} !UdpPort [udpChecksum] :: UdpHeader -> {-# UNPACK #-} !Word16 emptyUdpHeader :: UdpHeader udpHeaderSize :: Int -- | Parse out a UdpHeader, and the size of the payload. getUdpHeader :: Get (UdpHeader, Int) -- | Render a UdpHeader. putUdpHeader :: UdpHeader -> Int -> Put instance GHC.Show.Show Hans.Udp.Packet.UdpHeader instance GHC.Classes.Eq Hans.Udp.Packet.UdpHeader module Hans.Time type Expires = Entry UTCTime expiresBefore :: UTCTime -> Expires a -> Bool type ExpireHeap a = Heap (Expires a) emptyHeap :: ExpireHeap a fromListHeap :: [Expires a] -> ExpireHeap a filterHeap :: (a -> Bool) -> ExpireHeap a -> ExpireHeap a partitionHeap :: (a -> Bool) -> ExpireHeap a -> (ExpireHeap a, ExpireHeap a) -- | The next time that something in the heap will expire, if the heap is -- non-empty. nextEvent :: ExpireHeap a -> Maybe UTCTime -- | Remove all expired entries from the heap. dropExpired :: UTCTime -> ExpireHeap a -> ExpireHeap a -- | Given the current time, partition the heap into valid entries, and -- entries that have expired. partitionExpired :: UTCTime -> ExpireHeap a -> (ExpireHeap a, ExpireHeap a) -- | Add an entry to the ExpireHeap, and return the time of the next -- expiration event. expireAt :: UTCTime -> a -> ExpireHeap a -> (ExpireHeap a, UTCTime) nullHeap :: ExpireHeap a -> Bool -- | The amount of time until the top of the heap expires, relative to the -- time given. expirationDelay :: UTCTime -> ExpireHeap a -> Maybe NominalDiffTime -- | Convert a NominalDiffTime into microseconds for use with -- threadDelay. toUSeconds :: NominalDiffTime -> Int -- | Explicit priority/payload tuples. Useful to build a priority queue -- using a Heap, since the payload is ignored in the Eq/Ord -- instances. -- --
--   myHeap = fromList [Entry 2 "World", Entry 1 "Hello", Entry 3 "!"]
--   
--   ==> foldMap payload myHeap ≡ "HelloWorld!"
--   
data Entry p a :: * -> * -> * Entry :: p -> a -> Entry p a [priority] :: Entry p a -> p [payload] :: Entry p a -> a -- | O(n). Returns the elements in the heap in some arbitrary, very -- likely unsorted, order. -- --
--   >>> toUnsortedList (fromList [3,1,2])
--   [1,3,2]
--   
-- --
--   fromList . toUnsortedListid
--   
toUnsortedList :: Heap a -> [a] module Hans.Serialize -- | A specialized version of runPut that allows the initial and -- successive buffer sizes for the Builder to be defined. For -- example, if you're rendering an IP4 packet, you might give the first -- parameter as 20 (the size of the fixed header), and the second as 40 -- (the maximum additional length for options). runPutPacket :: Int -> Int -> ByteString -> Put -> ByteString module Hans.Lens -- | General lenses that allow for the type of the inner field to change. type Lens s t a b = forall f. Functor f => (a -> f b) -> (s -> f t) -- | Lenses that don't change type. type Lens' s a = Lens s s a a lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b type Getting r s a = (a -> Const r a) -> (s -> Const r s) type Getter s a = forall r. Getting r s a view :: Getting a s a -> s -> a to :: (s -> a) -> Getting r s a type ASetter s t a b = (a -> Id b) -> (s -> Id t) type ASetter' s a = ASetter s s a a set :: Lens s t a b -> b -> s -> t over :: ASetter s t a b -> (a -> b) -> (s -> t) modify :: Lens s t a b -> (a -> (b, r)) -> (s -> (t, r)) bit :: Bits a => Int -> Lens' a Bool byte :: (Integral a, Bits a) => Int -> Lens' a Word8 instance GHC.Base.Functor (Hans.Lens.Const r) instance GHC.Base.Functor (Hans.Lens.Modify r) module Hans.Tcp.Packet data TcpHeader TcpHeader :: !TcpPort -> !TcpPort -> !TcpSeqNum -> !TcpAckNum -> !Word16 -> !Word16 -> !Word16 -> !Word16 -> [TcpOption] -> TcpHeader [tcpSourcePort] :: TcpHeader -> !TcpPort [tcpDestPort] :: TcpHeader -> !TcpPort [tcpSeqNum] :: TcpHeader -> !TcpSeqNum [tcpAckNum] :: TcpHeader -> !TcpAckNum [tcpFlags_] :: TcpHeader -> !Word16 [tcpWindow] :: TcpHeader -> !Word16 [tcpChecksum] :: TcpHeader -> !Word16 [tcpUrgentPointer] :: TcpHeader -> !Word16 [tcpOptions_] :: TcpHeader -> [TcpOption] type TcpPort = Word16 putTcpPort :: Putter TcpPort emptyTcpHeader :: TcpHeader -- | The encoded size of a header. tcpHeaderSize :: TcpHeader -> Int data TcpSeqNum -- | An alias to TcpSeqNum, as these two are used in the same role. type TcpAckNum = TcpSeqNum withinWindow :: TcpSeqNum -> TcpSeqNum -> TcpSeqNum -> Bool fromTcpSeqNum :: Num a => TcpSeqNum -> a tcpNs :: Lens' TcpHeader Bool tcpCwr :: Lens' TcpHeader Bool tcpEce :: Lens' TcpHeader Bool tcpUrg :: Lens' TcpHeader Bool tcpAck :: Lens' TcpHeader Bool tcpPsh :: Lens' TcpHeader Bool tcpRst :: Lens' TcpHeader Bool tcpSyn :: Lens' TcpHeader Bool tcpFin :: Lens' TcpHeader Bool -- | Parse a TcpHeader. getTcpHeader :: Get TcpHeader -- | Render a TcpHeader. The checksum value is never rendered, as it is -- expected to be calculated and poked in afterwords. putTcpHeader :: Putter TcpHeader class HasTcpOptions a tcpOptions :: HasTcpOptions a => Lens' a [TcpOption] findTcpOption :: HasTcpOptions opts => TcpOptionTag -> opts -> Maybe TcpOption setTcpOption :: HasTcpOptions opts => TcpOption -> opts -> opts setTcpOptions :: HasTcpOptions opts => [TcpOption] -> opts -> opts data TcpOption OptEndOfOptions :: TcpOption OptNoOption :: TcpOption OptMaxSegmentSize :: !Word16 -> TcpOption OptWindowScaling :: !Word8 -> TcpOption OptSackPermitted :: TcpOption OptSack :: [SackBlock] -> TcpOption OptTimestamp :: !Word32 -> !Word32 -> TcpOption OptUnknown :: !Word8 -> !Word8 -> !ByteString -> TcpOption data TcpOptionTag OptTagEndOfOptions :: TcpOptionTag OptTagNoOption :: TcpOptionTag OptTagMaxSegmentSize :: TcpOptionTag OptTagWindowScaling :: TcpOptionTag OptTagSackPermitted :: TcpOptionTag OptTagSack :: TcpOptionTag OptTagTimestamp :: TcpOptionTag OptTagUnknown :: !Word8 -> TcpOptionTag tcpOptionTag :: TcpOption -> TcpOptionTag data SackBlock SackBlock :: !TcpSeqNum -> !TcpSeqNum -> SackBlock [sbLeft] :: SackBlock -> !TcpSeqNum [sbRight] :: SackBlock -> !TcpSeqNum -- | Get the rendered length of a list of TcpOptions, in 4-byte words, and -- the number of padding bytes required. This rounds up to the nearest -- 4-byte word. tcpOptionsSize :: [TcpOption] -> (Int, Int) tcpOptionSize :: TcpOption -> Int -- | The length of the data segment, including Syn and Fin. tcpSegLen :: TcpHeader -> Int -> Int -- | The last sequence number used in a segment. tcpSegLastSeqNum :: TcpHeader -> Int -> TcpSeqNum -- | The ack number for this segment. tcpSegNextAckNum :: TcpHeader -> Int -> TcpAckNum instance GHC.Show.Show Hans.Tcp.Packet.TcpHeader instance GHC.Classes.Eq Hans.Tcp.Packet.TcpHeader instance GHC.Classes.Eq Hans.Tcp.Packet.TcpOption instance GHC.Show.Show Hans.Tcp.Packet.TcpOption instance GHC.Classes.Eq Hans.Tcp.Packet.SackBlock instance GHC.Show.Show Hans.Tcp.Packet.SackBlock instance GHC.Show.Show Hans.Tcp.Packet.TcpOptionTag instance GHC.Classes.Eq Hans.Tcp.Packet.TcpOptionTag instance GHC.Show.Show Hans.Tcp.Packet.TcpSeqNum instance GHC.Classes.Eq Hans.Tcp.Packet.TcpSeqNum instance GHC.Num.Num Hans.Tcp.Packet.TcpSeqNum instance GHC.Classes.Ord Hans.Tcp.Packet.TcpSeqNum instance Hans.Tcp.Packet.HasTcpOptions Hans.Tcp.Packet.TcpHeader instance Hans.Tcp.Packet.HasTcpOptions [Hans.Tcp.Packet.TcpOption] module Hans.Tcp.RecvWindow -- | The receive window. -- -- INVARIANTS: -- --
    --
  1. All segments in rwSegments are within the window defined by -- rwRcvNxt and rwRcvWnd
  2. --
  3. The segments in rwSegments should not overlap
  4. --
data Window emptyWindow :: TcpSeqNum -> Int -> Window -- | Check an incoming segment, and queue it in the receive window. When -- the segment received was valid Just is returned, including -- segments in the receive window were unblocked by it. -- -- NOTE: when Just[] is returned, this should be a signal to issue a -- duplicate ACK, as we've receive something out of sequence (fast -- retransmit). recvSegment :: TcpHeader -> ByteString -> Window -> (Window, Maybe [(TcpHeader, ByteString)]) -- | The value of RCV.WND. rcvWnd :: Lens' Window Word16 -- | The left edge of the receive window. rcvNxt :: Getting r Window TcpSeqNum -- | Only sets RCV.NXT when the segment queue is empty. Returns True -- when the value has been successfully changed. setRcvNxt :: TcpSeqNum -> Window -> (Window, Bool) -- | The right edge of the receive window, RCV.NXT + RCV.WND. rcvRight :: Getting r Window TcpSeqNum -- | Increase the right edge of the window by n, clamping at the maximum -- window size. moveRcvRight :: Int -> Window -> (Window, ()) -- | This is the check described on page 68 of RFC793, which checks that -- data falls within the expected receive window. When the check is -- successful, the segment returned is one that has been trimmed to fit -- in the window (if necessary). -- -- When this produces a segment, the segment has these properties: -- --
    --
  1. The sequence number is within the window
  2. --
  3. The segment body falls within the window
  4. --
  5. The segment has been copied from the original bytestring
  6. --
-- -- The reason for point 3 is that when frames are allocated by devices, -- they are likely allocated to the full MTU, and not resized. Copying -- here frees up some memory. sequenceNumberValid :: TcpSeqNum -> TcpSeqNum -> TcpHeader -> ByteString -> Maybe Segment instance GHC.Show.Show Hans.Tcp.RecvWindow.Window instance GHC.Show.Show Hans.Tcp.RecvWindow.Segment module Hans.HashTable data HashTable k a -- | Create a new hash table with the given size. newHashTable :: (Eq k, Hashable k) => Int -> IO (HashTable k a) lookup :: (Eq k, Hashable k) => k -> HashTable k a -> IO (Maybe a) delete :: (Eq k, Hashable k) => k -> HashTable k a -> IO () -- | Delete a collection of keys from the table. This is good for multiple -- deletes, as deletes from the same bucket can be grouped together. deletes :: (Eq k, Hashable k) => [k] -> HashTable k a -> IO () mapHashTable :: (Eq k, Hashable k) => (k -> a -> a) -> HashTable k a -> IO () -- | Monadic mapping over the values of a hash table. mapHashTableM_ :: (Eq k, Hashable k) => (k -> a -> IO ()) -> HashTable k a -> IO () filterHashTable :: (Eq k, Hashable k) => (k -> a -> Bool) -> HashTable k a -> IO () -- | Create, update, or delete an entry in the hash table, returning some -- additional value derived from the operation. NOTE: This operation is -- only useful when you need to perform any of these operations at the -- same time -- the specialized versions of the individual behaviors all -- perform slightly better. alter :: (Eq k, Hashable k) => (Maybe a -> (Maybe a, b)) -> k -> HashTable k a -> IO b -- | Gives back an (unsorted) list of all the keys present in the hash -- table. keys :: HashTable k a -> IO [k] hasKey :: (Eq k, Hashable k) => k -> HashTable k a -> IO Bool size :: HashTable k a -> IO Int module Hans.Ethernet.Types data EthernetHeader EthernetHeader :: {-# UNPACK #-} !Mac -> {-# UNPACK #-} !Mac -> {-# UNPACK #-} !EtherType -> EthernetHeader [eDest] :: EthernetHeader -> {-# UNPACK #-} !Mac [eSource] :: EthernetHeader -> {-# UNPACK #-} !Mac [eType] :: EthernetHeader -> {-# UNPACK #-} !EtherType getEthernetHeader :: Get EthernetHeader putEthernetHeader :: Putter EthernetHeader type EtherType = Word16 data Mac Mac :: {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> Mac getMac :: Get Mac putMac :: Putter Mac showMac :: Mac -> ShowS readMac :: ReadS Mac -- | The broadcast MAC address. instance GHC.Show.Show Hans.Ethernet.Types.EthernetHeader instance GHC.Classes.Eq Hans.Ethernet.Types.EthernetHeader instance GHC.Read.Read Hans.Ethernet.Types.Mac instance GHC.Show.Show Hans.Ethernet.Types.Mac instance GHC.Classes.Ord Hans.Ethernet.Types.Mac instance GHC.Classes.Eq Hans.Ethernet.Types.Mac instance Data.Serialize.Serialize Hans.Ethernet.Types.Mac module Hans.Device.Types type DeviceName = ByteString data ChecksumOffload ChecksumOffload :: !Bool -> !Bool -> !Bool -> !Bool -> ChecksumOffload [coIP4] :: ChecksumOffload -> !Bool [coUdp] :: ChecksumOffload -> !Bool [coTcp] :: ChecksumOffload -> !Bool [coIcmp4] :: ChecksumOffload -> !Bool defaultChecksumOffload :: ChecksumOffload -- | Static configuration data for creating a device. data DeviceConfig DeviceConfig :: {-# UNPACK #-} !Int -> !ChecksumOffload -> !ChecksumOffload -> !Int -> DeviceConfig -- | How large the send queue should be. [dcSendQueueLen] :: DeviceConfig -> {-# UNPACK #-} !Int [dcTxOffload] :: DeviceConfig -> !ChecksumOffload [dcRxOffload] :: DeviceConfig -> !ChecksumOffload [dcMtu] :: DeviceConfig -> !Int class HasDeviceConfig cfg deviceConfig :: HasDeviceConfig cfg => Getting r cfg DeviceConfig -- | The TX checksum offload config. txOffload :: HasDeviceConfig cfg => Getting r cfg ChecksumOffload -- | The RX checksum offload config. rxOffload :: HasDeviceConfig cfg => Getting r cfg ChecksumOffload defaultDeviceConfig :: DeviceConfig data Device Device :: !DeviceName -> !Mac -> !DeviceConfig -> !(BoundedChan ByteString) -> !(IO ()) -> !(IO ()) -> !(IO ()) -> !DeviceStats -> Device -- | The name of this device [devName] :: Device -> !DeviceName -- | The mac address associated with this device [devMac] :: Device -> !Mac -- | Static configuration information for this device [devConfig] :: Device -> !DeviceConfig -- | Outgoing message queue for this device [devSendQueue] :: Device -> !(BoundedChan ByteString) -- | Start packet flow [devStart] :: Device -> !(IO ()) -- | Stop packet flow [devStop] :: Device -> !(IO ()) -- | Cleanup resources associated with a Device [devCleanup] :: Device -> !(IO ()) -- | Statistics about this device [devStats] :: Device -> !DeviceStats data DeviceException FailedToOpen :: !DeviceName -> DeviceException type Stat = IORef Int incrementStat :: Stat -> IO () addStat :: Stat -> Int -> IO () data StatGroup StatGroup :: !Stat -> !Stat -> !Stat -> !Stat -> StatGroup [_statBytes] :: StatGroup -> !Stat [_statPackets] :: StatGroup -> !Stat [_statErrors] :: StatGroup -> !Stat [_statDropped] :: StatGroup -> !Stat statBytes :: Getting r StatGroup Stat statPackets :: Getting r StatGroup Stat statErrors :: Getting r StatGroup Stat statDropped :: Getting r StatGroup Stat newStatGroup :: IO StatGroup dumpStatGroup :: String -> StatGroup -> IO () data DeviceStats DeviceStats :: !StatGroup -> !StatGroup -> DeviceStats [_statTX] :: DeviceStats -> !StatGroup [_statRX] :: DeviceStats -> !StatGroup statTX :: Getting r DeviceStats StatGroup statRX :: Getting r DeviceStats StatGroup newDeviceStats :: IO DeviceStats dumpStats :: DeviceStats -> IO () -- | Add one to the count of dropped packets for this device. updateDropped :: Getting Stat DeviceStats StatGroup -> DeviceStats -> IO () -- | Add one to the error count for this device. updateError :: Getting Stat DeviceStats StatGroup -> DeviceStats -> IO () -- | Update information about bytes received. updateBytes :: Getting Stat DeviceStats StatGroup -> DeviceStats -> Int -> IO () -- | Update information about bytes received. updatePackets :: Getting Stat DeviceStats StatGroup -> DeviceStats -> IO () instance GHC.Show.Show Hans.Device.Types.DeviceException instance GHC.Show.Show Hans.Device.Types.DeviceConfig instance GHC.Show.Show Hans.Device.Types.ChecksumOffload instance Hans.Device.Types.HasDeviceConfig Hans.Device.Types.DeviceConfig instance Hans.Device.Types.HasDeviceConfig Hans.Device.Types.Device instance GHC.Classes.Eq Hans.Device.Types.Device instance GHC.Classes.Ord Hans.Device.Types.Device instance GHC.Exception.Exception Hans.Device.Types.DeviceException module Hans.Ethernet -- | Send a message out via a device. sendEthernet :: Device -> Mac -> EtherType -> ByteString -> IO () module Hans.Monad data Hans a -- | Loop forever, running the underlying operation. runHans :: Hans () -> IO () -- | Run only one iteration of the Hans monad. runHansOnce :: Hans a -> IO (Maybe a) -- | Set the escape continuation to the current position, within the -- operation given, so that control flow always restores back through -- this point. setEscape :: Hans () -> Hans () -- | Invoke the escape continuation. escape :: Hans a -- | Synonym for escape that also updates device statistics. dropPacket :: DeviceStats -> Hans a -- | Call-cc. NOTE: the continuation will inherit the escape point of the -- calling context. callCC :: ((b -> Hans a) -> Hans b) -> Hans b -- | Lift an IO operation into Hans. io :: IO a -> Hans a -- | Run a Get action in the context of the Hans monad, decode :: DeviceStats -> Get a -> ByteString -> Hans a -- | Run a Get action in the context of the Hans monad, returning any -- unconsumed input. decode' :: DeviceStats -> Get a -> ByteString -> Hans (a, ByteString) instance GHC.Base.Functor Hans.Monad.Hans instance GHC.Base.Applicative Hans.Monad.Hans instance GHC.Base.Monad Hans.Monad.Hans instance MonadLib.BaseM Hans.Monad.Hans GHC.Types.IO module Hans.Network.Types type NetworkProtocol = Word8 getNetworkProtocol :: Get NetworkProtocol putNetworkProtocol :: NetworkProtocol -> Put -- | Information about how to reach a specific destination address (source -- and next-hop addresses, and device to use). data RouteInfo addr RouteInfo :: !addr -> !addr -> !Device -> RouteInfo addr -- | The source address to use when sending [riSource] :: RouteInfo addr -> !addr -- | The next-hop in the route [riNext] :: RouteInfo addr -> !addr -- | The device used for delivery [riDev] :: RouteInfo addr -> !Device instance GHC.Base.Functor Hans.Network.Types.RouteInfo instance GHC.Classes.Eq addr => GHC.Classes.Eq (Hans.Network.Types.RouteInfo addr) instance Hans.Device.Types.HasDeviceConfig (Hans.Network.Types.RouteInfo addr) module Hans.Config -- | General network stack configuration. data Config Config :: !Int -> !Int -> !NominalDiffTime -> !Int -> !Int -> !NominalDiffTime -> !Word8 -> !Int -> !Int -> !Int -> !Int -> !Int -> !NominalDiffTime -> !Int -> !Int -> !Int -> !Int -> !NominalDiffTime -> !Int -> !Int -> Config [cfgInputQueueSize] :: Config -> !Int -- | Best to pick a prime number. [cfgArpTableSize] :: Config -> !Int [cfgArpTableLifetime] :: Config -> !NominalDiffTime -- | Number of times to retry an arp request before failing [cfgArpRetry] :: Config -> !Int -- | The amount of time to wait between arp request retransmission. [cfgArpRetryDelay] :: Config -> !Int -- | Number of seconds to wait before expiring a partially reassembled IP4 -- packet [cfgIP4FragTimeout] :: Config -> !NominalDiffTime [cfgIP4InitialTTL] :: Config -> !Word8 -- | Maximum packets being reassembled at any time. [cfgIP4MaxFragTableEntries] :: Config -> !Int -- | Number of buckets in the udp socket table [cfgUdpSocketTableSize] :: Config -> !Int -- | In microseconds [cfgDnsResolveTimeout] :: Config -> !Int -- | Small-ish prime number [cfgTcpListenTableSize] :: Config -> !Int -- | Best to pick a prime number [cfgTcpActiveTableSize] :: Config -> !Int -- | Time to remain in TimeWait, in seconds. [cfgTcpTimeoutTimeWait] :: Config -> !NominalDiffTime -- | Initial MSS for tcp connections [cfgTcpInitialMSS] :: Config -> !Int -- | Maximum number of connections waiting for an acknowledgement. [cfgTcpMaxSynBacklog] :: Config -> !Int -- | Initial local window for tcp connections. [cfgTcpInitialWindow] :: Config -> !Int -- | Maximum segment lifetime [cfgTcpMSL] :: Config -> !Int -- | Frequency (in Hz) of timestamp clock updates. Should be between 1Hz -- and 1000Hz, according to RFC-1323. [cfgTcpTSClockFrequency] :: Config -> !NominalDiffTime -- | The max number of threads allowed in the time wait heap. [cfgTcpTimeWaitSocketLimit] :: Config -> !Int -- | The maximum number of entries allowed in the TCP or UDP NAT tables [cfgNatMaxEntries] :: Config -> !Int defaultConfig :: Config class HasConfig cfg config :: HasConfig cfg => Getting r cfg Config instance Hans.Config.HasConfig Hans.Config.Config module Hans.Tcp.SendWindow -- | This structure holds bookkeeping variables for the remote end's -- receive window, as well as the retransmit queue. data Window emptyWindow :: TcpSeqNum -> TcpSeqNum -> TSClock -> Window -- | The value of SND.NXT. -- -- NOTE: SND.UNA <= SND.NXT < SND.UNA + SND.WND sndNxt :: Getting r Window TcpSeqNum -- | Only sets the value of SND.NXT when the retransmit queue is empty. setSndNxt :: TcpSeqNum -> Window -> (Window, Bool) -- | The value of SND.UNA -- the left-edge of the send window. sndUna :: Getting r Window TcpSeqNum -- | The value of SND.WND. sndWnd :: Lens' Window TcpSeqNum -- | True when the window is empty. nullWindow :: Window -> Bool -- | True when the window is full. fullWindow :: Window -> Bool -- | Remove everything from the remote window. flushWindow :: Window -> (Window, ()) data TSClock -- | Create a TSClock. initialTSClock :: Word32 -> UTCTime -> TSClock -- | Update the timestamp clock, and return the new value of TSval. updateTSClock :: Config -> UTCTime -> TSClock -> TSClock -- | The current value of the TS clock. tsVal :: Getting r TSClock Word32 -- | Returns the new send window, as well as boolean indicating whether or -- not the retransmit timer needs to be started. queueSegment :: Config -> UTCTime -> (Word32 -> TcpSeqNum -> TcpHeader) -> ByteString -> Window -> (Window, Maybe (Bool, TcpHeader, ByteString)) -- | A retransmit timer has gone off: reset the sack bit on all segments in -- the queue; if the left-edge exists, mark it as having been -- retransmitted, and return it back to be sent. -- -- XXX: does this need to update the TS clock? retransmitTimeout :: Window -> (Window, Maybe (TcpHeader, ByteString)) -- | Remove all segments of the send window that occur before this sequence -- number, and increase the size of the available window. When the -- segment doesn't acknowledge anything in the window, Nothing as -- the second parameter. Otherwise, return a boolean that is True -- when there are no outstanding segments, and a measurement of the RTT -- when the segment has not been retransmitted. ackSegment :: Config -> UTCTime -> TcpSeqNum -> Window -> (Window, Maybe (Bool, Maybe NominalDiffTime)) -- | Process a sack option, and return the updated window, and the segments -- that are missing from the remote window. handleSack :: [SackBlock] -> Window -> (Window, [(TcpHeader, ByteString)]) instance Hans.Tcp.Packet.HasTcpOptions Hans.Tcp.SendWindow.Segment -- | A module providing checksum computations to other parts of Hans. The -- checksum here is the standard Internet 16-bit checksum (the one's -- complement of the one's complement sum of the data). module Hans.Checksum computeChecksum :: Checksum a => a -> Word16 -- | Incremental checksum computation interface. class Checksum a extendChecksum :: Checksum a => a -> PartialChecksum -> PartialChecksum data PartialChecksum emptyPartialChecksum :: PartialChecksum finalizeChecksum :: PartialChecksum -> Word16 stepChecksum :: Word32 -> Word8 -> Word8 -> Word32 data Pair8 Pair8 :: !Word8 -> !Word8 -> Pair8 instance GHC.Show.Show Hans.Checksum.PartialChecksum instance GHC.Classes.Eq Hans.Checksum.PartialChecksum instance Hans.Checksum.Checksum Hans.Checksum.Pair8 instance Hans.Checksum.Checksum GHC.Word.Word16 instance Hans.Checksum.Checksum GHC.Word.Word32 instance Hans.Checksum.Checksum a => Hans.Checksum.Checksum [a] instance Hans.Checksum.Checksum Data.ByteString.Lazy.Internal.ByteString instance Hans.Checksum.Checksum Data.ByteString.Short.Internal.ShortByteString instance Hans.Checksum.Checksum Data.ByteString.Internal.ByteString module Hans.IP4.Packet newtype IP4 IP4 :: Word32 -> IP4 getIP4 :: Get IP4 putIP4 :: Putter IP4 packIP4 :: Word8 -> Word8 -> Word8 -> Word8 -> IP4 unpackIP4 :: IP4 -> (Word8, Word8, Word8, Word8) showIP4 :: IP4 -> ShowS readIP4 :: ReadS IP4 data IP4Mask -- | Between 0 and 32 IP4Mask :: {-# UNPACK #-} !IP4 -> {-# UNPACK #-} !Int -> IP4Mask hostmask :: Int -> Word32 netmask :: Int -> Word32 maskRange :: IP4Mask -> (IP4, IP4) maskBits :: IP4Mask -> Int maskAddr :: IP4Mask -> IP4 clearHostBits :: IP4Mask -> IP4 setHostBits :: IP4Mask -> IP4 broadcastAddress :: IP4Mask -> IP4 readIP4Mask :: ReadS IP4Mask showIP4Mask :: IP4Mask -> ShowS -- | source address | +--------+--------+--------+--------+ | destination -- address | +--------+--------+--------+--------+ | zero |protocol| -- length | +--------+--------+--------+--------+ ip4PseudoHeader :: IP4 -> IP4 -> NetworkProtocol -> Int -> PartialChecksum type IP4Ident = Word16 data IP4Header IP4Header :: {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !IP4Ident -> {-# UNPACK #-} !Word16 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !NetworkProtocol -> {-# UNPACK #-} !Word16 -> {-# UNPACK #-} !IP4 -> {-# UNPACK #-} !IP4 -> ![IP4Option] -> IP4Header [ip4TypeOfService] :: IP4Header -> {-# UNPACK #-} !Word8 [ip4Ident] :: IP4Header -> {-# UNPACK #-} !IP4Ident -- | This includes the flags, and the fragment offset. [ip4Fragment_] :: IP4Header -> {-# UNPACK #-} !Word16 [ip4TimeToLive] :: IP4Header -> {-# UNPACK #-} !Word8 [ip4Protocol] :: IP4Header -> {-# UNPACK #-} !NetworkProtocol [ip4Checksum] :: IP4Header -> {-# UNPACK #-} !Word16 [ip4SourceAddr] :: IP4Header -> {-# UNPACK #-} !IP4 [ip4DestAddr] :: IP4Header -> {-# UNPACK #-} !IP4 [ip4Options] :: IP4Header -> ![IP4Option] emptyIP4Header :: IP4Header ip4DCSP :: Lens' IP4Header Word8 ip4ECN :: Lens' IP4Header Word8 ip4Fragment :: Lens' IP4Header Word16 ip4DontFragment :: Lens' IP4Header Bool ip4MoreFragments :: Lens' IP4Header Bool -- | The fragment offset, in bytes. ip4FragmentOffset :: Lens' IP4Header Word16 noMoreFragments :: IP4Header -> IP4Header moreFragments :: IP4Header -> IP4Header addOffset :: Word16 -> IP4Header -> IP4Header setIdent :: IP4Ident -> IP4Header -> IP4Header -- | Calculate the size of an IP4 packet ip4PacketSize :: IP4Header -> ByteString -> Int -- | Calculate the size of an IP4 header ip4HeaderSize :: IP4Header -> Int -- | Fragment a single IP packet into one or more, given an MTU to fit -- into. splitPacket :: Int -> IP4Header -> ByteString -> [(IP4Header, ByteString)] -- | Given a fragment size and a packet, fragment the packet into multiple -- smaller ones. fragmentPacket :: Int64 -> IP4Header -> ByteString -> [(IP4Header, ByteString)] -- | Compute the value of the version/header length byte. ip4VersionIHL :: Int -> Word8 -- | Version| IHL |Type of Service| Total Length | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | -- Identification |Flags| Fragment Offset | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | -- Time to Live | Protocol | Header Checksum | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | -- Source Address | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | -- Destination Address | -- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ getIP4Packet :: Get (IP4Header, Int, Int) putIP4Header :: IP4Header -> Int -> Put renderIP4Options :: [IP4Option] -> (ByteString, Int) getIP4Options :: Int -> Get [IP4Option] data IP4Option IP4Option :: !Bool -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !Word8 -> {-# UNPACK #-} !ShortByteString -> IP4Option [ip4OptionCopied] :: IP4Option -> !Bool [ip4OptionClass] :: IP4Option -> {-# UNPACK #-} !Word8 [ip4OptionNum] :: IP4Option -> {-# UNPACK #-} !Word8 [ip4OptionData] :: IP4Option -> {-# UNPACK #-} !ShortByteString ip4OptionSize :: IP4Option -> Int getIP4Option :: Get IP4Option ip4OptionType :: Bool -> Word8 -> Word8 -> Word8 putIP4Option :: Putter IP4Option -- | Arp packets, specialized to IP4 and Mac addresses. data ArpPacket ArpPacket :: {-# UNPACK #-} !ArpOper -> !Mac -> !IP4 -> !Mac -> !IP4 -> ArpPacket [arpOper] :: ArpPacket -> {-# UNPACK #-} !ArpOper [arpSHA] :: ArpPacket -> !Mac [arpSPA] :: ArpPacket -> !IP4 [arpTHA] :: ArpPacket -> !Mac [arpTPA] :: ArpPacket -> !IP4 -- | Parse an Arp packet, given a way to parse hardware and protocol -- addresses. getArpPacket :: Get ArpPacket renderArpPacket :: ArpPacket -> ByteString -- | Render an Arp packet, given a way to render hardware and protocol -- addresses. putArpPacket :: Putter ArpPacket type ArpOper = Word16 -- | Parse an Arp operation. getArpOper :: Get ArpOper -- | Render an Arp operation. putArpOper :: Putter ArpOper instance GHC.Show.Show Hans.IP4.Packet.ArpPacket instance GHC.Classes.Eq Hans.IP4.Packet.ArpPacket instance GHC.Show.Show Hans.IP4.Packet.IP4Header instance GHC.Classes.Eq Hans.IP4.Packet.IP4Header instance GHC.Show.Show Hans.IP4.Packet.IP4Option instance GHC.Classes.Eq Hans.IP4.Packet.IP4Option instance GHC.Read.Read Hans.IP4.Packet.IP4Mask instance GHC.Show.Show Hans.IP4.Packet.IP4Mask instance GHC.Generics.Generic Hans.IP4.Packet.IP4 instance Hans.Checksum.Checksum Hans.IP4.Packet.IP4 instance Data.Hashable.Class.Hashable Hans.IP4.Packet.IP4 instance GHC.Read.Read Hans.IP4.Packet.IP4 instance GHC.Show.Show Hans.IP4.Packet.IP4 instance GHC.Classes.Ord Hans.IP4.Packet.IP4 instance GHC.Classes.Eq Hans.IP4.Packet.IP4 instance Data.Serialize.Serialize Hans.IP4.Packet.IP4 instance GHC.Classes.Eq Hans.IP4.Packet.IP4Mask module Hans.Dns.Packet data DNSPacket DNSPacket :: DNSHeader -> [Query] -> [RR] -> [RR] -> [RR] -> DNSPacket [dnsHeader] :: DNSPacket -> DNSHeader [dnsQuestions] :: DNSPacket -> [Query] [dnsAnswers] :: DNSPacket -> [RR] [dnsAuthorityRecords] :: DNSPacket -> [RR] [dnsAdditionalRecords] :: DNSPacket -> [RR] data DNSHeader DNSHeader :: !Word16 -> Bool -> OpCode -> Bool -> Bool -> Bool -> Bool -> RespCode -> DNSHeader [dnsId] :: DNSHeader -> !Word16 [dnsQuery] :: DNSHeader -> Bool [dnsOpCode] :: DNSHeader -> OpCode [dnsAA] :: DNSHeader -> Bool [dnsTC] :: DNSHeader -> Bool [dnsRD] :: DNSHeader -> Bool [dnsRA] :: DNSHeader -> Bool [dnsRC] :: DNSHeader -> RespCode data OpCode OpQuery :: OpCode OpIQuery :: OpCode OpStatus :: OpCode OpReserved :: !Word16 -> OpCode data RespCode RespNoError :: RespCode RespFormatError :: RespCode RespServerFailure :: RespCode RespNameError :: RespCode RespNotImplemented :: RespCode RespRefused :: RespCode RespReserved :: !Word16 -> RespCode data Query Query :: Name -> QType -> QClass -> Query [qName] :: Query -> Name [qType] :: Query -> QType [qClass] :: Query -> QClass data QClass QClass :: Class -> QClass QAnyClass :: QClass data QType QType :: Type -> QType AFXR :: QType MAILB :: QType MAILA :: QType QTAny :: QType data RR RR :: Name -> Class -> !Int32 -> RData -> RR [rrName] :: RR -> Name [rrClass] :: RR -> Class [rrTTL] :: RR -> !Int32 [rrRData] :: RR -> RData data Type A :: Type NS :: Type MD :: Type MF :: Type CNAME :: Type SOA :: Type MB :: Type MG :: Type MR :: Type NULL :: Type PTR :: Type HINFO :: Type MINFO :: Type MX :: Type AAAA :: Type data Class IN :: Class CS :: Class CH :: Class HS :: Class data RData RDA :: IP4 -> RData RDNS :: Name -> RData RDMD :: Name -> RData RDMF :: Name -> RData RDCNAME :: Name -> RData RDSOA :: Name -> Name -> !Word32 -> !Int32 -> !Int32 -> !Int32 -> !Word32 -> RData RDMB :: Name -> RData RDMG :: Name -> RData RDMR :: Name -> RData RDPTR :: Name -> RData RDHINFO :: ByteString -> ByteString -> RData RDMINFO :: Name -> Name -> RData RDMX :: !Word16 -> Name -> RData RDNULL :: ByteString -> RData RDUnknown :: Type -> ByteString -> RData type Name = [ByteString] getDNSPacket :: Get DNSPacket putDNSPacket :: Putter DNSPacket instance GHC.Show.Show Hans.Dns.Packet.Label instance GHC.Show.Show Hans.Dns.Packet.RW instance GHC.Show.Show Hans.Dns.Packet.DNSPacket instance GHC.Show.Show Hans.Dns.Packet.RR instance GHC.Show.Show Hans.Dns.Packet.RData instance GHC.Show.Show Hans.Dns.Packet.Query instance GHC.Show.Show Hans.Dns.Packet.QClass instance GHC.Classes.Eq Hans.Dns.Packet.Class instance GHC.Show.Show Hans.Dns.Packet.Class instance GHC.Show.Show Hans.Dns.Packet.QType instance GHC.Show.Show Hans.Dns.Packet.Type instance GHC.Show.Show Hans.Dns.Packet.DNSHeader instance GHC.Show.Show Hans.Dns.Packet.RespCode instance GHC.Classes.Eq Hans.Dns.Packet.RespCode instance GHC.Show.Show Hans.Dns.Packet.OpCode module Hans.IP4.ArpTable -- | The Arp table consists of a map of IP4 to Mac, as well as a heap that -- orders the IP4 addresses according to when their corresponding entries -- should be expired. -- -- NOTE: There's currently no way to limit the memory use of the arp -- table, but that might not be a huge problem as the entries are added -- based on requests from higher layers. -- -- INVARIANT: there should never be entries in the map that aren't also -- in the heap. data ArpTable newArpTable :: Config -> IO ArpTable -- | Insert an entry into the Arp table, and unblock any waiting actions. addEntry :: ArpTable -> IP4 -> Mac -> IO () -- | If nobody has responded to queries for this address, notify any -- waiters that there is no mac associated. -- -- NOTE: in the future, it might be nice to keep an entry in the table -- that indicates that this host is unreachable. markUnreachable :: ArpTable -> IP4 -> IO () -- | Lookup an entry in the Arp table. lookupEntry :: ArpTable -> IP4 -> IO (Maybe Mac) -- | Returns either the address, or an empty MVar that will -- eventually contain the Mac, or Nothing if the Arp -- request fails. resolveAddr :: ArpTable -> IP4 -> WaitStrategy res -> IO (QueryResult res) data QueryResult res Known :: !Mac -> QueryResult res Unknown :: !Bool -> res -> QueryResult res data WaitStrategy res -- | Have the entry block on a blockingStrategy :: WaitStrategy (MVar (Maybe Mac)) -- | Write the discovered Mac to a bounded channel, passing it through a -- filtering function first. writeChanStrategy :: Maybe DeviceStats -> (Maybe Mac -> Maybe msg) -> BoundedChan msg -> WaitStrategy () module Hans.IP4.Dhcp.Codec class CodecAtom a getAtom :: CodecAtom a => Get a putAtom :: CodecAtom a => a -> Put atomSize :: CodecAtom a => a -> Int newtype SubnetMask SubnetMask :: Int -> SubnetMask [unmask] :: SubnetMask -> Int word32ToSubnetMask :: Word32 -> Maybe SubnetMask subnetMaskToWord32 :: SubnetMask -> Word32 computeMask :: Int -> Word32 instance GHC.Classes.Eq Hans.IP4.Dhcp.Codec.SubnetMask instance GHC.Show.Show Hans.IP4.Dhcp.Codec.SubnetMask instance (Hans.IP4.Dhcp.Codec.CodecAtom a, Hans.IP4.Dhcp.Codec.CodecAtom b) => Hans.IP4.Dhcp.Codec.CodecAtom (a, b) instance Hans.IP4.Dhcp.Codec.CodecAtom GHC.Word.Word8 instance Hans.IP4.Dhcp.Codec.CodecAtom GHC.Word.Word16 instance Hans.IP4.Dhcp.Codec.CodecAtom GHC.Word.Word32 instance Hans.IP4.Dhcp.Codec.CodecAtom GHC.Types.Bool instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Packet.IP4 instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Packet.IP4Mask instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.Ethernet.Types.Mac instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Codec.SubnetMask module Hans.IP4.Dhcp.Options data MagicCookie MagicCookie :: MagicCookie dhcp4MagicCookie :: Word32 data Dhcp4Option OptSubnetMask :: SubnetMask -> Dhcp4Option OptTimeOffset :: Word32 -> Dhcp4Option OptRouters :: [IP4] -> Dhcp4Option OptTimeServers :: [IP4] -> Dhcp4Option OptIEN116NameServers :: [IP4] -> Dhcp4Option OptNameServers :: [IP4] -> Dhcp4Option OptLogServers :: [IP4] -> Dhcp4Option OptCookieServers :: [IP4] -> Dhcp4Option OptLPRServers :: [IP4] -> Dhcp4Option OptImpressServers :: [IP4] -> Dhcp4Option OptResourceLocationServers :: [IP4] -> Dhcp4Option OptHostName :: NVTAsciiString -> Dhcp4Option OptBootFileSize :: Word16 -> Dhcp4Option OptMeritDumpFile :: NVTAsciiString -> Dhcp4Option OptDomainName :: NVTAsciiString -> Dhcp4Option OptSwapServer :: IP4 -> Dhcp4Option OptRootPath :: NVTAsciiString -> Dhcp4Option OptExtensionsPath :: NVTAsciiString -> Dhcp4Option OptEnableIPForwarding :: Bool -> Dhcp4Option OptEnableNonLocalSourceRouting :: Bool -> Dhcp4Option OptPolicyFilters :: [IP4Mask] -> Dhcp4Option OptMaximumDatagramReassemblySize :: Word16 -> Dhcp4Option OptDefaultTTL :: Word8 -> Dhcp4Option OptPathMTUAgingTimeout :: Word32 -> Dhcp4Option OptPathMTUPlateauTable :: [Word16] -> Dhcp4Option OptInterfaceMTU :: Word16 -> Dhcp4Option OptAllSubnetsAreLocal :: Bool -> Dhcp4Option OptBroadcastAddress :: IP4 -> Dhcp4Option OptPerformMaskDiscovery :: Bool -> Dhcp4Option OptShouldSupplyMasks :: Bool -> Dhcp4Option OptShouldPerformRouterDiscovery :: Bool -> Dhcp4Option OptRouterSolicitationAddress :: IP4 -> Dhcp4Option OptStaticRoutes :: [(IP4, IP4)] -> Dhcp4Option OptShouldNegotiateArpTrailers :: Bool -> Dhcp4Option OptArpCacheTimeout :: Word32 -> Dhcp4Option OptUseRFC1042EthernetEncapsulation :: Bool -> Dhcp4Option OptTcpDefaultTTL :: Word8 -> Dhcp4Option OptTcpKeepaliveInterval :: Word32 -> Dhcp4Option OptTcpKeepaliveUseGarbage :: Bool -> Dhcp4Option OptNisDomainName :: NVTAsciiString -> Dhcp4Option OptNisServers :: [IP4] -> Dhcp4Option OptNtpServers :: [IP4] -> Dhcp4Option OptVendorSpecific :: ByteString -> Dhcp4Option OptNetBiosNameServers :: [IP4] -> Dhcp4Option OptNetBiosDistributionServers :: [IP4] -> Dhcp4Option OptNetBiosNodeType :: NetBiosNodeType -> Dhcp4Option OptNetBiosScope :: NVTAsciiString -> Dhcp4Option OptXWindowsFontServer :: [IP4] -> Dhcp4Option OptXWindowsDisplayManagers :: [IP4] -> Dhcp4Option OptNisPlusDomain :: NVTAsciiString -> Dhcp4Option OptNisPlusServers :: [IP4] -> Dhcp4Option OptSmtpServers :: [IP4] -> Dhcp4Option OptPopServers :: [IP4] -> Dhcp4Option OptNntpServers :: [IP4] -> Dhcp4Option OptWwwServers :: [IP4] -> Dhcp4Option OptFingerServers :: [IP4] -> Dhcp4Option OptIrcServers :: [IP4] -> Dhcp4Option OptStreetTalkServers :: [IP4] -> Dhcp4Option OptStreetTalkDirectoryAssistanceServers :: [IP4] -> Dhcp4Option OptFQDN :: NVTAsciiString -> Dhcp4Option OptRequestIPAddress :: IP4 -> Dhcp4Option OptIPAddressLeaseTime :: Word32 -> Dhcp4Option OptOverload :: OverloadOption -> Dhcp4Option OptTftpServer :: NVTAsciiString -> Dhcp4Option OptBootfileName :: NVTAsciiString -> Dhcp4Option OptMessageType :: Dhcp4MessageType -> Dhcp4Option OptServerIdentifier :: IP4 -> Dhcp4Option OptParameterRequestList :: [OptionTagOrError] -> Dhcp4Option OptErrorMessage :: NVTAsciiString -> Dhcp4Option OptMaxDHCPMessageSize :: Word16 -> Dhcp4Option OptRenewalTime :: Word32 -> Dhcp4Option OptRebindingTime :: Word32 -> Dhcp4Option OptVendorClass :: NVTAsciiString -> Dhcp4Option OptClientIdentifier :: ByteString -> Dhcp4Option OptNetWareDomainName :: NVTAsciiString -> Dhcp4Option OptNetWareInfo :: ByteString -> Dhcp4Option OptAutoconfiguration :: Bool -> Dhcp4Option getDhcp4Option :: Get (Either ControlTag Dhcp4Option) putDhcp4Option :: Dhcp4Option -> Put data Dhcp4MessageType Dhcp4Discover :: Dhcp4MessageType Dhcp4Offer :: Dhcp4MessageType Dhcp4Request :: Dhcp4MessageType Dhcp4Decline :: Dhcp4MessageType Dhcp4Ack :: Dhcp4MessageType Dhcp4Nak :: Dhcp4MessageType Dhcp4Release :: Dhcp4MessageType Dhcp4Inform :: Dhcp4MessageType data ControlTag ControlPad :: ControlTag ControlEnd :: ControlTag putControlOption :: ControlTag -> Put data Dhcp4OptionTag OptTagPad :: Dhcp4OptionTag OptTagEnd :: Dhcp4OptionTag OptTagSubnetMask :: Dhcp4OptionTag OptTagTimeOffset :: Dhcp4OptionTag OptTagRouters :: Dhcp4OptionTag OptTagTimeServers :: Dhcp4OptionTag OptTagIEN116NameServers :: Dhcp4OptionTag OptTagNameServers :: Dhcp4OptionTag OptTagLogServers :: Dhcp4OptionTag OptTagCookieServers :: Dhcp4OptionTag OptTagLPRServers :: Dhcp4OptionTag OptTagImpressServers :: Dhcp4OptionTag OptTagResourceLocationServers :: Dhcp4OptionTag OptTagHostName :: Dhcp4OptionTag OptTagBootFileSize :: Dhcp4OptionTag OptTagMeritDumpFile :: Dhcp4OptionTag OptTagDomainName :: Dhcp4OptionTag OptTagSwapServer :: Dhcp4OptionTag OptTagRootPath :: Dhcp4OptionTag OptTagExtensionsPath :: Dhcp4OptionTag OptTagEnableIPForwarding :: Dhcp4OptionTag OptTagEnableNonLocalSourceRouting :: Dhcp4OptionTag OptTagPolicyFilters :: Dhcp4OptionTag OptTagMaximumDatagramReassemblySize :: Dhcp4OptionTag OptTagDefaultTTL :: Dhcp4OptionTag OptTagPathMTUAgingTimeout :: Dhcp4OptionTag OptTagPathMTUPlateauTable :: Dhcp4OptionTag OptTagInterfaceMTU :: Dhcp4OptionTag OptTagAllSubnetsAreLocal :: Dhcp4OptionTag OptTagBroadcastAddress :: Dhcp4OptionTag OptTagPerformMaskDiscovery :: Dhcp4OptionTag OptTagShouldSupplyMasks :: Dhcp4OptionTag OptTagShouldPerformRouterDiscovery :: Dhcp4OptionTag OptTagRouterSolicitationAddress :: Dhcp4OptionTag OptTagStaticRoutes :: Dhcp4OptionTag OptTagShouldNegotiateArpTrailers :: Dhcp4OptionTag OptTagArpCacheTimeout :: Dhcp4OptionTag OptTagUseRFC1042EthernetEncapsulation :: Dhcp4OptionTag OptTagTcpDefaultTTL :: Dhcp4OptionTag OptTagTcpKeepaliveInterval :: Dhcp4OptionTag OptTagTcpKeepaliveUseGarbage :: Dhcp4OptionTag OptTagNisDomainName :: Dhcp4OptionTag OptTagNisServers :: Dhcp4OptionTag OptTagNtpServers :: Dhcp4OptionTag OptTagVendorSpecific :: Dhcp4OptionTag OptTagNetBiosNameServers :: Dhcp4OptionTag OptTagNetBiosDistributionServers :: Dhcp4OptionTag OptTagNetBiosNodeType :: Dhcp4OptionTag OptTagNetBiosScope :: Dhcp4OptionTag OptTagXWindowsFontServer :: Dhcp4OptionTag OptTagXWindowsDisplayManagers :: Dhcp4OptionTag OptTagNisPlusDomain :: Dhcp4OptionTag OptTagNisPlusServers :: Dhcp4OptionTag OptTagSmtpServers :: Dhcp4OptionTag OptTagPopServers :: Dhcp4OptionTag OptTagNntpServers :: Dhcp4OptionTag OptTagWwwServers :: Dhcp4OptionTag OptTagFingerServers :: Dhcp4OptionTag OptTagIrcServers :: Dhcp4OptionTag OptTagStreetTalkServers :: Dhcp4OptionTag OptTagStreetTalkDirectoryAssistanceServers :: Dhcp4OptionTag OptTagFQDN :: Dhcp4OptionTag OptTagRequestIPAddress :: Dhcp4OptionTag OptTagIPAddressLeaseTime :: Dhcp4OptionTag OptTagOverload :: Dhcp4OptionTag OptTagTftpServer :: Dhcp4OptionTag OptTagBootfileName :: Dhcp4OptionTag OptTagMessageType :: Dhcp4OptionTag OptTagServerIdentifier :: Dhcp4OptionTag OptTagParameterRequestList :: Dhcp4OptionTag OptTagErrorMessage :: Dhcp4OptionTag OptTagMaxDHCPMessageSize :: Dhcp4OptionTag OptTagRenewalTime :: Dhcp4OptionTag OptTagRebindingTime :: Dhcp4OptionTag OptTagVendorClass :: Dhcp4OptionTag OptTagClientIdentifier :: Dhcp4OptionTag OptTagNetWareDomainName :: Dhcp4OptionTag OptTagNetWareInfo :: Dhcp4OptionTag OptTagAutoconfiguration :: Dhcp4OptionTag data OptionTagOrError UnknownTag :: Word8 -> OptionTagOrError KnownTag :: Dhcp4OptionTag -> OptionTagOrError getOptionTag :: Get OptionTagOrError putOptionTag :: OptionTagOrError -> Put data NetBiosNodeType BNode :: NetBiosNodeType PNode :: NetBiosNodeType MNode :: NetBiosNodeType HNode :: NetBiosNodeType data OverloadOption UsedFileField :: OverloadOption UsedSNameField :: OverloadOption UsedBothFields :: OverloadOption getDhcp4Options :: ByteString -> ByteString -> Get (String, String, [Dhcp4Option]) putDhcp4Options :: [Dhcp4Option] -> Put scrubControls :: (Applicative m, Monad m) => [Either ControlTag Dhcp4Option] -> m [Dhcp4Option] -- | eatPad fails on any non ControlPad option with an error -- message. eatPad :: Monad m => Either ControlTag Dhcp4Option -> m () replicateA :: Applicative f => Int -> f a -> f [a] repeatedly :: Get a -> Get [a] nullTerminated :: ByteString -> String lookupOverload :: [Dhcp4Option] -> Maybe OverloadOption lookupFile :: [Dhcp4Option] -> Maybe NVTAsciiString lookupSname :: [Dhcp4Option] -> Maybe NVTAsciiString lookupParams :: [Dhcp4Option] -> Maybe [OptionTagOrError] lookupMessageType :: [Dhcp4Option] -> Maybe Dhcp4MessageType lookupRequestAddr :: [Dhcp4Option] -> Maybe IP4 lookupLeaseTime :: [Dhcp4Option] -> Maybe Word32 class Option a getOption :: Option a => Get a putOption :: Option a => a -> Put defaultFixedGetOption :: CodecAtom a => Get a defaultFixedPutOption :: CodecAtom a => a -> Put fixedLen :: Int -> Get a -> Get a getRecord :: CodecAtom a => (Int, Get a) newtype NVTAsciiString NVTAsciiString :: String -> NVTAsciiString getLen :: Get Int putLen :: Int -> Put instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.Dhcp4Option instance GHC.Show.Show Hans.IP4.Dhcp.Options.Dhcp4Option instance GHC.Show.Show Hans.IP4.Dhcp.Options.NVTAsciiString instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.NVTAsciiString instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.OverloadOption instance GHC.Show.Show Hans.IP4.Dhcp.Options.OverloadOption instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.NetBiosNodeType instance GHC.Show.Show Hans.IP4.Dhcp.Options.NetBiosNodeType instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.OptionTagOrError instance GHC.Show.Show Hans.IP4.Dhcp.Options.OptionTagOrError instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.Dhcp4OptionTag instance GHC.Show.Show Hans.IP4.Dhcp.Options.Dhcp4OptionTag instance GHC.Show.Show Hans.IP4.Dhcp.Options.ControlTag instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.ControlTag instance GHC.Show.Show Hans.IP4.Dhcp.Options.Dhcp4MessageType instance GHC.Classes.Eq Hans.IP4.Dhcp.Options.Dhcp4MessageType instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Options.MagicCookie instance Hans.IP4.Dhcp.Options.Option Hans.IP4.Dhcp.Options.Dhcp4MessageType instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Options.Dhcp4MessageType instance Hans.IP4.Dhcp.Options.Option Hans.IP4.Dhcp.Options.NetBiosNodeType instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Options.NetBiosNodeType instance Hans.IP4.Dhcp.Options.Option Hans.IP4.Dhcp.Options.OverloadOption instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Options.OverloadOption instance Hans.IP4.Dhcp.Codec.CodecAtom a => Hans.IP4.Dhcp.Options.Option [a] instance (Hans.IP4.Dhcp.Codec.CodecAtom a, Hans.IP4.Dhcp.Codec.CodecAtom b) => Hans.IP4.Dhcp.Options.Option (a, b) instance Hans.IP4.Dhcp.Options.Option GHC.Types.Bool instance Hans.IP4.Dhcp.Options.Option GHC.Word.Word8 instance Hans.IP4.Dhcp.Options.Option GHC.Word.Word16 instance Hans.IP4.Dhcp.Options.Option GHC.Word.Word32 instance Hans.IP4.Dhcp.Options.Option Hans.IP4.Packet.IP4 instance Hans.IP4.Dhcp.Options.Option Hans.IP4.Dhcp.Codec.SubnetMask instance Hans.IP4.Dhcp.Options.Option Data.ByteString.Internal.ByteString instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Options.OptionTagOrError instance Hans.IP4.Dhcp.Options.Option Hans.IP4.Dhcp.Options.NVTAsciiString -- | The Dhcp4 module defines the various messages and transitions -- used in the DHCPv4 protocol. This module provides both a high-level -- view of the message types as well as a low-level intermediate form -- which is closely tied to the binary format. -- -- References: RFC 2131 - Dynamic Host Configuration Protocol -- http://www.faqs.org/rfcs/rfc2131.html module Hans.IP4.Dhcp.Packet -- | RequestMessage is a sum of the client request messages. data RequestMessage RequestMessage :: !Request -> RequestMessage DiscoverMessage :: !Discover -> RequestMessage -- | Request is used by the client to accept an offered lease. data Request Request :: !Xid -> Bool -> !IP4 -> !Mac -> [Dhcp4OptionTag] -> Maybe IP4 -> Request -- | Transaction ID of offer [requestXid] :: Request -> !Xid -- | Set True to instruct server to send to broadcast hardware -- address [requestBroadcast] :: Request -> Bool [requestServerAddr] :: Request -> !IP4 -- | Hardware address of the client [requestClientHardwareAddress] :: Request -> !Mac -- | Used to specify the information that client needs [requestParameters] :: Request -> [Dhcp4OptionTag] -- | Used to specify the address which was accepted [requestAddress] :: Request -> Maybe IP4 -- | Discover is used by the client to discover what servers are -- available. This message is sent to the IPv4 broadcast. data Discover Discover :: !Xid -> Bool -> !Mac -> [Dhcp4OptionTag] -> Discover -- | Transaction ID of this and subsequent messages [discoverXid] :: Discover -> !Xid -- | Set True to instruct the server to send to broadcast hardware -- address [discoverBroadcast] :: Discover -> Bool -- | Hardware address of the client [discoverClientHardwareAddr] :: Discover -> !Mac -- | Used to specify the information that client needs in the offers [discoverParameters] :: Discover -> [Dhcp4OptionTag] -- | ServerSettings define all of the information that would be -- needed to act as a DHCP server for one client. The server is defined -- to be able to issue a single "lease" whose parameters are defined -- below. data ServerSettings Settings :: !IP4 -> !Word32 -> !IP4 -> !Word32 -> !SubnetMask -> !IP4 -> [IP4] -> String -> [IP4] -> ServerSettings -- | The IPv4 address of the DHCP server [staticServerAddr] :: ServerSettings -> !IP4 -- | Lease: timezone offset in seconds from UTC [staticTimeOffset] :: ServerSettings -> !Word32 -- | Lease: client IPv4 address on network [staticClientAddr] :: ServerSettings -> !IP4 -- | Lease: duration in seconds [staticLeaseTime] :: ServerSettings -> !Word32 -- | Lease: subnet mask on network [staticSubnet] :: ServerSettings -> !SubnetMask -- | Lease: broadcast address on network [staticBroadcast] :: ServerSettings -> !IP4 -- | Lease: gateway routers on network [staticRouters] :: ServerSettings -> [IP4] -- | Lease: client's assigned domain name [staticDomainName] :: ServerSettings -> String -- | Lease: network DNS servers [staticDNS] :: ServerSettings -> [IP4] -- | ReplyMessage is a sum of the server response messages. data ReplyMessage AckMessage :: !Ack -> ReplyMessage OfferMessage :: !Offer -> ReplyMessage -- | Ack is sent by the DHCPv4 server to acknowledge a sucessful -- Request message. Upon receiving this message the client has -- completed the exchange and has successfully obtained a lease. data Ack Ack :: !Word8 -> !Xid -> !IP4 -> !IP4 -> !IP4 -> !Mac -> !Word32 -> [Dhcp4Option] -> Ack -- | The maximum number of relays this message can use. [ackHops] :: Ack -> !Word8 -- | Transaction ID for this exchange [ackXid] :: Ack -> !Xid -- | Lease: assigned client address [ackYourAddr] :: Ack -> !IP4 -- | DHCP server's IPv4 address [ackServerAddr] :: Ack -> !IP4 -- | DHCP relay server's address [ackRelayAddr] :: Ack -> !IP4 -- | Client's hardware address [ackClientHardwareAddr] :: Ack -> !Mac -- | Lease: duration of lease in seconds [ackLeaseTime] :: Ack -> !Word32 -- | Subset of information requested in previous Request [ackOptions] :: Ack -> [Dhcp4Option] -- | Offer is sent by the DHCPv4 server in response to a -- Discover. This offer is only valid for a short period of time -- as the client might receive many offers. The client must next request -- a lease from a specific server using the information in that server's -- offer. data Offer Offer :: !Word8 -> !Xid -> !IP4 -> !IP4 -> !IP4 -> !Mac -> [Dhcp4Option] -> Offer -- | The maximum number of relays this message can use. [offerHops] :: Offer -> !Word8 -- | Transaction ID of this exchange [offerXid] :: Offer -> !Xid -- | The IPv4 address that this server is willing to lease [offerYourAddr] :: Offer -> !IP4 -- | The IPv4 address of the DHCPv4 server [offerServerAddr] :: Offer -> !IP4 -- | The IPv4 address of the DHCPv4 relay server [offerRelayAddr] :: Offer -> !IP4 -- | The hardware address of the client [offerClientHardwareAddr] :: Offer -> !Mac -- | The options that this server would include in a lease [offerOptions] :: Offer -> [Dhcp4Option] -- | Dhcp4Message is a low-level message container that is very -- close to the binary representation of DHCPv4 message. It is suitable -- for containing any DHCPv4 message. Values of this type should only be -- created using the publicly exported functions. data Dhcp4Message Dhcp4Message :: Dhcp4Op -> !Word8 -> !Xid -> !Word16 -> Bool -> !IP4 -> !IP4 -> !IP4 -> !IP4 -> !Mac -> String -> String -> [Dhcp4Option] -> Dhcp4Message -- | Message op code / message type. 1 = BOOTREQUEST, 2 = BOOTREPLY [dhcp4Op] :: Dhcp4Message -> Dhcp4Op -- | Client sets to zero, optionally used by relay agents when booting via -- a relay agent. [dhcp4Hops] :: Dhcp4Message -> !Word8 -- | Transaction ID, a random number chosen by the client, used by the -- client and server to associate messages and responses between a client -- and a server. [dhcp4Xid] :: Dhcp4Message -> !Xid -- | Filled in by client, seconds elapsed since client began address -- acquisition or renewal process. [dhcp4Secs] :: Dhcp4Message -> !Word16 -- | Client requests messages be sent to hardware broadcast address [dhcp4Broadcast] :: Dhcp4Message -> Bool -- | Client IP address; only filled in if client is in BOUND, RENEW or -- REBINDING state and can respond to ARP requests. [dhcp4ClientAddr] :: Dhcp4Message -> !IP4 -- | your (client) address [dhcp4YourAddr] :: Dhcp4Message -> !IP4 -- | IP address of next server to use in bootstrap; returned in DHCPOFFER, -- DHCPACK by server [dhcp4ServerAddr] :: Dhcp4Message -> !IP4 -- | Relay agent IP address, used in booting via a relay agent [dhcp4RelayAddr] :: Dhcp4Message -> !IP4 -- | Client hardware address [dhcp4ClientHardwareAddr] :: Dhcp4Message -> !Mac -- | Optional server host name, null terminated string [dhcp4ServerHostname] :: Dhcp4Message -> String -- | Boot file name, full terminated string; "generic" name of null in -- DHCPDISCOVER, fully qualified directory-path name in DHCPOFFER [dhcp4BootFilename] :: Dhcp4Message -> String -- | Optional parameters field. [dhcp4Options] :: Dhcp4Message -> [Dhcp4Option] -- | Xid is a Transaction ID, a random number chosen by the client, -- used by the client and server to associate messages and responses -- between a client and a server. newtype Xid Xid :: Word32 -> Xid -- | requestToAck creates Ack messages suitable for -- responding to Request messages given a static -- ServerSettings configuration. requestToAck :: ServerSettings -> Request -> Ack -- | discoverToOffer creates a suitable Offer in response to -- a client's Discover message using the configuration settings -- specified in the given ServerSettings. discoverToOffer :: ServerSettings -> Discover -> Offer -- | mkDiscover creates a new Discover message with a set of -- options suitable for configuring a basic network stack. mkDiscover :: Xid -> Mac -> Discover -- | offerToRequest creates a Request message suitable for -- accepting an Offer from the DHCPv4 server. offerToRequest :: Offer -> Request -- | requestToMessage embeds Request messages in the -- low-level Dhcp4Message type, typically for the purpose of -- serialization. requestToMessage :: Request -> Dhcp4Message -- | ackToMessage embeds Ack messages in the low-level -- Dhcp4Message type, typically for the purpose of serialization. ackToMessage :: Ack -> Dhcp4Message -- | offerToMessage embeds Offer messages in the low-level -- Dhcp4Message type, typically for the purpose of serialization. offerToMessage :: Offer -> Dhcp4Message -- | discoverToMessage embeds Discover messages in the -- low-level Dhcp4Message type, typically for the purpose of -- serialization. discoverToMessage :: Discover -> Dhcp4Message -- | parseDhcpMessage attempts to find a valid high-level message -- contained in a low-level message. The Dhcp4Message is a large -- type and can encode invalid combinations of options. parseDhcpMessage :: Dhcp4Message -> Maybe (Either RequestMessage ReplyMessage) -- | getDhcp4Message is the binary decoder for parsing -- Dhcp4Message values. getDhcp4Message :: Get Dhcp4Message -- | getDhcp4Message is the binary encoder for rendering -- Dhcp4Message values. putDhcp4Message :: Dhcp4Message -> Put instance GHC.Classes.Eq Hans.IP4.Dhcp.Packet.Flags instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Flags instance GHC.Show.Show Hans.IP4.Dhcp.Packet.HardwareType instance GHC.Classes.Eq Hans.IP4.Dhcp.Packet.HardwareType instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Dhcp4Message instance GHC.Classes.Eq Hans.IP4.Dhcp.Packet.Dhcp4Message instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Dhcp4Op instance GHC.Classes.Eq Hans.IP4.Dhcp.Packet.Dhcp4Op instance GHC.Show.Show Hans.IP4.Dhcp.Packet.RequestMessage instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Request instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Discover instance GHC.Show.Show Hans.IP4.Dhcp.Packet.ReplyMessage instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Ack instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Offer instance GHC.Show.Show Hans.IP4.Dhcp.Packet.Xid instance GHC.Classes.Eq Hans.IP4.Dhcp.Packet.Xid instance GHC.Show.Show Hans.IP4.Dhcp.Packet.ServerSettings instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Packet.Xid instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Packet.Dhcp4Op instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Packet.HardwareType instance Hans.IP4.Dhcp.Codec.CodecAtom Hans.IP4.Dhcp.Packet.Flags module Hans.IP4.Fragments data FragTable newFragTable :: Config -> IO FragTable cleanupFragTable :: FragTable -> IO () -- | Handle an incoming fragment. If the fragment is buffered, but doesn't -- complete the packet, the escape continuation is invoked. processFragment :: FragTable -> IP4Header -> ByteString -> Hans (IP4Header, ByteString) instance GHC.Show.Show Hans.IP4.Fragments.Fragment module Hans.IP4.Icmp4 type Lifetime = Word16 getLifetime :: Get Lifetime putLifetime :: Putter Lifetime data Icmp4Packet EchoReply :: !Identifier -> !SequenceNumber -> !ByteString -> Icmp4Packet DestinationUnreachable :: !DestinationUnreachableCode -> !ByteString -> Icmp4Packet SourceQuench :: !ByteString -> Icmp4Packet Redirect :: !RedirectCode -> !IP4 -> !ByteString -> Icmp4Packet Echo :: !Identifier -> !SequenceNumber -> !ByteString -> Icmp4Packet RouterAdvertisement :: !Lifetime -> [RouterAddress] -> Icmp4Packet RouterSolicitation :: Icmp4Packet TimeExceeded :: !TimeExceededCode -> !ByteString -> Icmp4Packet ParameterProblem :: !Word8 -> !ByteString -> Icmp4Packet Timestamp :: !Identifier -> !SequenceNumber -> !Word32 -> !Word32 -> !Word32 -> Icmp4Packet TimestampReply :: !Identifier -> !SequenceNumber -> !Word32 -> !Word32 -> !Word32 -> Icmp4Packet Information :: !Identifier -> !SequenceNumber -> Icmp4Packet InformationReply :: !Identifier -> !SequenceNumber -> Icmp4Packet TraceRoute :: !TraceRouteCode -> !Identifier -> !Word16 -> !Word16 -> !Word32 -> !Word32 -> Icmp4Packet AddressMask :: !Identifier -> !SequenceNumber -> Icmp4Packet AddressMaskReply :: !Identifier -> !SequenceNumber -> !Word32 -> Icmp4Packet noCode :: String -> Get () getIcmp4Packet :: Get Icmp4Packet renderIcmp4Packet :: ChecksumOffload -> Icmp4Packet -> ByteString putIcmp4Packet :: Putter Icmp4Packet data NoCode NoCode :: NoCode data DestinationUnreachableCode NetUnreachable :: DestinationUnreachableCode HostUnreachable :: DestinationUnreachableCode ProtocolUnreachable :: DestinationUnreachableCode PortUnreachable :: DestinationUnreachableCode FragmentationUnreachable :: DestinationUnreachableCode SourceRouteFailed :: DestinationUnreachableCode DestinationNetworkUnknown :: DestinationUnreachableCode DestinationHostUnknown :: DestinationUnreachableCode SourceHostIsolatedError :: DestinationUnreachableCode AdministrativelyProhibited :: DestinationUnreachableCode HostAdministrativelyProhibited :: DestinationUnreachableCode NetworkUnreachableForTOS :: DestinationUnreachableCode HostUnreachableForTOS :: DestinationUnreachableCode CommunicationAdministrativelyProhibited :: DestinationUnreachableCode HostPrecedenceViolation :: DestinationUnreachableCode PrecedenceCutoffInEffect :: DestinationUnreachableCode data TimeExceededCode TimeToLiveExceededInTransit :: TimeExceededCode FragmentReassemblyTimeExceeded :: TimeExceededCode data RedirectCode RedirectForNetwork :: RedirectCode RedirectForHost :: RedirectCode RedirectForTypeOfServiceAndNetwork :: RedirectCode RedirectForTypeOfServiceAndHost :: RedirectCode data TraceRouteCode TraceRouteForwarded :: TraceRouteCode TraceRouteDiscarded :: TraceRouteCode type PreferenceLevel = Int32 data RouterAddress RouterAddress :: IP4 -> PreferenceLevel -> RouterAddress [raAddr] :: RouterAddress -> IP4 [raPreferenceLevel] :: RouterAddress -> PreferenceLevel type Identifier = Word16 getIdentifier :: Get Identifier putIdentifier :: Putter Identifier type SequenceNumber = Word16 getSequenceNumber :: Get SequenceNumber putSequenceNumber :: Putter SequenceNumber getUntilDone :: Serialize a => Get [a] instance GHC.Show.Show Hans.IP4.Icmp4.Icmp4Packet instance GHC.Classes.Eq Hans.IP4.Icmp4.Icmp4Packet instance GHC.Show.Show Hans.IP4.Icmp4.RouterAddress instance GHC.Classes.Eq Hans.IP4.Icmp4.RouterAddress instance GHC.Show.Show Hans.IP4.Icmp4.TraceRouteCode instance GHC.Classes.Eq Hans.IP4.Icmp4.TraceRouteCode instance GHC.Show.Show Hans.IP4.Icmp4.RedirectCode instance GHC.Classes.Eq Hans.IP4.Icmp4.RedirectCode instance GHC.Show.Show Hans.IP4.Icmp4.TimeExceededCode instance GHC.Classes.Eq Hans.IP4.Icmp4.TimeExceededCode instance GHC.Show.Show Hans.IP4.Icmp4.DestinationUnreachableCode instance GHC.Classes.Eq Hans.IP4.Icmp4.DestinationUnreachableCode instance Data.Serialize.Serialize Hans.IP4.Icmp4.NoCode instance Data.Serialize.Serialize Hans.IP4.Icmp4.DestinationUnreachableCode instance Data.Serialize.Serialize Hans.IP4.Icmp4.TimeExceededCode instance Data.Serialize.Serialize Hans.IP4.Icmp4.RedirectCode instance Data.Serialize.Serialize Hans.IP4.Icmp4.TraceRouteCode instance Data.Serialize.Serialize Hans.IP4.Icmp4.RouterAddress module Hans.IP4.RoutingTable data Route Route :: {-# UNPACK #-} !IP4Mask -> !RouteType -> !Device -> Route [routeNetwork] :: Route -> {-# UNPACK #-} !IP4Mask [routeType] :: Route -> !RouteType [routeDevice] :: Route -> !Device data RouteType Direct :: RouteType Indirect :: !IP4 -> RouteType Loopback :: RouteType routeSource :: Route -> IP4 routeNextHop :: IP4 -> Route -> IP4 -- | Simple routing. data RoutingTable empty :: RoutingTable addRule :: Bool -> Route -> RoutingTable -> RoutingTable deleteRule :: IP4Mask -> RoutingTable -> RoutingTable lookupRoute :: IP4 -> RoutingTable -> Maybe Route -- | If the address given is the source address for a rule in the table, -- return the associated Device. isLocal :: IP4 -> RoutingTable -> Maybe Route getRoutes :: RoutingTable -> [Route] -- | Give back routes that involve this device. routesForDev :: Device -> RoutingTable -> [Route] module Hans.IP4.State data IP4State IP4State :: !(IORef RoutingTable) -> !ArpTable -> !FragTable -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> !(BoundedChan ResponderRequest) -> !(IORef StdGen) -> IP4State -- | Addresses currently assigned to devices. [ip4Routes] :: IP4State -> !(IORef RoutingTable) -- | The ARP cache. [ip4ArpTable] :: IP4State -> !ArpTable -- | IP4 packet fragments [ip4Fragments] :: IP4State -> !FragTable -- | Arp retry count [ip4ArpRetry] :: IP4State -> {-# UNPACK #-} !Int [ip4ArpRetryDelay] :: IP4State -> {-# UNPACK #-} !Int [ip4ResponderQueue] :: IP4State -> !(BoundedChan ResponderRequest) [ip4RandomSeed] :: IP4State -> !(IORef StdGen) data SendSource -- | Any interface that will route the message SourceAny :: SendSource -- | The interface with this address SourceIP4 :: !IP4 -> SendSource -- | This device with this source address SourceDev :: !Device -> !IP4 -> SendSource data ResponderRequest -- | Finish sending these IP4 packets Finish :: !Device -> !Mac -> [ByteString] -> ResponderRequest -- | Send this IP4 payload to this address Send :: !SendSource -> !IP4 -> !Bool -> !NetworkProtocol -> ByteString -> ResponderRequest newIP4State :: Config -> IO IP4State class HasIP4State state ip4State :: HasIP4State state => Getting r state IP4State addRoute :: HasIP4State state => state -> Bool -> Route -> IO () -- | Lookup the source address, as well as the next hop and device. lookupRoute4 :: HasIP4State state => state -> IP4 -> IO (Maybe (IP4, IP4, Device)) -- | Is this an address that's assigned to a device in the network stack? isLocalAddr :: HasIP4State state => state -> IP4 -> IO (Maybe Route) -- | Give back the result of using the random function on the -- internal state. nextIdent :: HasIP4State state => state -> IO IP4Ident -- | Give back the list of routing rules associated with this device. routesForDev :: HasIP4State state => state -> Device -> IO [Route] instance Hans.IP4.State.HasIP4State Hans.IP4.State.IP4State module Hans.Addr.Types data Addr Addr4 :: !IP4 -> Addr putAddr :: Addr -> Put showAddr :: Addr -> ShowS sameFamily :: Addr -> Addr -> Bool instance GHC.Generics.Generic Hans.Addr.Types.Addr instance GHC.Show.Show Hans.Addr.Types.Addr instance GHC.Classes.Ord Hans.Addr.Types.Addr instance GHC.Classes.Eq Hans.Addr.Types.Addr instance Data.Hashable.Class.Hashable Hans.Addr.Types.Addr module Hans.Addr data Addr sameFamily :: Addr -> Addr -> Bool class (Hashable addr, Show addr, Typeable addr, Eq addr, Generic addr) => NetworkAddr addr -- | Forget what kind of address this is. toAddr :: NetworkAddr addr => addr -> Addr -- | Try to remember what this opaque address was. fromAddr :: NetworkAddr addr => Addr -> Maybe addr -- | Check to see if this address is the wildcard address. isWildcardAddr :: NetworkAddr addr => addr -> Bool -- | The wildcard address wildcardAddr :: NetworkAddr addr => addr -> addr -- | Check to see if this address is the broadcast address. isBroadcastAddr :: NetworkAddr addr => addr -> Bool -- | The broadcast address. broadcastAddr :: NetworkAddr addr => addr -> addr putAddr :: Addr -> Put showAddr :: Addr -> ShowS instance Hans.Addr.NetworkAddr Hans.Addr.Types.Addr instance Hans.Addr.NetworkAddr Hans.IP4.Packet.IP4 module Hans.Tcp.Tcb type SlowTicks = Int data TcpTimers TcpTimers :: !Bool -> !SlowTicks -> !Bool -> !SlowTicks -> !Int -> !SlowTicks -> !NominalDiffTime -> !NominalDiffTime -> !SlowTicks -> !SlowTicks -> TcpTimers [ttDelayedAck] :: TcpTimers -> !Bool [tt2MSL] :: TcpTimers -> !SlowTicks [ttRetransmitValid] :: TcpTimers -> !Bool [ttRetransmit] :: TcpTimers -> !SlowTicks [ttRetries] :: TcpTimers -> !Int [ttRTO] :: TcpTimers -> !SlowTicks [ttSRTT] :: TcpTimers -> !NominalDiffTime [ttRTTVar] :: TcpTimers -> !NominalDiffTime [ttMaxIdle] :: TcpTimers -> !SlowTicks [ttIdle] :: TcpTimers -> !SlowTicks emptyTcpTimers :: TcpTimers -- | Reset retransmit info. resetRetransmit :: TcpTimers -> (TcpTimers, ()) -- | Increment the retry count, and double the last retransmit timer. retryRetransmit :: TcpTimers -> (TcpTimers, ()) -- | Invalidate the retransmit timer. stopRetransmit :: TcpTimers -> (TcpTimers, ()) reset2MSL :: Config -> TcpTimers -> (TcpTimers, ()) -- | Update all slow-tick timers. Return the old timers, for use with -- 'atomicModifyIORef\''. updateTimers :: TcpTimers -> (TcpTimers, TcpTimers) -- | Calibrate the RTO timer, given a round-trip measurement, as specified -- by RFC-6298. calibrateRTO :: NominalDiffTime -> TcpTimers -> (TcpTimers, ()) data State Listen :: State SynSent :: State SynReceived :: State Established :: State FinWait1 :: State FinWait2 :: State CloseWait :: State Closing :: State LastAck :: State TimeWait :: State Closed :: State class GetState tcb getState :: GetState tcb => tcb -> IO State whenState :: (BaseM m IO, GetState tcb) => tcb -> State -> m () -> m () -- | The Tcb type is the only one that supports changing state. setState :: Tcb -> State -> IO () class CanSend sock getSendWindow :: (CanSend sock, BaseM io IO) => sock -> io (TcpSeqNum, TcpSeqNum) getSndNxt :: (BaseM io IO, CanSend sock) => sock -> io TcpSeqNum getSndWnd :: (BaseM io IO, CanSend sock) => sock -> io TcpSeqNum class CanReceive sock -- | Retrieve the left and right edges of the receive window: -- -- (RCV.NXT, RCV.NXT + RCV.WND) getRecvWindow :: (CanReceive sock, BaseM io IO) => sock -> io (TcpSeqNum, TcpSeqNum) getRcvNxt :: (BaseM io IO, CanReceive sock) => sock -> io TcpSeqNum getRcvWnd :: (BaseM io IO, CanReceive sock) => sock -> io Word16 getRcvRight :: (BaseM io IO, CanReceive sock) => sock -> io TcpSeqNum data ListenTcb ListenTcb :: !Addr -> !TcpPort -> !(IORef AcceptQueue) -> !Signal -> !(IORef TSClock) -> ListenTcb [lSrc] :: ListenTcb -> !Addr [lPort] :: ListenTcb -> !TcpPort [lAccept] :: ListenTcb -> !(IORef AcceptQueue) [lAcceptSignal] :: ListenTcb -> !Signal [lTSClock] :: ListenTcb -> !(IORef TSClock) -- | Create a new listening socket. newListenTcb :: Addr -> TcpPort -> Int -> IO ListenTcb -- | Create a child from a Syn request. createChild :: HasConfig cfg => cfg -> TcpSeqNum -> ListenTcb -> RouteInfo Addr -> Addr -> TcpHeader -> (Tcb -> State -> IO ()) -> (Tcb -> State -> IO ()) -> IO Tcb -- | Reserve a slot in the accept queue, returns True when the space has -- been reserved. reserveSlot :: ListenTcb -> IO Bool -- | Release a slot back to the accept queue. releaseSlot :: ListenTcb -> IO () -- | Wait until a Tcb is available in the accept queue. acceptTcb :: ListenTcb -> IO Tcb data Tcb Tcb :: Maybe ListenTcb -> !(IORef TcbConfig) -> !(IORef State) -> (Tcb -> State -> IO ()) -> (Tcb -> State -> IO ()) -> !SeqNumVar -> !SeqNumVar -> !SeqNumVar -> !SeqNumVar -> !(IORef Window) -> !SeqNumVar -> !SeqNumVar -> !(IORef Bool) -> !(IORef Window) -> !Buffer -> !TcpPort -> !TcpPort -> !(RouteInfo Addr) -> !Addr -> !(IORef Int64) -> !(IORef TcpTimers) -> !(IORef Word32) -> !(IORef TcpSeqNum) -> Tcb -- | Parent to notify if this tcb was generated from a socket in the LISTEN -- state [tcbParent] :: Tcb -> Maybe ListenTcb [tcbConfig] :: Tcb -> !(IORef TcbConfig) [tcbState] :: Tcb -> !(IORef State) [tcbEstablished] :: Tcb -> Tcb -> State -> IO () [tcbClosed] :: Tcb -> Tcb -> State -> IO () -- | SND.UP [tcbSndUp] :: Tcb -> !SeqNumVar -- | SND.WL1 [tcbSndWl1] :: Tcb -> !SeqNumVar -- | SND.WL2 [tcbSndWl2] :: Tcb -> !SeqNumVar -- | ISS [tcbIss] :: Tcb -> !SeqNumVar [tcbSendWindow] :: Tcb -> !(IORef Window) -- | RCV.UP [tcbRcvUp] :: Tcb -> !SeqNumVar -- | IRS [tcbIrs] :: Tcb -> !SeqNumVar [tcbNeedsDelayedAck] :: Tcb -> !(IORef Bool) [tcbRecvWindow] :: Tcb -> !(IORef Window) [tcbRecvBuffer] :: Tcb -> !Buffer -- | Local port [tcbLocalPort] :: Tcb -> !TcpPort -- | Remote port [tcbRemotePort] :: Tcb -> !TcpPort -- | Cached routing [tcbRouteInfo] :: Tcb -> !(RouteInfo Addr) -- | Remote host [tcbRemote] :: Tcb -> !Addr -- | Maximum segment size [tcbMss] :: Tcb -> !(IORef Int64) [tcbTimers] :: Tcb -> !(IORef TcpTimers) [tcbTSRecent] :: Tcb -> !(IORef Word32) [tcbLastAckSent] :: Tcb -> !(IORef TcpSeqNum) newTcb :: HasConfig state => state -> Maybe ListenTcb -> TcpSeqNum -> RouteInfo Addr -> TcpPort -> Addr -> TcpPort -> State -> TSClock -> (Tcb -> State -> IO ()) -> (Tcb -> State -> IO ()) -> IO Tcb -- | Record that a delayed ack should be sent. signalDelayedAck :: Tcb -> IO () -- | Set the value of RCV.NXT. Returns True when the value has been -- set successfully, and False if the receive queue was not empty. setRcvNxt :: TcpSeqNum -> Tcb -> IO Bool -- | Cleanup the Tcb. finalizeTcb :: Tcb -> IO () getSndUna :: BaseM io IO => Tcb -> io TcpSeqNum -- | Reset idle timer in the presence of packets, for use with -- 'atomicModifyIORef\''. resetIdleTimer :: TcpTimers -> (TcpTimers, ()) data TcbConfig TcbConfig :: !Bool -> TcbConfig [tcUseTimestamp] :: TcbConfig -> !Bool -- | True when the timestamp option should be included. usingTimestamps :: Tcb -> IO Bool -- | Disable the use of the timestamp option. disableTimestamp :: Tcb -> IO () -- | Queue bytes in the receive buffer. queueBytes :: ByteString -> Tcb -> IO () -- | Determine if there are bytes in the receive buffer that can be read. haveBytesAvail :: Tcb -> IO Bool -- | Remove data from the receive buffer, and move the right-side of the -- receive window. Reading 0 bytes indicates that the remote side has -- closed the connection. receiveBytes :: Int -> Tcb -> IO ByteString -- | Non-blocking version of receiveBytes. Reading 0 bytes indicates -- that the remote side has closed the connection. tryReceiveBytes :: Int -> Tcb -> IO (Maybe ByteString) data TimeWaitTcb TimeWaitTcb :: !TcpSeqNum -> !SeqNumVar -> !Word16 -> !TcpPort -> !TcpPort -> !(RouteInfo Addr) -> !Addr -> TimeWaitTcb -- | SND.NXT [twSndNxt] :: TimeWaitTcb -> !TcpSeqNum -- | RCV.NXT [twRcvNxt] :: TimeWaitTcb -> !SeqNumVar -- | RCV.WND [twRcvWnd] :: TimeWaitTcb -> !Word16 [twLocalPort] :: TimeWaitTcb -> !TcpPort [twRemotePort] :: TimeWaitTcb -> !TcpPort [twRouteInfo] :: TimeWaitTcb -> !(RouteInfo Addr) [twRemote] :: TimeWaitTcb -> !Addr mkTimeWaitTcb :: Tcb -> IO TimeWaitTcb instance GHC.Classes.Eq Hans.Tcp.Tcb.TimeWaitTcb instance GHC.Show.Show Hans.Tcp.Tcb.State instance GHC.Classes.Eq Hans.Tcp.Tcb.State instance Hans.Tcp.Tcb.GetState Hans.Tcp.Tcb.ListenTcb instance Hans.Tcp.Tcb.GetState Hans.Tcp.Tcb.Tcb instance Hans.Tcp.Tcb.GetState Hans.Tcp.Tcb.TimeWaitTcb instance Hans.Tcp.Tcb.CanSend (GHC.IORef.IORef Hans.Tcp.SendWindow.Window) instance Hans.Tcp.Tcb.CanSend Hans.Tcp.Tcb.Tcb instance Hans.Tcp.Tcb.CanReceive (GHC.IORef.IORef Hans.Tcp.RecvWindow.Window) instance Hans.Tcp.Tcb.CanReceive Hans.Tcp.Tcb.Tcb instance Hans.Tcp.Tcb.CanReceive Hans.Tcp.Tcb.TimeWaitTcb module Hans.Tcp.Message -- |
--   SEQ=SEG.ACKCTL=RST
--   
mkRst :: TcpHeader -> IO TcpHeader -- |
--   SEQ=0ACK=SEG.SEQ+SEG.LENCTL=RST,ACK
--   
mkRstAck :: TcpHeader -> ByteString -> IO TcpHeader mkSyn :: Tcb -> IO TcpHeader -- |
--   SEQ=ISSACK=RCV.NXTCTL=SYN,ACK
--   
mkSynAck :: Tcb -> TcpHeader -> IO TcpHeader mkAck :: TcpSeqNum -> TcpSeqNum -> TcpPort -> TcpPort -> IO TcpHeader module Hans.Tcp.State class HasTcpState state tcpState :: HasTcpState state => Getting r state TcpState data TcpState newTcpState :: Config -> IO TcpState tcpQueue :: HasTcpState state => Getting r state (BoundedChan TcpResponderRequest) -- | Requests that can be made to the responder thread. data TcpResponderRequest SendSegment :: !(RouteInfo Addr) -> !Addr -> !TcpHeader -> !ByteString -> TcpResponderRequest SendWithTcb :: !Tcb -> !TcpHeader -> !ByteString -> TcpResponderRequest -- | Yield back an entry in the Syn backlog. incrSynBacklog :: HasTcpState state => state -> IO () -- | Returns True when there is space in the Syn backlog, and False -- if the connection should be rejected. decrSynBacklog :: HasTcpState state => state -> IO Bool -- | Register a new listening socket. registerListening :: HasTcpState state => state -> ListenTcb -> IO Bool -- | Lookup a socket in the Listen state. lookupListening :: HasTcpState state => state -> Addr -> TcpPort -> IO (Maybe ListenTcb) -- | Remove a listening socket. deleteListening :: HasTcpState state => state -> ListenTcb -> IO () data Key tcbKey :: Getting r Tcb Key tcpActive :: HasTcpState state => Getting r state (HashTable Key Tcb) -- | Lookup an active socket. lookupActive :: HasTcpState state => state -> Addr -> TcpPort -> Addr -> TcpPort -> IO (Maybe Tcb) -- | Register a new active socket. registerActive :: HasTcpState state => state -> Tcb -> IO Bool -- | Delete the Tcb, and notify any waiting processes. closeActive :: HasTcpState state => state -> Tcb -> IO () -- | Delete an active connection from the tcp state. deleteActive :: HasTcpState state => state -> Tcb -> IO () -- | Register a socket in the TimeWait state. If the heap was empty, fork -- off a thread to reap its contents after the timeWaitTimeout. -- -- NOTE: this doesn't remove the original socket from the Active set. registerTimeWait :: (HasConfig state, HasTcpState state) => state -> TimeWaitTcb -> IO () -- | Lookup a socket in the TimeWait state. lookupTimeWait :: HasTcpState state => state -> Addr -> TcpPort -> Addr -> TcpPort -> IO (Maybe TimeWaitTcb) -- | Reset the timer associated with a TimeWaitTcb. resetTimeWait :: (HasConfig state, HasTcpState state) => state -> TimeWaitTcb -> IO () -- | Delete an entry from the TimeWait heap. deleteTimeWait :: HasTcpState state => state -> TimeWaitTcb -> IO () -- | Pick a fresh port for a connection. nextTcpPort :: HasTcpState state => state -> Addr -> Addr -> TcpPort -> IO (Maybe TcpPort) nextIss :: HasTcpState state => state -> Addr -> TcpPort -> Addr -> TcpPort -> IO TcpSeqNum instance GHC.Generics.Generic Hans.Tcp.State.Key instance GHC.Classes.Ord Hans.Tcp.State.Key instance GHC.Classes.Eq Hans.Tcp.State.Key instance GHC.Show.Show Hans.Tcp.State.Key instance GHC.Generics.Generic Hans.Tcp.State.ListenKey instance GHC.Classes.Ord Hans.Tcp.State.ListenKey instance GHC.Classes.Eq Hans.Tcp.State.ListenKey instance GHC.Show.Show Hans.Tcp.State.ListenKey instance Data.Hashable.Class.Hashable Hans.Tcp.State.ListenKey instance Data.Hashable.Class.Hashable Hans.Tcp.State.Key instance Hans.Tcp.State.HasTcpState Hans.Tcp.State.TcpState module Hans.Udp.State data UdpState UdpState :: !(HashTable Key UdpBuffer) -> !(MVar UdpPort) -> !(BoundedChan UdpResponderRequest) -> UdpState [udpRecv] :: UdpState -> !(HashTable Key UdpBuffer) [udpPorts] :: UdpState -> !(MVar UdpPort) [udpQueue_] :: UdpState -> !(BoundedChan UdpResponderRequest) newUdpState :: Config -> IO UdpState class HasUdpState udp udpState :: HasUdpState udp => Getting r udp UdpState type UdpBuffer = Buffer (Device, Addr, UdpPort, Addr, UdpPort) lookupRecv :: HasUdpState state => state -> Addr -> UdpPort -> IO (Maybe UdpBuffer) -- | Register a listener for messages to this address and port, returning -- Just an action to unregister the listener on success. registerRecv :: HasUdpState state => state -> Addr -> UdpPort -> UdpBuffer -> IO (Maybe (IO ())) nextUdpPort :: HasUdpState state => state -> Addr -> IO (Maybe UdpPort) data UdpResponderRequest SendDatagram :: !(RouteInfo Addr) -> !Addr -> !UdpHeader -> !ByteString -> UdpResponderRequest udpQueue :: HasUdpState state => Getting r state (BoundedChan UdpResponderRequest) instance GHC.Generics.Generic Hans.Udp.State.Key instance GHC.Show.Show Hans.Udp.State.Key instance GHC.Classes.Eq Hans.Udp.State.Key instance Data.Hashable.Class.Hashable Hans.Udp.State.Key instance Hans.Udp.State.HasUdpState Hans.Udp.State.UdpState module Hans.Types data InputPacket FromDevice :: !Device -> !ByteString -> InputPacket FromIP4 :: !Device -> !IP4Header -> !ByteString -> InputPacket data NetworkStack NetworkStack :: !Config -> !NatState -> !(BoundedChan InputPacket) -> {-# UNPACK #-} !(IORef [Device]) -> !IP4State -> !ThreadId -> !UdpState -> !ThreadId -> !TcpState -> !ThreadId -> !ThreadId -> !(IORef [IP4]) -> NetworkStack -- | The configuration for this instance of the network stack. [nsConfig] :: NetworkStack -> !Config -- | Nat table/config [nsNat] :: NetworkStack -> !NatState -- | The input packet queue [nsInput] :: NetworkStack -> !(BoundedChan InputPacket) -- | All registered devices [nsDevices] :: NetworkStack -> {-# UNPACK #-} !(IORef [Device]) -- | State for IP4 processing [nsIP4State] :: NetworkStack -> !IP4State -- | Internal IP4 responder for messages produced in teh fast path. [nsIP4Responder] :: NetworkStack -> !ThreadId -- | State for UDP processing [nsUdpState] :: NetworkStack -> !UdpState -- | Responder thread for UDP messages produced in the fast path. [nsUdpResponder] :: NetworkStack -> !ThreadId -- | State for TCP processing [nsTcpState] :: NetworkStack -> !TcpState -- | Responder thread for TCP messages produced in the fast path. [nsTcpResponder] :: NetworkStack -> !ThreadId -- | The TCP timer thread [nsTcpTimers] :: NetworkStack -> !ThreadId [nsNameServers4] :: NetworkStack -> !(IORef [IP4]) class HasNetworkStack ns networkStack :: HasNetworkStack ns => Getting r ns NetworkStack addNameServer4 :: HasNetworkStack ns => ns -> IP4 -> IO () getNameServers4 :: HasNetworkStack ns => ns -> IO [IP4] instance Hans.Config.HasConfig Hans.Types.NetworkStack instance Hans.IP4.State.HasIP4State Hans.Types.NetworkStack instance Hans.Udp.State.HasUdpState Hans.Types.NetworkStack instance Hans.Tcp.State.HasTcpState Hans.Types.NetworkStack instance Hans.Nat.State.HasNatState Hans.Types.NetworkStack instance Hans.Types.HasNetworkStack Hans.Types.NetworkStack module Hans.Device.Loopback -- | A device that just posts outgoing packets back to the input queue. newLoopbackDevice :: NetworkStack -> IO Device module Hans.Device -- | Stop packets flowing, and cleanup any resources associated with this -- device. closeDevice :: Device -> IO () -- | Start processing packets through this device. startDevice :: Device -> IO () module Hans.IP4.Output -- | Send an IP4 packet to the given destination. If it's not possible to -- find a route to the destination, return False. sendIP4 :: NetworkStack -> SendSource -> IP4 -> Bool -> NetworkProtocol -> ByteString -> IO Bool -- | Queue a message on the responder queue instead of attempting to send -- it directly. queueIP4 :: NetworkStack -> DeviceStats -> SendSource -> IP4 -> Bool -> NetworkProtocol -> ByteString -> IO () -- | Prepare IP4 fragments to be sent. prepareIP4 :: NetworkStack -> Device -> IP4 -> IP4 -> Bool -> NetworkProtocol -> ByteString -> IO [ByteString] -- | Send an IP4 packet to the given destination. This assumes that routing -- has already taken place, and that the source and destination addresses -- are correct. primSendIP4 :: NetworkStack -> Device -> IP4 -> IP4 -> IP4 -> Bool -> NetworkProtocol -> ByteString -> IO () responder :: NetworkStack -> IO () queueIcmp4 :: NetworkStack -> Device -> SendSource -> IP4 -> Icmp4Packet -> IO () -- | Emit a destination unreachable ICMP message. This will always be -- queued via the responder queue, as it is most likely coming from the -- fast path. The bytestring argument is assumed to be the original IP4 -- datagram, trimmed to IP4 header + 8 bytes of data. portUnreachable :: NetworkStack -> Device -> SendSource -> IP4 -> ByteString -> IO () module Hans.IP4 module Hans.Network -- | Interaction with routing and message delivery for a network layer. class NetworkAddr addr => Network addr -- | Calculate the pseudo-header for checksumming a packet at this layer of -- the network. pseudoHeader :: Network addr => addr -> addr -> NetworkProtocol -> Int -> PartialChecksum -- | Lookup a route to reach this destination address. lookupRoute :: (Network addr, HasNetworkStack ns) => ns -> addr -> IO (Maybe (RouteInfo addr)) -- | Send a single datagram to a destination. sendDatagram' :: (Network addr, HasNetworkStack ns) => ns -> Device -> addr -> addr -> addr -> Bool -> NetworkProtocol -> ByteString -> IO () sendDatagram :: (HasNetworkStack ns, Network addr) => ns -> RouteInfo addr -> addr -> Bool -> NetworkProtocol -> ByteString -> IO () -- | Send a datagram and lookup routing information at the same time. -- Returns False if no route to the destination was known. routeDatagram :: (HasNetworkStack ns, Network addr) => ns -> addr -> Bool -> NetworkProtocol -> ByteString -> IO Bool findNextHop :: (HasNetworkStack ns, Network addr) => ns -> Maybe Device -> Maybe addr -> addr -> IO (Maybe (RouteInfo addr)) instance Hans.Network.Network Hans.Addr.Types.Addr instance Hans.Network.Network Hans.IP4.Packet.IP4 module Hans.Nat -- | Add a TCP port-forwarding rule. forwardTcpPort :: Network addr => NetworkStack -> addr -> TcpPort -> addr -> TcpPort -> IO () -- | Remove a TCP port-forwarding rule. removeTcpPortForward :: Network addr => NetworkStack -> addr -> TcpPort -> IO () -- | Add a UDP port-forwarding rule. forwardUdpPort :: Network addr => NetworkStack -> addr -> UdpPort -> addr -> UdpPort -> IO () -- | Remove a UDP port-forwarding rule. removeUdpPortForward :: Network addr => NetworkStack -> addr -> UdpPort -> IO () module Hans.Tcp.Output -- | Send outgoing tcp segments, with a route calculation. -- -- See note "No Retransmit Queue" -- (Hans.Tcp.Output#no-retransmit-queue). routeTcp :: Network addr => NetworkStack -> Device -> addr -> addr -> TcpHeader -> ByteString -> IO Bool -- | Lowest-level output function for TCP. -- -- See note "No Retransmit Queue" -- (Hans.Tcp.Output#no-retransmit-queue). sendTcp :: Network addr => NetworkStack -> RouteInfo addr -> addr -> TcpHeader -> ByteString -> IO Bool -- | Send a segment and queue it in the remote window. The number of bytes -- that were sent is returned. sendWithTcb :: NetworkStack -> Tcb -> TcpHeader -> ByteString -> IO (Maybe Int64) -- | Send a single ACK immediately. sendAck :: NetworkStack -> Tcb -> IO () -- | Send a single FIN packet. sendFin :: NetworkStack -> Tcb -> IO () -- | Send a data segment, potentially sending multiple packets if the send -- window allows, and the payload is larger than MSS. When the remote -- window is full, this returns 0. sendData :: NetworkStack -> Tcb -> ByteString -> IO Int64 -- | Determine if there is any room in the remote window for us to send -- data. canSend :: Tcb -> IO Bool -- | Queue an outgoing TCP segment from the fast-path. -- -- See note "No Retransmit Queue" -- (Hans.Tcp.Output#no-retransmit-queue). queueTcp :: NetworkStack -> RouteInfo Addr -> Addr -> TcpHeader -> ByteString -> IO Bool -- | Queue an outgoing TCP segment from the fast-path. queueWithTcb :: NetworkStack -> Tcb -> TcpHeader -> ByteString -> IO Bool -- | Queue an ACK from the fast-path. queueAck :: NetworkStack -> Tcb -> IO Bool -- | Responder thread for messages generated in the fast-path. responder :: NetworkStack -> IO () module Hans.Tcp.Input -- | Process incoming tcp segments. processTcp :: Network addr => NetworkStack -> Device -> addr -> addr -> ByteString -> Hans () module Hans.Tcp.Timers -- | Process the slow and fast tcp timers. The fast timer runs four times a -- second, while the slow timer runs two times a second. tcpTimers :: NetworkStack -> IO () -- | The body of the fast and slow tick handlers. The boolean indicates -- whether or not the slow tick should also be run. updateActive :: NetworkStack -> Bool -> Tcb -> IO () -- | Handle the retransmit timer. When the timer expires, if there is -- anything in the send window, retransmit the left-most segment. handleRTO :: NetworkStack -> Tcb -> TcpTimers -> IO () -- | Make sure that the connection is still active. The Idle timer is -- checked when the 2MSL timer expires. handle2MSL :: NetworkStack -> Tcb -> TcpTimers -> IO () module Hans.Udp.Output -- | Send Udp over IP4 with a pre-computed route. primSendUdp :: Network addr => NetworkStack -> RouteInfo addr -> addr -> UdpPort -> UdpPort -> ByteString -> IO Bool responder :: NetworkStack -> IO () queueUdp :: NetworkStack -> RouteInfo Addr -> Addr -> UdpHeader -> ByteString -> IO Bool module Hans.Socket class Socket sock -- | Close an open socket. sClose :: (Socket sock, Network addr) => sock addr -> IO () class (DataSocket (Client sock), Socket sock) => ListenSocket sock where type Client sock :: * -> * where { type family Client sock :: * -> *; } -- | Create a listening socket, with a backlog of n. sListen :: (ListenSocket sock, HasNetworkStack ns, Network addr) => ns -> SocketConfig -> addr -> SockPort -> Int -> IO (sock addr) sAccept :: (ListenSocket sock, Network addr) => sock addr -> IO (Client sock addr) class Socket sock => DataSocket sock -- | Connect this socket to one on a remote machine. sConnect :: (DataSocket sock, HasNetworkStack ns, Network addr) => ns -> SocketConfig -> Maybe Device -> addr -> Maybe SockPort -> addr -> SockPort -> IO (sock addr) -- | Returns True iff there is currently space in the buffer to accept a -- write. Note, this is probably a bad thing to count on in a concurrent -- system ... sCanWrite :: (DataSocket sock, Network addr) => sock addr -> IO Bool -- | Send a chunk of data on a socket. sWrite :: (DataSocket sock, Network addr) => sock addr -> ByteString -> IO Int -- | Returns True iff there is data in the buffer that can be read. Note, -- this is probably a bad thing to count on in a concurrent system ... sCanRead :: (DataSocket sock, Network addr) => sock addr -> IO Bool -- | Read a chunk of data from a socket. Reading an empty result indicates -- that the socket has closed. sRead :: (DataSocket sock, Network addr) => sock addr -> Int -> IO ByteString -- | Non-blocking read from a socket. Reading an empty result means that -- the socket has closed, while reading a Nothing result indicates -- that there was no data available. sTryRead :: (DataSocket sock, Network addr) => sock addr -> Int -> IO (Maybe ByteString) data SocketConfig SocketConfig :: !Int -> SocketConfig -- | Bytes to buffer [scRecvBufferSize] :: SocketConfig -> !Int defaultSocketConfig :: SocketConfig type SockPort = Word16 data UdpSocket addr newUdpSocket :: (HasNetworkStack ns, Network addr) => ns -> SocketConfig -> Maybe Device -> addr -> Maybe SockPort -> IO (UdpSocket addr) -- | Send to a specific end host. sendto :: Network addr => UdpSocket addr -> addr -> SockPort -> ByteString -> IO () -- | Receive, with information about who sent this datagram. recvfrom :: Network addr => UdpSocket addr -> IO (Device, addr, SockPort, ByteString) recvfrom' :: Network addr => UdpSocket addr -> IO (Device, addr, SockPort, addr, ByteString) data TcpSocket addr data TcpListenSocket addr -- | The remote address of this socket. tcpRemoteAddr :: NetworkAddr addr => Getting r (TcpSocket addr) addr -- | The remote port of this socket. tcpRemotePort :: Getting r (TcpSocket addr) SockPort -- | The source address of this socket. tcpLocalAddr :: NetworkAddr addr => Getting r (TcpSocket addr) addr -- | The local port for this socket. tcpLocalPort :: Getting r (TcpSocket addr) SockPort data ConnectionException data ListenException data RoutingException module Hans.Dns type HostName = ByteString data HostEntry HostEntry :: HostName -> [HostName] -> [IP4] -> HostEntry [hostName] :: HostEntry -> HostName [hostAliases] :: HostEntry -> [HostName] [hostAddresses] :: HostEntry -> [IP4] parseHostEntry :: Source -> [RR] -> HostEntry -- | Parse the A and CNAME parts out of a response. parseAddr :: HostName -> [RR] -> HostEntry parsePtr :: IP4 -> [RR] -> HostEntry data DnsException NoNameServers :: DnsException getHostByName :: HasNetworkStack ns => ns -> HostName -> IO (Maybe HostEntry) sendRequest :: HasNetworkStack ns => ns -> Source -> IO (Maybe HostEntry) queryServers4 :: UdpSocket IP4 -> ByteString -> [IP4] -> IO (Maybe DNSPacket) data Source FromHost :: HostName -> Source FromAddr4 :: IP4 -> Source sourceHost :: Source -> Name toLabels :: HostName -> Name sourceQType :: Source -> [QType] mkPacket :: Source -> Word16 -> DNSPacket instance GHC.Show.Show Hans.Dns.Source instance GHC.Show.Show Hans.Dns.DnsException instance GHC.Show.Show Hans.Dns.HostEntry instance GHC.Exception.Exception Hans.Dns.DnsException module Hans.IP4.Dhcp.Client data DhcpConfig DhcpConfig :: !NominalDiffTime -> !Int -> Bool -> Bool -> DhcpConfig -- | Initial timeout [dcInitialTimeout] :: DhcpConfig -> !NominalDiffTime -- | Number of retries [dcRetries] :: DhcpConfig -> !Int -- | Whether or not routing information received from the DHCP server -- should be used as the default route for the network stack. [dcDefaultRoute] :: DhcpConfig -> Bool -- | Whether or not to fork a renew thread once configuration information -- has been received. [dcAutoRenew] :: DhcpConfig -> Bool defaultDhcpConfig :: DhcpConfig data DhcpLease DhcpLease :: !(IO ()) -> !IP4 -> DhcpLease [dhcpRenew] :: DhcpLease -> !(IO ()) [dhcpAddr] :: DhcpLease -> !IP4 dhcpClient :: NetworkStack -> DhcpConfig -> Device -> IO (Maybe DhcpLease) module Hans.Socket.Handle -- | Make a GHC Handle from a Hans handle. makeHansHandle :: (Socket sock, DataSocket sock, Network addr, Typeable sock) => sock addr -> IOMode -> IO Handle instance (Hans.Socket.Types.Socket sock, Hans.Socket.Types.DataSocket sock, Hans.Network.Network addr) => GHC.IO.Device.IODevice (sock addr) instance (Hans.Socket.Types.Socket sock, Hans.Socket.Types.DataSocket sock, Hans.Network.Network addr) => GHC.IO.Device.RawIO (sock addr) instance (Hans.Socket.Types.Socket sock, Hans.Socket.Types.DataSocket sock, Hans.Network.Network addr) => GHC.IO.BufferedIO.BufferedIO (sock addr) module Hans.Udp.Input -- | Process a message destined for the UDP layer. When the message cannot -- be routed, False is returned. processUdp :: Network addr => NetworkStack -> Device -> addr -> addr -> ByteString -> Hans Bool module Hans.IP4.Input -- | Handle incoming Arp packets. processArp :: NetworkStack -> Device -> ByteString -> Hans () -- | Process a packet that has arrived from a device. processIP4 :: NetworkStack -> Device -> ByteString -> Hans () -- | The processing stage after the packet has been decoded and validated. -- It's exposed here so that routing to an address that's managed by the -- network stack can skip the device layer. handleIP4 :: NetworkStack -> Device -> Maybe (Int, ByteString) -> IP4Header -> ByteString -> Hans () module Hans.Input -- | Handle incoming packets. processPackets :: NetworkStack -> IO () processEthernet :: NetworkStack -> Device -> ByteString -> Hans () module Hans data NetworkStack -- | General network stack configuration. data Config Config :: !Int -> !Int -> !NominalDiffTime -> !Int -> !Int -> !NominalDiffTime -> !Word8 -> !Int -> !Int -> !Int -> !Int -> !Int -> !NominalDiffTime -> !Int -> !Int -> !Int -> !Int -> !NominalDiffTime -> !Int -> !Int -> Config [cfgInputQueueSize] :: Config -> !Int -- | Best to pick a prime number. [cfgArpTableSize] :: Config -> !Int [cfgArpTableLifetime] :: Config -> !NominalDiffTime -- | Number of times to retry an arp request before failing [cfgArpRetry] :: Config -> !Int -- | The amount of time to wait between arp request retransmission. [cfgArpRetryDelay] :: Config -> !Int -- | Number of seconds to wait before expiring a partially reassembled IP4 -- packet [cfgIP4FragTimeout] :: Config -> !NominalDiffTime [cfgIP4InitialTTL] :: Config -> !Word8 -- | Maximum packets being reassembled at any time. [cfgIP4MaxFragTableEntries] :: Config -> !Int -- | Number of buckets in the udp socket table [cfgUdpSocketTableSize] :: Config -> !Int -- | In microseconds [cfgDnsResolveTimeout] :: Config -> !Int -- | Small-ish prime number [cfgTcpListenTableSize] :: Config -> !Int -- | Best to pick a prime number [cfgTcpActiveTableSize] :: Config -> !Int -- | Time to remain in TimeWait, in seconds. [cfgTcpTimeoutTimeWait] :: Config -> !NominalDiffTime -- | Initial MSS for tcp connections [cfgTcpInitialMSS] :: Config -> !Int -- | Maximum number of connections waiting for an acknowledgement. [cfgTcpMaxSynBacklog] :: Config -> !Int -- | Initial local window for tcp connections. [cfgTcpInitialWindow] :: Config -> !Int -- | Maximum segment lifetime [cfgTcpMSL] :: Config -> !Int -- | Frequency (in Hz) of timestamp clock updates. Should be between 1Hz -- and 1000Hz, according to RFC-1323. [cfgTcpTSClockFrequency] :: Config -> !NominalDiffTime -- | The max number of threads allowed in the time wait heap. [cfgTcpTimeWaitSocketLimit] :: Config -> !Int -- | The maximum number of entries allowed in the TCP or UDP NAT tables [cfgNatMaxEntries] :: Config -> !Int defaultConfig :: Config -- | Create a network stack with no devices registered. newNetworkStack :: Config -> IO NetworkStack -- | Handle incoming packets. processPackets :: NetworkStack -> IO () type DeviceName = ByteString data Device -- | Static configuration data for creating a device. data DeviceConfig DeviceConfig :: {-# UNPACK #-} !Int -> !ChecksumOffload -> !ChecksumOffload -> !Int -> DeviceConfig -- | How large the send queue should be. [dcSendQueueLen] :: DeviceConfig -> {-# UNPACK #-} !Int [dcTxOffload] :: DeviceConfig -> !ChecksumOffload [dcRxOffload] :: DeviceConfig -> !ChecksumOffload [dcMtu] :: DeviceConfig -> !Int defaultDeviceConfig :: DeviceConfig -- | Initialize and register a device with the network stack. NOTE: this -- does not start the device. addDevice :: NetworkStack -> DeviceName -> DeviceConfig -> IO Device -- | Not sure how this should work yet... Should it only ever show tap -- device names? Maybe this should return a singleton list of an -- ephemeral device? listDevices :: IO [DeviceName] -- | Stop packets flowing, and cleanup any resources associated with this -- device. closeDevice :: Device -> IO () -- | Start processing packets through this device. startDevice :: Device -> IO () data Addr sameFamily :: Addr -> Addr -> Bool class (Hashable addr, Show addr, Typeable addr, Eq addr, Generic addr) => NetworkAddr addr -- | Forget what kind of address this is. toAddr :: NetworkAddr addr => addr -> Addr -- | Try to remember what this opaque address was. fromAddr :: NetworkAddr addr => Addr -> Maybe addr -- | Check to see if this address is the wildcard address. isWildcardAddr :: NetworkAddr addr => addr -> Bool -- | The wildcard address wildcardAddr :: NetworkAddr addr => addr -> addr -- | Check to see if this address is the broadcast address. isBroadcastAddr :: NetworkAddr addr => addr -> Bool -- | The broadcast address. broadcastAddr :: NetworkAddr addr => addr -> addr -- | Interaction with routing and message delivery for a network layer. class NetworkAddr addr => Network addr -- | Calculate the pseudo-header for checksumming a packet at this layer of -- the network. pseudoHeader :: Network addr => addr -> addr -> NetworkProtocol -> Int -> PartialChecksum -- | Lookup a route to reach this destination address. lookupRoute :: (Network addr, HasNetworkStack ns) => ns -> addr -> IO (Maybe (RouteInfo addr)) -- | Send a single datagram to a destination. sendDatagram' :: (Network addr, HasNetworkStack ns) => ns -> Device -> addr -> addr -> addr -> Bool -> NetworkProtocol -> ByteString -> IO () -- | Information about how to reach a specific destination address (source -- and next-hop addresses, and device to use). data RouteInfo addr RouteInfo :: !addr -> !addr -> !Device -> RouteInfo addr -- | The source address to use when sending [riSource] :: RouteInfo addr -> !addr -- | The next-hop in the route [riNext] :: RouteInfo addr -> !addr -- | The device used for delivery [riDev] :: RouteInfo addr -> !Device data IP4 packIP4 :: Word8 -> Word8 -> Word8 -> Word8 -> IP4 unpackIP4 :: IP4 -> (Word8, Word8, Word8, Word8) data IP4Mask -- | Between 0 and 32 IP4Mask :: {-# UNPACK #-} !IP4 -> {-# UNPACK #-} !Int -> IP4Mask data Route Route :: {-# UNPACK #-} !IP4Mask -> !RouteType -> !Device -> Route [routeNetwork] :: Route -> {-# UNPACK #-} !IP4Mask [routeType] :: Route -> !RouteType [routeDevice] :: Route -> !Device data RouteType Direct :: RouteType Indirect :: !IP4 -> RouteType -- | Add a route to the IP4 layer. addIP4Route :: NetworkStack -> Bool -> Route -> IO ()