{-# LANGUAGE CPP #-} module MacAddress where import Data.Binary (decode) import qualified Data.ByteString.Lazy as BSL import Safe (headDef) #ifdef ETA_VERSION import Java import Data.Maybe (catMaybes) import Data.Traversable (for) import Data.Word (Word64, Word8) #else /* ETA_VERSION */ import Data.Word (Word64) import Network.Info (MAC (MAC), getNetworkInterfaces, mac) #endif /* ETA_VERSION */ getMacAddress :: IO Word64 #ifdef ETA_VERSION getMacAddress = java $ do interfaces <- fromJava <$> getNetworkInterfaces macs <- for interfaces (<.> getHardwareAddress) let macBytes = headDef (error "Can't get any non-zero MAC address of this machine") $ catMaybes macs let mac = foldBytes $ fromJava macBytes pure mac data NetworkInterface = NetworkInterface @java.net.NetworkInterface deriving Class foreign import java unsafe "@static java.net.NetworkInterface.getNetworkInterfaces" getNetworkInterfaces :: Java a (Enumeration NetworkInterface) foreign import java unsafe getHardwareAddress :: Java NetworkInterface (Maybe JByteArray) foldBytes :: [Word8] -> Word64 foldBytes bytes = decode . BSL.pack $ replicate (8 - length bytes) 0 ++ bytes #else /* ETA_VERSION */ getMacAddress = decodeMac <$> getMac getMac :: IO MAC getMac = headDef (error "Can't get any non-zero MAC address of this machine") . filter (/= minBound) . map mac <$> getNetworkInterfaces decodeMac :: MAC -> Word64 decodeMac (MAC b5 b4 b3 b2 b1 b0) = decode $ BSL.pack [0, 0, b5, b4, b3, b2, b1, b0] #endif /* ETA_VERSION */