Win32-dhcp-server-0.3.1: src/System/Win32/DHCP/SUBNET_ELEMENT_DATA_V4.hs
{-# LANGUAGE RankNTypes #-}
module System.Win32.DHCP.SUBNET_ELEMENT_DATA_V4
( SUBNET_ELEMENT_DATA_V4 (..)
, SUBNET_ELEMENT_TYPE
, elementTypeOf
, subnetElementData
) where
import Import
import System.Win32.DHCP.DhcpStructure
import System.Win32.DHCP.HOST_INFO
import System.Win32.DHCP.IP_CLUSTER
import System.Win32.DHCP.IP_RANGE
import System.Win32.DHCP.Reservation
-- typedef struct _DHCP_SUBNET_ELEMENT_DATA_V4 {
-- DHCP_SUBNET_ELEMENT_TYPE ElementType;
-- union {
-- DHCP_IP_RANGE *IpRange;
-- DHCP_HOST_INFO *SecondaryHost;
-- DHCP_IP_RESERVATION_V4 *ReservedIp;
-- DHCP_IP_RANGE *ExcludeIpRange;
-- DHCP_IP_CLUSTER *IpUsedCluster;
-- } Element;
-- } DHCP_SUBNET_ELEMENT_DATA_V4, *LPDHCP_SUBNET_ELEMENT_DATA_V4;
data SUBNET_ELEMENT_DATA_V4
= IpRanges !IP_RANGE
| SecondaryHosts !HOST_INFO
| ReservedIps !Reservation
| ExcludedIpRanges !IP_RANGE
| IpUsedCluster !IP_CLUSTER
-- typedef enum _DHCP_SUBNET_ELEMENT_TYPE_V5 {
-- DhcpIpRanges,
-- DhcpSecondaryHosts,
-- DhcpReservedIps,
-- DhcpExcludedIpRanges,
-- DhcpIpRangesDhcpOnly,
-- DhcpIpRangesDhcpBootp,
-- DhcpIpRangesBootpOnly
-- } DHCP_SUBNET_ELEMENT_TYPE, *LPDHCP_SUBNET_ELEMENT_TYPE;
type SUBNET_ELEMENT_TYPE = CInt
subnetElementData :: DhcpStructure SUBNET_ELEMENT_DATA_V4
subnetElementData = DhcpStructure
{ peekDhcp = peekSubnetElementData
, freeDhcpChildren = freeSubnetElementData
, withDhcp' = withSubnetElementData'
, sizeDhcp = 8
}
peekSubnetElementData :: Ptr SUBNET_ELEMENT_DATA_V4 -> IO SUBNET_ELEMENT_DATA_V4
peekSubnetElementData ptr = do
elementType <- (peek . castPtr) ptr :: IO SUBNET_ELEMENT_TYPE
pElement <- peekByteOff ptr 4
case elementType of
0 -> IpRanges <$> peek (castPtr pElement)
1 -> SecondaryHosts <$> peekDhcp hostInfo (castPtr pElement)
2 -> ReservedIps <$> peekDhcp reservation (castPtr pElement)
3 -> ExcludedIpRanges <$> peek (castPtr pElement)
4 -> IpUsedCluster <$> peek (castPtr pElement)
_ -> error "Invalid element type found in SUBNET_ELEMENT_DATA_V4."
freeSubnetElementData :: (forall x. Ptr x -> IO ())
-> Ptr SUBNET_ELEMENT_DATA_V4 -> IO ()
freeSubnetElementData freefunc ptr = do
elementType <- (peek . castPtr) ptr :: IO SUBNET_ELEMENT_TYPE
scrubWith_ (ppElement ptr) $ \pElement -> do
case elementType of
0 -> return ()
1 -> freeDhcp hostInfo freefunc $ castPtr pElement
2 -> freeDhcp reservation freefunc $ castPtr pElement
3 -> return ()
4 -> return ()
_ -> error "Invalid element type found in SUBNET_ELEMENT_DATA_V4."
-- Also used by withSubnetElementDataArray.
withSubnetElementData' :: SUBNET_ELEMENT_DATA_V4 -> Ptr SUBNET_ELEMENT_DATA_V4
-> IO r -> IO r
withSubnetElementData' elementData ptr f = do
castPtr ptr `poke` elementTypeOf elementData
case elementData of
IpRanges x -> with x $ \pX -> poke (ppElement ptr) pX >> f
SecondaryHosts x -> withDhcp hostInfo x $ \pX -> poke (ppElement ptr) pX >> f
ReservedIps x -> withDhcp reservation x $ \pX -> poke (ppElement ptr) pX >> f
ExcludedIpRanges x -> with x $ \pX -> poke (ppElement ptr) pX >> f
IpUsedCluster x -> with x $ \pX -> poke (ppElement ptr) pX >> f
ppElement :: Ptr SUBNET_ELEMENT_DATA_V4 -> Ptr a
ppElement ptr = castPtr $ ptr `plusPtr` 4
elementTypeOf :: SUBNET_ELEMENT_DATA_V4 -> SUBNET_ELEMENT_TYPE
elementTypeOf (IpRanges _) = 0
elementTypeOf (SecondaryHosts _) = 1
elementTypeOf (ReservedIps _) = 2
elementTypeOf (ExcludedIpRanges _) = 3
elementTypeOf (IpUsedCluster _) = 4