Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support range, cidrs in grepip #188

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions ipinfo/cmd_grepip.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ var completionsGrepIP = &complete.Command{
Flags: map[string]complete.Predictor{
"-o": predict.Nothing,
"--only-matching": predict.Nothing,
"--include-cidrs": predict.Nothing,
"--include-ranges": predict.Nothing,
"--cidrs-only": predict.Nothing,
"--ranges-only": predict.Nothing,
"-h": predict.Nothing,
"--no-filename": predict.Nothing,
"--no-recurse": predict.Nothing,
Expand All @@ -35,6 +39,14 @@ Options:
General:
--only-matching, -o
print only matched IP in result line, excluding surrounding content.
--include-cidrs
prints the CIDRs too.
--include-ranges
prints the Ranges too.
--cidrs-only
prints the CIDRs only.
--ranges-only
prints the Ranges only.
--no-filename, -h
don't print source of match in result lines when more than 1 source.
--no-recurse
Expand Down
79 changes: 71 additions & 8 deletions lib/cmd_grepip.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ import (

// CmdGrepIPFlags are flags expected by CmdGrepIP.
type CmdGrepIPFlags struct {
OnlyMatching bool
NoFilename bool
NoRecurse bool
Help bool
NoColor bool
V4 bool
V6 bool
ExclRes bool
OnlyMatching bool
IncludeCIDRs bool
IncludeRanges bool
CIDRsOnly bool
RangesOnly bool
NoFilename bool
NoRecurse bool
Help bool
NoColor bool
V4 bool
V6 bool
ExclRes bool
}

// Init initializes the common flags available to CmdGrepIP with sensible
Expand All @@ -37,6 +41,26 @@ func (f *CmdGrepIPFlags) Init() {
"only-matching", "o", false,
"print only matched IPs in result line.",
)
pflag.BoolVarP(
&f.IncludeCIDRs,
"include-cidrs", "", false,
"print cidrs too.",
)
pflag.BoolVarP(
&f.IncludeRanges,
"include-ranges", "", false,
"print ranges too.",
)
pflag.BoolVarP(
&f.CIDRsOnly,
"cidrs-only", "", false,
"print cidrs.",
)
pflag.BoolVarP(
&f.RangesOnly,
"ranges-only", "", false,
"print ranges.",
)
pflag.BoolVarP(
&f.NoFilename,
"no-filename", "h", false,
Expand Down Expand Up @@ -123,10 +147,49 @@ func CmdGrepIP(
var rexp *regexp.Regexp
if ipv == 4 {
rexp = ipV4Regex
if f.CIDRsOnly && f.RangesOnly {
rexp = v4SubnetRegex
} else if f.IncludeCIDRs && f.IncludeRanges {
rexp = v4IpSubnetRegex
} else if f.IncludeCIDRs {
rexp = v4IpCidrRegex
} else if f.IncludeRanges {
rexp = v4IpRangeRegex
} else if f.CIDRsOnly {
rexp = v4CidrRegex
} else if f.RangesOnly {
rexp = v4RangeRegex
}
} else if ipv == 6 {
rexp = ipV6Regex
if f.CIDRsOnly && f.RangesOnly {
rexp = v6SubnetRegex
} else if f.IncludeCIDRs && f.IncludeRanges {
rexp = v6IpSubnetRegex
} else if f.IncludeCIDRs {
rexp = v6IpCidrRegex
} else if f.IncludeRanges {
rexp = v6IpRangeRegex
} else if f.CIDRsOnly {
rexp = v6CidrRegex
} else if f.RangesOnly {
rexp = v6RangeRegex
}
} else {
rexp = ipRegex
if f.CIDRsOnly && f.RangesOnly {
rexp = subnetRegex
} else if f.IncludeCIDRs && f.IncludeRanges {
rexp = ipSubnetRegex
} else if f.IncludeCIDRs {
rexp = ipCidrRegex
} else if f.IncludeRanges {
rexp = ipRangeRegex
} else if f.CIDRsOnly {
rexp = cidrRegex
} else if f.RangesOnly {
rexp = rangeRegex
}
}

fmtSrc := color.New(color.FgMagenta)
Expand Down
32 changes: 32 additions & 0 deletions lib/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,39 @@ import "regexp"
func init() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do the new regexes below add any significant startup time to the command? With so many regexes compiled at startup, wanna make sure the command still runs super fast without overheads, as these regexes would be getting compiled for every single invocation of the CLI no matter what command.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$ time ipinfo grepip list.txt 
...
real	0m0.010s
user	0m0.000s
sys	0m0.011s
$ go build
$ time ./ipinfo grepip list.txt 
...
real	0m0.023s
user	0m0.009shas
sys	0m0.023s

execution time has increased now, difference in practice doesn't appear to be as significant, I guess

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went up 13ms, so should be fine for now. We can optimize if it gets worse

bogonIP4List = GetBogonRange4()
bogonIP6List = GetBogonRange6()

// IP
ipV4Regex = regexp.MustCompilePOSIX(IPv4RegexPattern)
ipV6Regex = regexp.MustCompilePOSIX(IPv6RegexPattern)
ipRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv6RegexPattern)

// IP and CIDR
v4IpCidrRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv4CIDRRegexPattern)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A comment against each grouped code is warranted now

v6IpCidrRegex = regexp.MustCompilePOSIX(IPv6RegexPattern + "|" + IPv6CIDRRegexPattern)
ipCidrRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv6RegexPattern + "|" + IPv4CIDRRegexPattern + "|" + IPv6CIDRRegexPattern)

// IP and Range
v4IpRangeRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv4RangeRegexPattern)
v6IpRangeRegex = regexp.MustCompilePOSIX(IPv6RegexPattern + "|" + IPv6RangeRegexPattern)
ipRangeRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv6RegexPattern + "|" + IPv4RangeRegexPattern + "|" + IPv6RangeRegexPattern)

