-- | Maintainer: Arnaud Bailly <arnaud.oqube@gmail.com>
--
-- Properties for configuring firewall (iptables) rules

module Propellor.Property.Firewall (
	rule,
	installed,
	Chain(..),
	Table(..),
	Target(..),
	Proto(..),
	Rules(..),
	ConnectionState(..),
	ICMPTypeMatch(..),
	TCPFlag(..),
	Frequency(..),
	IPWithMask(..),
) where

import qualified Data.Semigroup as Sem
import Data.Char
import Data.List

import Propellor.Base
import qualified Propellor.Property.Apt as Apt
import qualified Propellor.Property.Network as Network

installed :: Property DebianLike
installed :: Property DebianLike
installed = [Package] -> Property DebianLike
Apt.installed [Package
"iptables"]

rule :: Chain -> Table -> Target -> Rules -> Property Linux
rule :: Chain -> Table -> Target -> Rules -> Property Linux
rule Chain
c Table
tb Target
tg Rules
rs = Package -> Propellor Result -> Property Linux
forall k (metatypes :: k).
SingI metatypes =>
Package -> Propellor Result -> Property (MetaTypes metatypes)
property (Package
"firewall rule: " Package -> Package -> Package
forall a. Semigroup a => a -> a -> a
<> Rule -> Package
forall a. Show a => a -> Package
show Rule
r) Propellor Result
addIpTable
  where
	r :: Rule
r = Chain -> Table -> Target -> Rules -> Rule
Rule Chain
c Table
tb Target
tg Rules
rs
	addIpTable :: Propellor Result
addIpTable = IO Result -> Propellor Result
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Result -> Propellor Result) -> IO Result -> Propellor Result
forall a b. (a -> b) -> a -> b
$ do
		let args :: [CommandParam]
args = Rule -> [CommandParam]
toIpTable Rule
r
		Bool
exist <- Package -> [CommandParam] -> IO Bool
boolSystem Package
"iptables" ([CommandParam] -> [CommandParam]
chk [CommandParam]
args)
		if Bool
exist
			then Result -> IO Result
forall (m :: * -> *) a. Monad m => a -> m a
return Result
NoChange
			else Bool -> Result
forall t. ToResult t => t -> Result
toResult (Bool -> Result) -> IO Bool -> IO Result
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Package -> [CommandParam] -> IO Bool
boolSystem Package
"iptables" ([CommandParam] -> [CommandParam]
add [CommandParam]
args)
	add :: [CommandParam] -> [CommandParam]
add [CommandParam]
params = Package -> CommandParam
Param Package
"-A" CommandParam -> [CommandParam] -> [CommandParam]
forall a. a -> [a] -> [a]
: [CommandParam]
params
	chk :: [CommandParam] -> [CommandParam]
chk [CommandParam]
params = Package -> CommandParam
Param Package
"-C" CommandParam -> [CommandParam] -> [CommandParam]
forall a. a -> [a] -> [a]
: [CommandParam]
params

toIpTable :: Rule -> [CommandParam]
toIpTable :: Rule -> [CommandParam]
toIpTable Rule
r =  (Package -> CommandParam) -> [Package] -> [CommandParam]
forall a b. (a -> b) -> [a] -> [b]
map Package -> CommandParam
Param ([Package] -> [CommandParam]) -> [Package] -> [CommandParam]
forall a b. (a -> b) -> a -> b
$
	Chain -> Package
forall t. ConfigurableValue t => t -> Package
val (Rule -> Chain
ruleChain Rule
r) Package -> [Package] -> [Package]
forall a. a -> [a] -> [a]
:
	[Package
"-t", Table -> Package
forall t. ConfigurableValue t => t -> Package
val (Rule -> Table
ruleTable Rule
r), Package
"-j", Target -> Package
forall t. ConfigurableValue t => t -> Package
val (Rule -> Target
ruleTarget Rule
r)] [Package] -> [Package] -> [Package]
forall a. [a] -> [a] -> [a]
++
	Rules -> [Package]
toIpTableArg (Rule -> Rules
ruleRules Rule
r)

