module Text.IPv6Addr.Manip ( randIPv6AddrChunk , randPartialIPv6Addr , macAddrToIPv6AddrTokens , getTokIPv6AddrOf , getTokMacAddrOf ) where import Control.Monad (replicateM) import Data.Attoparsec.Text as A import Data.Char (intToDigit) import Data.List (intersperse) import qualified Data.Text as T import Network.Info import System.Random (randomRIO) import Text.IPv6Addr.Internal import Text.IPv6Addr.Types -- | Returns 'Just' a random 'SixteenBit' token based on a mask \"____\", each -- underscore being replaced by a random hexadecimal digit. -- -- > randIPv6AddrChunk "_f__" == Just (SixteenBit "bfd4") -- randIPv6AddrChunk :: String -> IO IPv6AddrToken randIPv6AddrChunk m = mapM getHex m >>= \g -> return $ SixteenBit $ T.dropWhile (=='0') $ T.pack g where getHex c | c == '_' = getDigit | otherwise = pure c -- | Generates a random partial 'IPv6Addr' with n 'SixteenBit'. randPartialIPv6Addr :: Int -> IO [IPv6AddrToken] randPartialIPv6Addr n = if n > 0 && n < 9 then intersperse Colon <$> replicateM n (SixteenBit <$> T.pack <$> replicateM 4 getDigit) else pure [] -- | Given a MAC address, returns 'Just' the corresponding 'IPv6AddrToken' list, or 'Nothing'. -- -- > macAddrToIPv6AddrTokens "fa:1d:58:cc:95:16" == Just [SixteenBit "fa1d",Colon,SixteenBit "58cc",Colon,SixteenBit "9516"] -- macAddrToIPv6AddrTokens :: T.Text -> Maybe [IPv6AddrToken] macAddrToIPv6AddrTokens t = case parse macAddr t of Done a b -> if a == T.empty then intersperse Colon <$> b else Nothing _ -> Nothing -- -- Functions based upon Network.Info to get local MAC and IPv6 addresses. -- -- | Given a valid name of a local network interface, returns 'Just' the list of -- tokens of the interface's IPv6 address, or 'Nothing'. -- -- > getTokIPv6AddrOf "eth0" == Just [SixteenBit "fe80",DoubleColon,SixteenBit "fa1d",Colon,SixteenBit "58cc",Colon,SixteenBit "9516"] -- getTokIPv6AddrOf :: String -> IO (Maybe [IPv6AddrToken]) getTokIPv6AddrOf s = maybe Nothing (maybeTokIPv6Addr. T.pack . show) <$> (lookup s <$> networkInterfacesIPv6AddrList) -- | Given a valid name of a local network interface, -- returns 'Just' the corresponding list of 'IPv6AddrToken' of the interface's MAC Address, -- or 'Nothing'. -- -- > getTokMacAddrOf "eth0" == Just [SixteenBit "fa1d",Colon,SixteenBit "58cc",Colon,SixteenBit "9516"] -- getTokMacAddrOf :: String -> IO (Maybe [IPv6AddrToken]) getTokMacAddrOf s = maybe Nothing (macAddrToIPv6AddrTokens . T.pack . show) <$> (lookup s <$> networkInterfacesMacAddrList) where networkInterfacesMacAddrList = getNetworkInterfaces >>= \n -> return (networkInterfacesMac <$> n) where networkInterfacesMac (NetworkInterface n _ _ m) = (n,m) getDigit :: IO Char getDigit = intToDigit <$> randomRIO (0,15)