module System.Win32.DHCP.CLIENT_UID ( CLIENT_UID (..) , clientUid , macCuid , macCuidDrop5 , withMac ) where import Foreign import System.Win32.Types import Data.Mac import System.Win32.DHCP.DhcpStructure import System.Win32.DHCP.LengthBuffer -- typedef struct _DHCP_BINARY_DATA { -- DWORD DataLength; -- BYTE *Data; -- } DHCP_BINARY_DATA, *LPDHCP_BINARY_DATA, DHCP_CLIENT_UID; -- Byte 0 - 3: The result of a binary AND on the IP address and the subnet -- mask in reverse order. -- Byte 4: Hardware identifier. This value is always 0x01. -- Byte 5 - 10: The Mac address of the client. newtype CLIENT_UID = CLIENT_UID (LengthBuffer BYTE) unwrap :: CLIENT_UID -> LengthBuffer BYTE unwrap (CLIENT_UID uid) = uid clientUid :: DhcpStructure CLIENT_UID clientUid = newtypeDhcpStructure CLIENT_UID unwrap $ lengthBuffer (basicDhcpArray storableDhcpStructure) -- |Functions returning a CLIENT_UID often have the first 5 bytes hold -- information about the subnet being used. Microsoft does not document this, -- but it can be determined through experimentation. macCuidDrop5 :: CLIENT_UID -> Mac macCuidDrop5 (CLIENT_UID (LengthBuffer _ bytes)) = fromOctets a b c d e f where [a, b, c, d, e, f] = drop 5 bytes macCuid :: CLIENT_UID -> Mac macCuid (CLIENT_UID (LengthBuffer _ bytes)) = fromOctets a b c d e f where [a, b, c, d, e, f] = bytes fromMac :: Mac -> CLIENT_UID fromMac mac = CLIENT_UID (LengthBuffer 6 [a, b, c, d, e, f]) where (a, b, c, d, e, f) = toOctets mac -- |When creating CLIENT_UID structures in memory we only need 6 bytes -- representing the Mac address. This is contrary to MSDN documentation, which -- states that there should be 11 bytes, with the first 5 being constructed -- from the IP and subnet. withMac :: Mac -> (Ptr CLIENT_UID -> IO b) -> IO b withMac mac f = withDhcp clientUid (fromMac mac) f