toIpTableArg :: Rules -> [String]
toIpTableArg :: Rules -> [Package]
toIpTableArg Rules
Everything = []
toIpTableArg (Proto Proto
proto) = [Package
"-p", (Char -> Char) -> Package -> Package
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower (Package -> Package) -> Package -> Package
forall a b. (a -> b) -> a -> b
$ Proto -> Package
forall a. Show a => a -> Package
show Proto
proto]
toIpTableArg (DPort Port
port) = [Package
"--dport", Port -> Package
forall t. ConfigurableValue t => t -> Package
val Port
port]
toIpTableArg (DPortRange (Port
portf, Port
portt)) =
	[Package
"--dport", Port -> Package
forall t. ConfigurableValue t => t -> Package
val Port
portf Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Package
":" Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Port -> Package
forall t. ConfigurableValue t => t -> Package
val Port
portt]
toIpTableArg (InIFace Package
iface) = [Package
"-i", Package
iface]
toIpTableArg (OutIFace Package
iface) = [Package
"-o", Package
iface]
toIpTableArg (Ctstate [ConnectionState]
states) =
	[ Package
"-m"
	, Package
"conntrack"
	, Package
"--ctstate", Package -> [Package] -> Package
forall a. [a] -> [[a]] -> [a]
intercalate Package
"," ((ConnectionState -> Package) -> [ConnectionState] -> [Package]
forall a b. (a -> b) -> [a] -> [b]
map ConnectionState -> Package
forall a. Show a => a -> Package
show [ConnectionState]
states)
	]
toIpTableArg (ICMPType ICMPTypeMatch
i) =
	[ Package
"-m"
	, Package
"icmp"
	, Package
"--icmp-type", ICMPTypeMatch -> Package
forall t. ConfigurableValue t => t -> Package
val ICMPTypeMatch
i
	]
toIpTableArg (RateLimit Frequency
f) =
	[ Package
"-m"
	, Package
"limit"
	, Package
"--limit", Frequency -> Package
forall t. ConfigurableValue t => t -> Package
val Frequency
f
	]
toIpTableArg (TCPFlags TCPFlagMask
m TCPFlagMask
c) =
	[ Package
"-m"
	, Package
"tcp"
	, Package
"--tcp-flags"
	, Package -> [Package] -> Package
forall a. [a] -> [[a]] -> [a]
intercalate Package
"," ((TCPFlag -> Package) -> TCPFlagMask -> [Package]
forall a b. (a -> b) -> [a] -> [b]
map TCPFlag -> Package
forall a. Show a => a -> Package
show TCPFlagMask
m)
	, Package -> [Package] -> Package
forall a. [a] -> [[a]] -> [a]
intercalate Package
"," ((TCPFlag -> Package) -> TCPFlagMask -> [Package]
forall a b. (a -> b) -> [a] -> [b]
map TCPFlag -> Package
forall a. Show a => a -> Package
show TCPFlagMask
c)
	]
toIpTableArg Rules
TCPSyn = [Package
"--syn"]
toIpTableArg (GroupOwner (Group Package
g)) =
	[ Package
"-m"
	, Package
"owner"
	, Package
"--gid-owner"
	, Package
g
	]
toIpTableArg (Source [IPWithMask]
ipwm) =
	[ Package
"-s"
	, Package -> [Package] -> Package
forall a. [a] -> [[a]] -> [a]
intercalate Package
"," ((IPWithMask -> Package) -> [IPWithMask] -> [Package]
forall a b. (a -> b) -> [a] -> [b]
map IPWithMask -> Package
forall t. ConfigurableValue t => t -> Package
val [IPWithMask]
ipwm)
	]
toIpTableArg (Destination [IPWithMask]
ipwm) =
	[ Package
"-d"
	, Package -> [Package] -> Package
forall a. [a] -> [[a]] -> [a]
intercalate Package
"," ((IPWithMask -> Package) -> [IPWithMask] -> [Package]
forall a b. (a -> b) -> [a] -> [b]
map IPWithMask -> Package
forall t. ConfigurableValue t => t -> Package
val [IPWithMask]
ipwm)
	]
