diff --git a/ipinfo/cmd_tool.go b/ipinfo/cmd_tool.go index 8650ef32..f66ca6fb 100644 --- a/ipinfo/cmd_tool.go +++ b/ipinfo/cmd_tool.go @@ -25,6 +25,7 @@ var completionsTool = &complete.Command{ "ip2n": completionsToolIP2n, "n2ip": completionsToolN2IP, "n2ip6": completionsToolN2IP6, + "prefix": completionsToolPrefix, }, Flags: map[string]complete.Predictor{ "-h": predict.Nothing, @@ -52,6 +53,7 @@ Commands: ip2n converts an IPv4 or IPv6 address to its decimal representation. n2ip evaluates a mathematical expression and converts it to an IPv4 or IPv6. n2ip6 evaluates a mathematical expression and converts it to an IPv6. + prefix misc. prefix tools related to CIDRs. Options: --help, -h @@ -108,6 +110,8 @@ func cmdTool() error { err = cmdToolN2IP() case cmd == "n2ip6": err = cmdToolN2IP6() + case cmd == "prefix": + err = cmdToolPrefix() default: err = toolHelp() } diff --git a/ipinfo/cmd_tool_prefix.go b/ipinfo/cmd_tool_prefix.go new file mode 100644 index 00000000..675a952d --- /dev/null +++ b/ipinfo/cmd_tool_prefix.go @@ -0,0 +1,67 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ipinfo/cli/lib/complete" + "github.com/ipinfo/cli/lib/complete/predict" + "github.com/spf13/pflag" +) + +var completionsToolPrefix = &complete.Command{ + Sub: map[string]*complete.Command{ + "addr": completionsToolPrefixAddr, + }, + Flags: map[string]complete.Predictor{ + "-h": predict.Nothing, + "--help": predict.Nothing, + }, +} + +func printHelpToolPrefix() { + fmt.Printf( + `Usage: %s tool prefix [] [] + +Commands: + addr returns the base IP address of a prefix. + +Options: + --help, -h + show help. +`, progBase) +} + +func toolPrefixHelp() (err error) { + pflag.BoolVarP(&fHelp, "help", "h", false, "show help.") + pflag.Parse() + + if fHelp { + printHelpToolPrefix() + return nil + } + + printHelpToolPrefix() + return nil +} + +func cmdToolPrefix() error { + var err error + cmd := "" + if len(os.Args) > 3 { + cmd = os.Args[3] + } + + switch { + case cmd == "addr": + err = cmdToolPrefixAddr() + default: + err = toolPrefixHelp() + } + + if err != nil { + fmt.Fprintf(os.Stderr, "err: %v\n", err) + } + + return nil +} diff --git a/ipinfo/cmd_tool_prefix_addr.go b/ipinfo/cmd_tool_prefix_addr.go new file mode 100644 index 00000000..c980bbf0 --- /dev/null +++ b/ipinfo/cmd_tool_prefix_addr.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + + "github.com/ipinfo/cli/lib" + "github.com/ipinfo/cli/lib/complete" + "github.com/ipinfo/cli/lib/complete/predict" + "github.com/spf13/pflag" +) + +var completionsToolPrefixAddr = &complete.Command{ + Flags: map[string]complete.Predictor{ + "-h": predict.Nothing, + "--help": predict.Nothing, + }, +} + +func printHelpToolPrefixAddr() { + fmt.Printf( + `Usage: %s tool prefix addr + +Description: + Returns the base IP address of a prefix. + +Examples: + # CIDR Valid Examples. + $ %[1]s tool prefix addr 192.168.0.0/16 + $ %[1]s tool prefix addr 10.0.0.0/8 + $ %[1]s tool prefix addr 2001:0db8:1234::/48 + $ %[1]s tool prefix addr 2606:2800:220:1::/64 + + # CIDR Invalid Examples. + $ %[1]s tool prefix addr 192.168.0.0/40 + $ %[1]s tool prefix addr 2001:0db8:1234::/129 + +Options: + --help, -h + show help. +`, progBase) +} + +func cmdToolPrefixAddr() (err error) { + f := lib.CmdToolPrefixAddrFlags{} + f.Init() + pflag.Parse() + + return lib.CmdToolPrefixAddr(f, pflag.Args()[3:], printHelpToolPrefixAddr) +} diff --git a/lib/cmd_tool_prefix_addr.go b/lib/cmd_tool_prefix_addr.go new file mode 100644 index 00000000..8786961a --- /dev/null +++ b/lib/cmd_tool_prefix_addr.go @@ -0,0 +1,41 @@ +package lib + +import ( + "fmt" + "net/netip" + + "github.com/spf13/pflag" +) + +type CmdToolPrefixAddrFlags struct { + Help bool +} + +func (f *CmdToolPrefixAddrFlags) Init() { + pflag.BoolVarP( + &f.Help, + "help", "h", false, + "show help.", + ) +} + +func CmdToolPrefixAddr(f CmdToolPrefixAddrFlags, args []string, printHelp func()) error { + if f.Help { + printHelp() + return nil + } + + op := func(input string, inputType INPUT_TYPE) error { + switch inputType { + case INPUT_TYPE_CIDR: + prefix, err := netip.ParsePrefix(input) + if err != nil { + return err + } + fmt.Printf("%s,%s\n", input, prefix.Addr()) + } + return nil + } + + return GetInputFrom(args, true, true, op) +}