// IP, CIDR and Range
v4IpSubnetRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv4CIDRRegexPattern + "|" + IPv4RangeRegexPattern)
v6IpSubnetRegex = regexp.MustCompilePOSIX(IPv6RegexPattern + "|" + IPv6RangeRegexPattern + "|" + IPv6CIDRRegexPattern)
ipSubnetRegex = regexp.MustCompilePOSIX(IPv4RegexPattern + "|" + IPv6RegexPattern + "|" + IPv4CIDRRegexPattern + "|" + IPv4RangeRegexPattern + "|" + IPv6RangeRegexPattern + "|" + IPv6CIDRRegexPattern)

// CIDR
v4CidrRegex = regexp.MustCompilePOSIX(IPv4CIDRRegexPattern)
v6CidrRegex = regexp.MustCompilePOSIX(IPv6CIDRRegexPattern)
cidrRegex = regexp.MustCompilePOSIX(IPv4CIDRRegexPattern + "|" + IPv6CIDRRegexPattern)

// Range
v4RangeRegex = regexp.MustCompilePOSIX(IPv4RangeRegexPattern)
v6RangeRegex = regexp.MustCompilePOSIX(IPv6RangeRegexPattern)
rangeRegex = regexp.MustCompilePOSIX(IPv4RangeRegexPattern + "|" + IPv6RangeRegexPattern)

// CIDR and Range
v4SubnetRegex = regexp.MustCompilePOSIX(IPv4RangeRegexPattern + "|" + IPv4CIDRRegexPattern)
v6SubnetRegex = regexp.MustCompilePOSIX(IPv6RangeRegexPattern + "|" + IPv6CIDRRegexPattern)
subnetRegex = regexp.MustCompilePOSIX(IPv4RangeRegexPattern + "|" + IPv4CIDRRegexPattern + "|" + IPv6RangeRegexPattern + "|" + IPv6CIDRRegexPattern)
}
32 changes: 31 additions & 1 deletion lib/regex.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,35 @@ var ipV4Regex *regexp.Regexp
var ipV6Regex *regexp.Regexp
var ipRegex *regexp.Regexp

const IPv4RegexPattern = `((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`
var v4IpCidrRegex *regexp.Regexp
var v6IpCidrRegex *regexp.Regexp
var ipCidrRegex *regexp.Regexp

var v4IpRangeRegex *regexp.Regexp
var v6IpRangeRegex *regexp.Regexp
var ipRangeRegex *regexp.Regexp

var v4IpSubnetRegex *regexp.Regexp
var v6IpSubnetRegex *regexp.Regexp
var ipSubnetRegex *regexp.Regexp

var v4CidrRegex *regexp.Regexp
var v6CidrRegex *regexp.Regexp
var cidrRegex *regexp.Regexp

var v4RangeRegex *regexp.Regexp
var v6RangeRegex *regexp.Regexp
var rangeRegex *regexp.Regexp

var v4SubnetRegex *regexp.Regexp
var v6SubnetRegex *regexp.Regexp
var subnetRegex *regexp.Regexp

const v4octet = `(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)`
const IPv4RegexPattern = `(` + v4octet + `\.){3}` + v4octet
const IPv4RangeRegexPattern = IPv4RegexPattern + `[-,]` + IPv4RegexPattern
const IPv4CIDRRegexPattern = IPv4RegexPattern + `\/([1-2]?[0-9]|3[0-2])`

const IPv6RegexPattern = `(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))`
const IPv6RangeRegexPattern = IPv6RegexPattern + `[-,]` + IPv6RegexPattern
const IPv6CIDRRegexPattern = IPv6RegexPattern + `\/([0-9]|[1-9][0-9]|1[0-1][0-9]|12[0-8])`