toIpTableArg (NotDestination [IPWithMask]
ipwm) =
	[ Package
"!"
	, Package
"-d"
	, Package -> [Package] -> Package
forall a. [a] -> [[a]] -> [a]
intercalate Package
"," ((IPWithMask -> Package) -> [IPWithMask] -> [Package]
forall a b. (a -> b) -> [a] -> [b]
map IPWithMask -> Package
forall t. ConfigurableValue t => t -> Package
val [IPWithMask]
ipwm)
	]
toIpTableArg (NatDestination IPAddr
ip Maybe Port
mport) =
	[ Package
"--to-destination"
	, IPAddr -> Package
forall t. ConfigurableValue t => t -> Package
val IPAddr
ip Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Package -> (Port -> Package) -> Maybe Port -> Package
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Package
"" (\Port
p -> Package
":" Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Port -> Package
forall t. ConfigurableValue t => t -> Package
val Port
p) Maybe Port
mport
	]
toIpTableArg (Rules
r :- Rules
r') = Rules -> [Package]
toIpTableArg Rules
r [Package] -> [Package] -> [Package]
forall a. Semigroup a => a -> a -> a
<> Rules -> [Package]
toIpTableArg Rules
r'

data IPWithMask = IPWithNoMask IPAddr | IPWithIPMask IPAddr IPAddr | IPWithNumMask IPAddr Int
	deriving (IPWithMask -> IPWithMask -> Bool
(IPWithMask -> IPWithMask -> Bool)
-> (IPWithMask -> IPWithMask -> Bool) -> Eq IPWithMask
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IPWithMask -> IPWithMask -> Bool
$c/= :: IPWithMask -> IPWithMask -> Bool
== :: IPWithMask -> IPWithMask -> Bool
$c== :: IPWithMask -> IPWithMask -> Bool
Eq, Int -> IPWithMask -> Package -> Package
[IPWithMask] -> Package -> Package
IPWithMask -> Package
(Int -> IPWithMask -> Package -> Package)
-> (IPWithMask -> Package)
-> ([IPWithMask] -> Package -> Package)
-> Show IPWithMask
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [IPWithMask] -> Package -> Package
$cshowList :: [IPWithMask] -> Package -> Package
show :: IPWithMask -> Package
$cshow :: IPWithMask -> Package
showsPrec :: Int -> IPWithMask -> Package -> Package
$cshowsPrec :: Int -> IPWithMask -> Package -> Package
Show)

instance ConfigurableValue IPWithMask where
	val :: IPWithMask -> Package
val (IPWithNoMask IPAddr
ip) = IPAddr -> Package
forall t. ConfigurableValue t => t -> Package
val IPAddr
ip
	val (IPWithIPMask IPAddr
ip IPAddr
ipm) = IPAddr -> Package
forall t. ConfigurableValue t => t -> Package
val IPAddr
ip Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Package
"/" Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ IPAddr -> Package
forall t. ConfigurableValue t => t -> Package
val IPAddr
ipm
	val (IPWithNumMask IPAddr
ip Int
m) = IPAddr -> Package
forall t. ConfigurableValue t => t -> Package
val IPAddr
ip Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Package
"/" Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Int -> Package
forall t. ConfigurableValue t => t -> Package
val Int
m

data Rule = Rule
	{ Rule -> Chain
ruleChain  :: Chain
	, Rule -> Table
ruleTable  :: Table
	, Rule -> Target
ruleTarget :: Target
	, Rule -> Rules
ruleRules  :: Rules
	} deriving (Rule -> Rule -> Bool
(Rule -> Rule -> Bool) -> (Rule -> Rule -> Bool) -> Eq Rule
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rule -> Rule -> Bool
$c/= :: Rule -> Rule -> Bool
== :: Rule -> Rule -> Bool
$c== :: Rule -> Rule -> Bool
Eq, Int -> Rule -> Package -> Package
[Rule] -> Package -> Package
Rule -> Package
(Int -> Rule -> Package -> Package)
-> (Rule -> Package) -> ([Rule] -> Package -> Package) -> Show Rule
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Rule] -> Package -> Package
$cshowList :: [Rule] -> Package -> Package
show :: Rule -> Package
$cshow :: Rule -> Package
showsPrec :: Int -> Rule -> Package -> Package
$cshowsPrec :: Int -> Rule -> Package -> Package
Show)

