{-# LANGUAGE CPP #-} module System.Global6 where import Control.Monad import Control.Applicative #if MIN_VERSION_iproute(1,7,4) import Data.IP hiding (fromSockAddr) #else import Data.IP #endif import Data.List import Data.Maybe import Network.Socket import System.Process import Text.Read import System.IO parseIpAddr :: String -> Maybe IPv6 parseIpAddr s = do let ws = words s (addr,bs) = splitAt 1 $ drop 1 $ dropWhile (/= "inet6") ws guard ("global" `elem` bs) addr <- listToMaybe addr guard (not $ isPrefixOf "fd" addr) guard (not $ isPrefixOf "fc" addr) let (addr',slash) = break (=='/') addr ip6 <- readMaybe addr' return $ (ip6 :: IPv6) global6 :: IO (Maybe IPv6) global6 = do addrs <- lines <$> readProcess "ip" ["-o","-6","addr"] "" return $ foldr1 mplus $ map parseIpAddr addrs everyOther (x:_:xs) = x : everyOther xs everyOther xs = xs -- | Obtain all available IP broadcast addresses (in dotted quad or IPv6 colon -- format) as Strings. broadcastAddrs :: IO [String] broadcastAddrs = parseBroadcastAddrs <$> readProcess "ip" ["-o","addr"] "" parseBroadcastAddrs :: String -> [String] parseBroadcastAddrs ipoutput = brds where brds = mapMaybe getbrd as assoclist ws = zip (everyOther ws) (everyOther $ drop 1 ws) as = map (assoclist . drop 2 . words) $ lines ipoutput getbrd alist = do ip <- lookup "inet" alist <|> lookup "inet6" alist lookup "brd" alist