module Hans.Layer.Arp.Table where
import Hans.Address.Mac
import Hans.Address.IP4
import Control.Arrow (second)
import Data.Time.Clock.POSIX (POSIXTime)
import qualified Data.Map as Map
arpEntryTimeout :: POSIXTime
arpEntryTimeout = 60
data ArpEntry
= ArpEntry { arpMac :: Mac
, arpTimeout :: POSIXTime
}
| ArpPending { arpTimeout :: POSIXTime
}
deriving Show
data ArpResult
= KnownAddress Mac
| Pending
| Unknown
type ArpTable = Map.Map IP4 ArpEntry
stepArpTable :: POSIXTime -> ArpTable -> (ArpTable, [IP4])
stepArpTable now tab = second (Map.keys) (Map.partition p tab)
where
p ent = arpTimeout ent >= now
addArpEntry :: POSIXTime -> IP4 -> Mac -> ArpTable -> ArpTable
addArpEntry now ip mac = Map.insert ip ent where
ent = ArpEntry
{ arpMac = mac
, arpTimeout = now + arpEntryTimeout
}
addPending :: POSIXTime -> IP4 -> ArpTable -> ArpTable
addPending now ip = Map.insert ip ent where
ent = ArpPending
{ arpTimeout = now + arpEntryTimeout
}
lookupArpEntry :: IP4 -> ArpTable -> ArpResult
lookupArpEntry ip arp =
case Map.lookup ip arp of
Just (ArpEntry mac _) -> KnownAddress mac
Just (ArpPending _) -> Pending
_ -> Unknown