data Table = Filter | Nat | Mangle | Raw | Security
	deriving (Table -> Table -> Bool
(Table -> Table -> Bool) -> (Table -> Table -> Bool) -> Eq Table
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Table -> Table -> Bool
$c/= :: Table -> Table -> Bool
== :: Table -> Table -> Bool
$c== :: Table -> Table -> Bool
Eq, Int -> Table -> Package -> Package
[Table] -> Package -> Package
Table -> Package
(Int -> Table -> Package -> Package)
-> (Table -> Package)
-> ([Table] -> Package -> Package)
-> Show Table
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Table] -> Package -> Package
$cshowList :: [Table] -> Package -> Package
show :: Table -> Package
$cshow :: Table -> Package
showsPrec :: Int -> Table -> Package -> Package
$cshowsPrec :: Int -> Table -> Package -> Package
Show)

instance ConfigurableValue Table where
	val :: Table -> Package
val Table
Filter = Package
"filter"
	val Table
Nat = Package
"nat"
	val Table
Mangle = Package
"mangle"
	val Table
Raw = Package
"raw"
	val Table
Security = Package
"security"

data Target = ACCEPT | REJECT | DROP | LOG | TargetCustom String
	deriving (Target -> Target -> Bool
(Target -> Target -> Bool)
-> (Target -> Target -> Bool) -> Eq Target
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Target -> Target -> Bool
$c/= :: Target -> Target -> Bool
== :: Target -> Target -> Bool
$c== :: Target -> Target -> Bool
Eq, Int -> Target -> Package -> Package
[Target] -> Package -> Package
Target -> Package
(Int -> Target -> Package -> Package)
-> (Target -> Package)
-> ([Target] -> Package -> Package)
-> Show Target
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Target] -> Package -> Package
$cshowList :: [Target] -> Package -> Package
show :: Target -> Package
$cshow :: Target -> Package
showsPrec :: Int -> Target -> Package -> Package
$cshowsPrec :: Int -> Target -> Package -> Package
Show)

instance ConfigurableValue Target where
	val :: Target -> Package
val Target
ACCEPT = Package
"ACCEPT"
	val Target
REJECT = Package
"REJECT"
	val Target
DROP = Package
"DROP"
	val Target
LOG = Package
"LOG"
	val (TargetCustom Package
t) = Package
t

data Chain = INPUT | OUTPUT | FORWARD | PREROUTING | POSTROUTING | ChainCustom String
	deriving (Chain -> Chain -> Bool
(Chain -> Chain -> Bool) -> (Chain -> Chain -> Bool) -> Eq Chain
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Chain -> Chain -> Bool
$c/= :: Chain -> Chain -> Bool
== :: Chain -> Chain -> Bool
$c== :: Chain -> Chain -> Bool
Eq, Int -> Chain -> Package -> Package
[Chain] -> Package -> Package
Chain -> Package
(Int -> Chain -> Package -> Package)
-> (Chain -> Package)
-> ([Chain] -> Package -> Package)
-> Show Chain
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Chain] -> Package -> Package
$cshowList :: [Chain] -> Package -> Package
show :: Chain -> Package
$cshow :: Chain -> Package
showsPrec :: Int -> Chain -> Package -> Package
$cshowsPrec :: Int -> Chain -> Package -> Package
Show)

instance ConfigurableValue Chain where
	val :: Chain -> Package
val Chain
INPUT = Package
"INPUT"
	val Chain
OUTPUT = Package
"OUTPUT"
	val Chain
FORWARD = Package
"FORWARD"
	val Chain
PREROUTING = Package
"PREROUTING"
	val Chain
POSTROUTING = Package
"POSTROUTING"
	val (ChainCustom Package
c) = Package
c

