ip6addr 1.0.4 → 2.0.0
raw patch · 4 files changed
+209/−109 lines, 4 filesdep +optparse-applicativedep −cmdargs
Dependencies added: optparse-applicative
Dependencies removed: cmdargs
Files
- README.md +54/−21
- app/Main.hs +0/−81
- app/ip6addr.hs +148/−0
- ip6addr.cabal +7/−7
README.md view
@@ -1,35 +1,68 @@ # ip6addr  -A commandline tool that validates and generates IPv6 address text representations+## 1. Goal -* Canonical, in conformation with RFC 5952 (default output)-* Pure, i.e. rewriting IPv4 address if present+`ip6addr` is a commandline tool that validates and generates IPv6 address text representations, based upon [the library IPv6Addr](https://github.com/MichelBoucey/IPv6Addr) :++* Canonical, in conformation with [RFC 5952](https://www.rfc-editor.org/rfc/rfc5952) (default output)+* Pure, *i.e.* force the rewriting of IPv4 address if present * Full length-* Reverse lookup domain name, in conformation with RFC 3596 Section 2.5+* Reverse lookup domain name, in conformation with [RFC 3596 Section 2.5](https://www.rfc-editor.org/rfc/rfc3596#section-2.5) * Windows UNC path name * Random generation for test purpose +## 2. Usage +```+ip6addr v2.0.0 (c) Michel Boucey 2011-2024++Usage: ip6addr [-v|--version]+ [(-c|--canonical) | (-n|--no-ipv4) | (-f|--full-length) |+ (-p|--ptr) | (-w|--windows-unc) | (-r|--random)]+ [-q|--quantity ARG] [-s|--prefix ARG] [-d|--no-newline]+ [IPv6 address]++ ip6addr++Available options:+ -v,--version Show version+ -c,--canonical In conformation with RFC 5952 (default output)+ -n,--no-ipv4 Force the rewriting of the IPv4 address if present to+ get a pure IPv6 address made of nibbles only+ -f,--full-length Full IPv6 address length+ -p,--ptr PTR reverse mapping+ -w,--windows-unc Windows UNC path name+ -r,--random Random generation+ -q,--quantity ARG Amount of random addresses to generate+ -s,--prefix ARG Set a prefix for random addresses to generate+ -d,--no-newline Do not output trailing newlines+ -h,--help Show this help text+```++*N.B.* : In version 2, flags and arguments have changed from version 1, but the main features are identical.++## 3. Examples+ ```bash- [user@box ~]$ ip6addr -a 0:0::FFFF:192.0.2.128 + [user@box ~]$ ip6addr 0:0::FFFF:192.0.2.128 ::ffff:192.0.2.128 - [user@box ~]$ ip6addr -o pure -a 0:0::FFFF:192.0.2.128 + [user@box ~]$ ip6addr --no-ipv4 0:0::FFFF:192.0.2.128 ::ffff:c000:280 - [user@box ~]$ ip6addr -o arpa -a 0:0::FFFF:192.0.2.128 - 0.8.2.0.0.0.0.c.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA. - [user@box ~]$ ip6addr -o unc -a 2001:db8:85a3:8d3:1319:8a2e:370:7348- 2001-db8-85a3-8d3-1319-8a2e-370-7348.ipv6-literal.net - [user@box ~]$ ip6addr -o full -a 0:0::FFFF:192.0.2.128 - 0000:0000:0000:0000:0000:ffff:c000:0280 - [user@box ~]$ ip6addr -o random - ca18::654a:57ab:2ed7 - [user@box ~]$ ip6addr -o random -q 4 - 488:f7f3:7f7e::6ffd - 5b8b:8ab4::f0b8 - f191:ecc9:8193:8a2:104c:fec1:0:8c4d - af3b:3ffd:8302:6c56::8623:26 - [user@box ~]$ ip6addr -o random -q 3 -p 1234:1ab2:: - 1234:1a2b::cda6:cf2a:bb1d:d70b + [user@box ~]$ ip6addr --ptr 0:0::FFFF:192.0.2.128+ 0.8.2.0.0.0.0.c.f.f.f.f.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA.+ [user@box ~]$ ip6addr --windows-unc 2001:db8:85a3:8d3:1319:8a2e:370:7348+ 2001-db8-85a3-8d3-1319-8a2e-370-7348.ipv6-literal.net+ [user@box ~]$ ip6addr --full-length 0:0::FFFF:192.0.2.128+ 0000:0000:0000:0000:0000:ffff:c000:0280+ [user@box ~]$ ip6addr --random+ ca18::654a:57ab:2ed7+ [user@box ~]$ ip6addr --random --quantity 4+ 488:f7f3:7f7e::6ffd+ 5b8b:8ab4::f0b8+ f191:ecc9:8193:8a2:104c:fec1:0:8c4d+ af3b:3ffd:8302:6c56::8623:26+ [user@box ~]$ ip6addr --random --quantity 3 --prefix 1234:1ab2::+ 1234:1a2b::cda6:cf2a:bb1d:d70b 1234:1a2b::362c:8295:f546:a43a 1234:1a2b::1121:ca16:ab5:688a ```
− app/Main.hs
@@ -1,81 +0,0 @@-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RecordWildCards #-}-{-# LANGUAGE TemplateHaskell #-}--import Control.Monad (replicateM_)-import qualified Data.Text as T-import qualified Data.Text.IO as TIO (hPutStrLn, putStrLn)-import Data.Version (showVersion)-import Paths_ip6addr (version)-import System.Console.CmdArgs-import System.Exit-import System.IO (stderr)--import Text.IPv6Addr--data Input = Input- { output :: String- , address :: String- , quantity :: Int- , prefix :: String- } deriving (Show, Data, Typeable)--ip6addrInput :: Input-ip6addrInput = Input- { address = mempty- &= typ " <IPv6 address>"- , output = "canonical"- &= typ " [canonical|pure|full|arpa|unc|random]"- &= help "Default : canonical (RFC 5952)"- , quantity = 1- &= help "Amount of random addresses to generate"- &= typ " <Integer>"- , prefix = ""- &= typ " <Prefix>"- &= help "Set a prefix for random addresses generation"- } &= summary ("ip6addr " <> showVer <> " (c) Michel Boucey 2011-2023")- &= program "ip6addr"- &= helpArg [name "h"]- &= details [ "Examples:"- , ""- , " ip6addr -a 0:0::FFFF:192.0.2.128"- , " ip6addr -o full -a ::1"- , " ip6addr -o random -q 10 -p 1234:abcd::"- , ""- ]--showVer :: String-showVer = "v" <> showVersion version--main :: IO ()-main = do- Input{..} <- cmdArgs ip6addrInput- if output == "random"- then replicateM_ quantity (putRandAddr prefix) >> exitSuccess- else- case output of- "canonical" -> out maybeIPv6Addr address unIPv6Addr- "pure" -> out maybePureIPv6Addr address unIPv6Addr- "full" -> out maybeFullIPv6Addr address unIPv6Addr- "arpa" -> out maybeIP6ARPA address id- "unc" -> out maybeUNC address id- _ -> TIO.hPutStrLn stderr "See help" >> exitFailure- where- putRandAddr p = do- r <- randIPv6AddrWithPrefix (if p == mempty then Nothing else Just (T.pack p))- case r of- Just a -> TIO.putStrLn (unIPv6Addr a)- Nothing -> TIO.putStrLn "Bad prefix"- out t i o =- if i /= mempty- then do- let p = T.pack i- case t p of- Nothing ->- TIO.hPutStrLn stderr ("'" <> p <> "' is not an IPv6 address") >> exitFailure- Just a -> TIO.putStrLn (o a) >> exitSuccess- else Prelude.putStrLn "See help" >> exitFailure- maybeUNC t = toUNC <$> maybePureIPv6Addr t- maybeIP6ARPA t = toIP6ARPA <$> maybeFullIPv6Addr t-
+ app/ip6addr.hs view
@@ -0,0 +1,148 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}++import Control.Exception (SomeException, try)+import Control.Monad (replicateM_)+import Data.Maybe (fromJust)+import qualified Data.Text as T (pack)+import qualified Data.Text.IO as TIO (hPutStrLn, putStr, putStrLn)+import Data.Version (showVersion)+import Options.Applicative+import Paths_ip6addr (version)+import System.Exit+import System.IO (stderr)+import Text.IPv6Addr++showVer :: String+showVer = "ip6addr v"+ <> showVersion version+ <> " (c) Michel Boucey 2011-2024"++main :: IO ()+main = do+ Options{..} <- execParser opts+ if showver then failMsg $ T.pack showVer+ else+ case output of+ Canonical -> out noNewline maybeIPv6Addr address unIPv6Addr+ NoIPv4 -> out noNewline maybePureIPv6Addr address unIPv6Addr+ FullLength -> out noNewline maybeFullIPv6Addr address unIPv6Addr+ PTR -> out noNewline maybeIP6ARPA address id+ UNC -> out noNewline maybeUNC address id+ Random -> replicateM_ quantity (putRandAddr noNewline prefix) >> exitSuccess+ where+ putRandAddr n p = do+ let p' = T.pack p+ t <- try $ randIPv6AddrWithPrefix (if p == mempty then Nothing else Just p')+ case t of+ Right a -> put n (unIPv6Addr $ fromJust a)+ Left (_ :: SomeException) -> failMsg $ "'" <> p' <> "' is an invalid prefix"+ out n t i o =+ if i /= mempty+ then do+ let p = T.pack i+ case t p of+ Just a -> put n (o a) >> exitSuccess+ Nothing -> failMsg $ "'" <> p <> "' is not an IPv6 address"+ else failMsg "See --help"+ maybeUNC t = toUNC <$> maybePureIPv6Addr t+ maybeIP6ARPA t = toIP6ARPA <$> maybeFullIPv6Addr t+ put n = if n then TIO.putStr else TIO.putStrLn+ failMsg m = TIO.hPutStrLn stderr m >> exitFailure++data Output+ = Canonical+ | NoIPv4+ | FullLength+ | PTR+ | UNC+ | Random+ deriving (Eq)++data Options =+ Options+ { showver :: !Bool+ , output :: !Output+ , quantity :: !Int+ , prefix :: !String+ , noNewline :: !Bool+ , address :: !String+ }++opts :: ParserInfo Options+opts = info (parseOptions <**> helper)+ ( fullDesc+ <> progDesc "ip6addr"+ <> header showVer+ )++parseOptions :: Parser Options+parseOptions =+ Options+ <$>+ switch+ ( short 'v'+ <> long "version"+ <> help "Show version"+ )+ <*>+ (flag Canonical Canonical+ ( short 'c'+ <> long "canonical"+ <> help "In conformation with RFC 5952 (default output)"+ )+ <|>+ flag' NoIPv4+ ( short 'n'+ <> long "no-ipv4"+ <> help "Force the rewriting of the IPv4 address if present\+ \ to get a pure IPv6 address made of nibbles only"+ )+ <|>+ flag' FullLength+ ( short 'f'+ <> long "full-length"+ <> help "Full IPv6 address length"+ )+ <|>+ flag' PTR+ ( short 'p'+ <> long "ptr"+ <> help "PTR reverse mapping"+ )+ <|>+ flag' UNC+ ( short 'w'+ <> long "windows-unc"+ <> help "Windows UNC path name"+ )+ <|>+ flag' Random+ ( short 'r'+ <> long "random"+ <> help "Random generation"+ )+ )+ <*>+ option auto+ ( short 'q'+ <> long "quantity"+ <> help "Amount of random addresses to generate"+ <> value 1+ )+ <*>+ option str+ ( short 's'+ <> long "prefix"+ <> help "Set a prefix for random addresses to generate"+ <> value ""+ )+ <*>+ flag False True+ ( short 'd'+ <> long "no-newline"+ <> help "Do not output trailing newlines" )+ <*>+ argument str (metavar "IPv6 address" <> value "")+
ip6addr.cabal view
@@ -1,5 +1,5 @@ name: ip6addr-version: 1.0.4+version: 2.0.0 synopsis: Commandline tool to deal with IPv6 address text representations description: Commandline tool to validate, canonize and generate IPv6 address text representations license: BSD3@@ -13,7 +13,7 @@ cabal-version: >=1.10 extra-source-files: README.md -Tested-With: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.1+Tested-With: GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.8 || ==9.4.8 || ==9.6.3 || ==9.8.2 Source-Repository head Type: git@@ -21,14 +21,14 @@ executable ip6addr hs-source-dirs: app- main-is: Main.hs+ main-is: ip6addr.hs other-modules: Paths_ip6addr other-extensions: DeriveDataTypeable , OverloadedStrings- build-depends: base >= 4.8 && < 5- , cmdargs >= 0.10.13 && < 0.11- , IPv6Addr >= 2.0.0 && < 2.1- , text >=1.1 && < 2.2+ build-depends: base >= 4.8 && < 5+ , IPv6Addr >= 2.0.0 && < 2.1+ , optparse-applicative >= 0.14 && < 0.19+ , text >=1.1 && < 2.2 default-language: Haskell2010 GHC-Options: -Wall