iptadmin-1.1.0: src/IptAdmin/ShowPage.hs
{-# LANGUAGE OverloadedStrings #-}
module IptAdmin.ShowPage where
import Control.Monad.Error
import Control.Monad.State
import Data.IORef
import Data.Map
import Happstack.Server.SimpleHTTP
import Template
import IptAdmin.Render
import IptAdmin.ShowPage.Render
import IptAdmin.System
import IptAdmin.Types
import IptAdmin.Utils
import Iptables
import Iptables.Types
import System.Random
import Text.Blaze
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
import Text.Blaze.Renderer.String (renderHtml)
pageHandlers :: IptAdmin Response
pageHandlers = msum [ methodSP GET pageHandlerGet
, methodSP POST pageHandlerPost
]
pageHandlerGet :: IptAdmin Response
pageHandlerGet = do
table <- getInputOrEmptyString "table"
iptables <- getIptables
countType <- do
setCountType <- getInputOrEmptyString "countersType"
case setCountType of
"bytes" -> do
let countTypeCookie = mkCookie "countersType" "Bytes"
addCookie (60 * 60 * 24 * 365 * 10) countTypeCookie
return CTBytes
"packets" -> do
let countTypeCookie = mkCookie "countersType" "Packets"
addCookie (60 * 60 * 24 * 365 * 10) countTypeCookie
return CTPackets
_ -> do
countTypeMay <- getDataFn $ lookCookieValue "countersType"
case countTypeMay of
Nothing -> return CTPackets
Just "Bytes" -> return CTBytes
_ -> return CTPackets
(sessionId, sessionsIO, _) <- lift get
sessions <- liftIO $ readIORef sessionsIO
let session = sessions Data.Map.! sessionId
iptables' <- if sIptables session /= iptables
then
liftIO $ atomicModifyIORef sessionsIO $
\ sessions' ->
( insert sessionId (session {sIptables = iptables}) sessions'
, iptables)
else
return $ sIptables session
case table of
"" -> showFilter countType iptables iptables'
"filter" -> showFilter countType iptables iptables'
"nat" -> showNat countType iptables iptables'
"mangle" -> showMangle countType iptables iptables'
"raw" -> throwError "We're sorry, the Raw table is not supported yet"
a -> throwError $ "Invalid table parameter: " ++ a
maxPacketCounterDiff :: [(Chain, Chain)] -> Integer
maxPacketCounterDiff [] = 0
maxPacketCounterDiff ((x,x'):xs) = max (maxPacketCounterDiff' (x,x')) (maxPacketCounterDiff xs)
where
maxPacketCounterDiff' :: (Chain, Chain) -> Integer
maxPacketCounterDiff' (Chain _ _ (Counters p _) rs, Chain _ _ (Counters p' _) rs') = max (p - p') (maxPacketCounterDiff'' $ zip rs rs')
maxPacketCounterDiff'' :: [(Rule, Rule)] -> Integer
maxPacketCounterDiff'' [] = 0
maxPacketCounterDiff'' ((Rule (Counters p _) _ _, Rule (Counters p' _) _ _):rs) = max (p - p') (maxPacketCounterDiff'' rs)
showFilter :: CountersType -> Iptables -> Iptables -> IptAdmin Response
showFilter countType iptables iptables' = do
refreshString <- liftIO $ show `fmap` (randomRIO (1,100000) :: IO Int)
let filter' = renderTable ("filter", "Filter")
countType
(maxPacketCounterDiff $ zip (sortFilterTable $ tFilter iptables) (sortFilterTable $ tFilter iptables'))
refreshString
(sortFilterTable $ tFilter iptables)
(sortFilterTable $ tFilter iptables')
return $ buildResponse $ Template.htmlWrapper $ renderHtml $ do
header "filter" "Iptables Filter table"
showPageHtml filter'
showNat :: CountersType -> Iptables -> Iptables -> IptAdmin Response
showNat countType iptables iptables' = do
refreshString <- liftIO $ show `fmap` (randomRIO (1,100000) :: IO Int)
let nat = renderTable ("nat", "Nat")
countType
(maxPacketCounterDiff $ zip (sortNatTable $ tNat iptables) (sortNatTable $ tNat iptables'))
refreshString
(sortNatTable $ tNat iptables)
(sortNatTable $ tNat iptables')
return $ buildResponse $ Template.htmlWrapper $ renderHtml $ do
header "nat" "Iptables Nat table"
showPageHtml nat
showMangle :: CountersType -> Iptables -> Iptables -> IptAdmin Response
showMangle countType iptables iptables' = do
refreshString <- liftIO $ show `fmap` (randomRIO (1,100000) :: IO Int)
let mangle = renderTable ("mangle", "Mangle")
countType
(maxPacketCounterDiff $ zip (sortMangleTable $ tMangle iptables) (sortMangleTable $ tMangle iptables'))
refreshString
(sortMangleTable $ tMangle iptables)
(sortMangleTable $ tMangle iptables')
return $ buildResponse $ Template.htmlWrapper $ renderHtml $ do
header "mangle" "Iptables Mangle table. Rule editing is not supported for Mangle yet."
showPageHtml mangle
showPageHtml :: Html -> Html
showPageHtml table =
H.div H.! A.id "rules" $
table
pageHandlerPost :: IptAdmin Response
pageHandlerPost = do
actionS <- getInputOrEmptyString "action"
case actionS of
"reset" -> do
tableName <- getInputOrEmptyString "table"
chainName <- getInputString "chain"
iptables <- getIptables
(sessionId, sessionsIO, _) <- lift get
sessions <- liftIO $ readIORef sessionsIO
let session = sessions Data.Map.! sessionId
liftIO $ atomicModifyIORef sessionsIO $
\ sessions' ->
( insert sessionId (session {sIptables = iptables}) sessions'
, ())
redir $ "/show?table=" ++ tableName ++ bookmarkForJump chainName Nothing
"" -> throwError "'action' parameter is not specified"
a -> throwError $ "unknown value of 'action' parameter: " ++ a