data Proto = TCP | UDP | ICMP
	deriving (Proto -> Proto -> Bool
(Proto -> Proto -> Bool) -> (Proto -> Proto -> Bool) -> Eq Proto
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Proto -> Proto -> Bool
$c/= :: Proto -> Proto -> Bool
== :: Proto -> Proto -> Bool
$c== :: Proto -> Proto -> Bool
Eq, Int -> Proto -> Package -> Package
[Proto] -> Package -> Package
Proto -> Package
(Int -> Proto -> Package -> Package)
-> (Proto -> Package)
-> ([Proto] -> Package -> Package)
-> Show Proto
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Proto] -> Package -> Package
$cshowList :: [Proto] -> Package -> Package
show :: Proto -> Package
$cshow :: Proto -> Package
showsPrec :: Int -> Proto -> Package -> Package
$cshowsPrec :: Int -> Proto -> Package -> Package
Show)

data ConnectionState = ESTABLISHED | RELATED | NEW | INVALID
	deriving (ConnectionState -> ConnectionState -> Bool
(ConnectionState -> ConnectionState -> Bool)
-> (ConnectionState -> ConnectionState -> Bool)
-> Eq ConnectionState
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ConnectionState -> ConnectionState -> Bool
$c/= :: ConnectionState -> ConnectionState -> Bool
== :: ConnectionState -> ConnectionState -> Bool
$c== :: ConnectionState -> ConnectionState -> Bool
Eq, Int -> ConnectionState -> Package -> Package
[ConnectionState] -> Package -> Package
ConnectionState -> Package
(Int -> ConnectionState -> Package -> Package)
-> (ConnectionState -> Package)
-> ([ConnectionState] -> Package -> Package)
-> Show ConnectionState
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [ConnectionState] -> Package -> Package
$cshowList :: [ConnectionState] -> Package -> Package
show :: ConnectionState -> Package
$cshow :: ConnectionState -> Package
showsPrec :: Int -> ConnectionState -> Package -> Package
$cshowsPrec :: Int -> ConnectionState -> Package -> Package
Show)

data ICMPTypeMatch = ICMPTypeName String | ICMPTypeCode Int
	deriving (ICMPTypeMatch -> ICMPTypeMatch -> Bool
(ICMPTypeMatch -> ICMPTypeMatch -> Bool)
-> (ICMPTypeMatch -> ICMPTypeMatch -> Bool) -> Eq ICMPTypeMatch
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ICMPTypeMatch -> ICMPTypeMatch -> Bool
$c/= :: ICMPTypeMatch -> ICMPTypeMatch -> Bool
== :: ICMPTypeMatch -> ICMPTypeMatch -> Bool
$c== :: ICMPTypeMatch -> ICMPTypeMatch -> Bool
Eq, Int -> ICMPTypeMatch -> Package -> Package
[ICMPTypeMatch] -> Package -> Package
ICMPTypeMatch -> Package
(Int -> ICMPTypeMatch -> Package -> Package)
-> (ICMPTypeMatch -> Package)
-> ([ICMPTypeMatch] -> Package -> Package)
-> Show ICMPTypeMatch
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [ICMPTypeMatch] -> Package -> Package
$cshowList :: [ICMPTypeMatch] -> Package -> Package
show :: ICMPTypeMatch -> Package
$cshow :: ICMPTypeMatch -> Package
showsPrec :: Int -> ICMPTypeMatch -> Package -> Package
$cshowsPrec :: Int -> ICMPTypeMatch -> Package -> Package
Show)

instance ConfigurableValue ICMPTypeMatch where
	val :: ICMPTypeMatch -> Package
val (ICMPTypeName Package
t) = Package
t
	val (ICMPTypeCode Int
c) = Int -> Package
forall t. ConfigurableValue t => t -> Package
val Int
c

data Frequency = NumBySecond Int
	deriving (Frequency -> Frequency -> Bool
(Frequency -> Frequency -> Bool)
-> (Frequency -> Frequency -> Bool) -> Eq Frequency
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Frequency -> Frequency -> Bool
$c/= :: Frequency -> Frequency -> Bool
== :: Frequency -> Frequency -> Bool
$c== :: Frequency -> Frequency -> Bool
Eq, Int -> Frequency -> Package -> Package
[Frequency] -> Package -> Package
Frequency -> Package
(Int -> Frequency -> Package -> Package)
-> (Frequency -> Package)
-> ([Frequency] -> Package -> Package)
-> Show Frequency
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Frequency] -> Package -> Package
$cshowList :: [Frequency] -> Package -> Package
show :: Frequency -> Package
$cshow :: Frequency -> Package
showsPrec :: Int -> Frequency -> Package -> Package
$cshowsPrec :: Int -> Frequency -> Package -> Package
Show)

