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 */