{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module Data.Header
	( L3Header (..)
	, L3Address (..)
	) where

import Data.Serialize (encode, Serialize)
import qualified Data.ByteString as B

-- |A class of network headers that assumes a checksum is present.
class (Num c,Serialize h) => L3Header h a c | h -> a, a -> h, h -> c where
	-- |Returns the checksum from the header
	getChecksum :: h -> c

	-- |Sets the checksum in the header
	setChecksum :: h -> c -> h

	-- |Returns a 'source' for the header.
	src :: h -> a

	-- |Returns a 'destination' for the header.
	dst :: h -> a

	-- |Returns a header with all the same fields except the checksum is zeroed
	zeroChecksum :: h -> h
	zeroChecksum h = setChecksum h 0

	-- |Computes the checksum
	computeChecksum :: h -> c

	-- |Computes the checksum, returns a header with the proper checksum
	fillChecksum :: h -> h
	fillChecksum h = setChecksum h (computeChecksum h)

	-- |Used by various layer 4 protocols (UDP, TCP),
	-- a pseudo header is needed to compute the checksum
	pseudoHeader :: h -> B.ByteString

	-- |Returns True iff the checksum is valid
	valid :: h -> Bool
	valid h = computeChecksum h == getChecksum h

-- |A class of network addresses that assumes there is a 'broadcast' concept.
class (Serialize a) => L3Address a h | a -> h, h -> a where
	localBroadcast :: a -> a
	globalBroadcast :: a

class (Serialize h, Serialize p) => L4Header h p | h -> p where
	fixChecksum :: (L3Header l3 a c) => h -> l3 -> h
	srcPort	:: h -> p
	dstPort :: h -> p