instance ConfigurableValue Frequency where
	val :: Frequency -> Package
val (NumBySecond Int
n) = Int -> Package
forall t. ConfigurableValue t => t -> Package
val Int
n Package -> Package -> Package
forall a. [a] -> [a] -> [a]
++ Package
"/second"

type TCPFlagMask = [TCPFlag]

type TCPFlagComp = [TCPFlag]

data TCPFlag = SYN | ACK | FIN | RST | URG | PSH | ALL | NONE
	deriving (TCPFlag -> TCPFlag -> Bool
(TCPFlag -> TCPFlag -> Bool)
-> (TCPFlag -> TCPFlag -> Bool) -> Eq TCPFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TCPFlag -> TCPFlag -> Bool
$c/= :: TCPFlag -> TCPFlag -> Bool
== :: TCPFlag -> TCPFlag -> Bool
$c== :: TCPFlag -> TCPFlag -> Bool
Eq, Int -> TCPFlag -> Package -> Package
TCPFlagMask -> Package -> Package
TCPFlag -> Package
(Int -> TCPFlag -> Package -> Package)
-> (TCPFlag -> Package)
-> (TCPFlagMask -> Package -> Package)
-> Show TCPFlag
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: TCPFlagMask -> Package -> Package
$cshowList :: TCPFlagMask -> Package -> Package
show :: TCPFlag -> Package
$cshow :: TCPFlag -> Package
showsPrec :: Int -> TCPFlag -> Package -> Package
$cshowsPrec :: Int -> TCPFlag -> Package -> Package
Show)

data Rules
	= Everything
	| Proto Proto
	-- ^There is actually some order dependency between proto and port so this should be a specific
	-- data type with proto + ports
	| DPort Port
	| DPortRange (Port, Port)
	| InIFace Network.Interface
	| OutIFace Network.Interface
	| Ctstate [ ConnectionState ]
	| ICMPType ICMPTypeMatch
	| RateLimit Frequency
	| TCPFlags TCPFlagMask TCPFlagComp
	| TCPSyn
	| GroupOwner Group
	| Source [ IPWithMask ]
	| Destination [ IPWithMask ]
	| NotDestination [ IPWithMask ]
	| NatDestination IPAddr (Maybe Port)
	| Rules :- Rules   -- ^Combine two rules
	deriving (Rules -> Rules -> Bool
(Rules -> Rules -> Bool) -> (Rules -> Rules -> Bool) -> Eq Rules
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Rules -> Rules -> Bool
$c/= :: Rules -> Rules -> Bool
== :: Rules -> Rules -> Bool
$c== :: Rules -> Rules -> Bool
Eq, Int -> Rules -> Package -> Package
[Rules] -> Package -> Package
Rules -> Package
(Int -> Rules -> Package -> Package)
-> (Rules -> Package)
-> ([Rules] -> Package -> Package)
-> Show Rules
forall a.
(Int -> a -> Package -> Package)
-> (a -> Package) -> ([a] -> Package -> Package) -> Show a
showList :: [Rules] -> Package -> Package
$cshowList :: [Rules] -> Package -> Package
show :: Rules -> Package
$cshow :: Rules -> Package
showsPrec :: Int -> Rules -> Package -> Package
$cshowsPrec :: Int -> Rules -> Package -> Package
Show)

infixl 0 :-

instance Sem.Semigroup Rules where
	<> :: Rules -> Rules -> Rules
(<>) = Rules -> Rules -> Rules
(:-)

instance Monoid Rules where
	mempty :: Rules
mempty  = Rules
Everything
	mappend :: Rules -> Rules -> Rules
mappend = Rules -> Rules -> Rules
forall a. Semigroup a => a -> a -> a
(Sem.<>)