Skip to content

Commit

Permalink
Solve issue with sort / reverse sort option #103 (#104)
Browse files Browse the repository at this point in the history
* Add IP range input support (ipv4, ipv6) #98

- Update main.go to accept IP range from stdin and print the possible
  CIDRs

* Add test cases to validate RangeTOCIDR function

- Add test case for singleCIDR, multipleCIDRs and ip6 range.
- Convert the []net.IPNet to []string before comparing the expected.

* Add check to validate the IP range and Update README

- Accept the list of IP ranges
- Fatal() if the first IP is greater than last IP
- Fatal() if IP range contains more than 2 values.
- Update README.md to add the ip range input documentation.

* Update IP range functionality to accept only single range

- Remove the unnecessary for loop.
- Update the READ.md to remove the IP range list block

* Remove the IP comparing logic to a function

- Add new function `GetCIDRFromIPRange` which validate the input
  If input is wrong send the error otherwise returns the sorted list
  of CIDR ranges.
- Update the test case to test `GetCIDRFromIPRange` function.
- Add the wrong input IP range test case.
- Remove the IP comparing and sorting logic from main.go

* Remove the typo

* Update code to handle the IP range expansion

- Update the `main.go` to handle the case to IP range expansion
- rename the `CIDRFromIPRange` to `IPRangeInput`
- Add the if block which handles the case when Input is IP range.

* Remove old cidrs before appending new cidrs in allCidrs

* Move logic to common function to avoid repetition. Do not overwrite
allCidrs list instead use a separate net.IP list.

* Add tests for process function,

* Break wg.Add(2) into two wg.Add(1)

* Make wg.Done as defer

* Handle case of multiple IP range, combination of CIDR and IP range

- Input may contain the multiple CIDRs and multiple IP ranges
  eg. `166.8.0.0/16,166.11.0.0/16,166.9.0.0-166.10.255.255`
- Handle the above input for arggregation, count, etc
- Move the string split logic from `main()` to `process()` function
- Add the new variable IPRangeMap which stores multiple IP range

* Add the comment for ipRange block

* Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.
Replace ipRangeMap to ipRangeList.

- map key is not being used so dropped the map implementation.

* Resolve the requested changes

- Remove the IPRangeInput variable
- Simplify checking len of IPRange Input
- Use require package for checking expected and got in test cases

* Replace string.Equal to require package for testing

* Update goflags version

- mapcidr and goflag had conflicting version to solve that update the
  goflags version

* Update sorting behaviour

- Expand the CIDR then sort
- Before it was converting IPs to CIDR then sort.
- Add `getIPList()` which expands the CIDRs to IP for sorting

* Remove the unnecessary err block

Co-authored-by: Sandeep Singh <[email protected]>
Co-authored-by: Jaideep Khandelwal <[email protected]>
Co-authored-by: Siddharth Shashikar <[email protected]>
  • Loading branch information
4 people authored Sep 14, 2022
1 parent 4333a43 commit 4bb3bd9
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 8 deletions.
36 changes: 28 additions & 8 deletions cmd/mapcidr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ func ParseOptions() *Options {

// Miscellaneous
flagSet.CreateGroup("miscellaneous", "Miscellaneous",
flagSet.BoolVarP(&options.SortAscending, "sort", "s", false, "Sort input IPs/CIDRs in ascending order"),
flagSet.BoolVarP(&options.SortDescending, "sort-reverse", "sr", false, "Sort input IPs/CIDRs in descending order"),
flagSet.BoolVarP(&options.SortAscending, "sort", "s", false, "Sort input IPs in ascending order"),
flagSet.BoolVarP(&options.SortDescending, "sort-reverse", "sr", false, "Sort input IPs in descending order"),
flagSet.BoolVarP(&options.Shuffle, "shuffle-ip", "si", false, "Shuffle Input IPs in random order"),
flagSet.StringVarP(&options.ShufflePorts, "shuffle-port", "sp", "", "Shuffle Input IP:Port in random order"),
)
Expand Down Expand Up @@ -175,6 +175,10 @@ func (options *Options) validateOptions() error {
if options.FilterIP != nil && options.MatchIP != nil {
return errors.New("both match and filter mode specified")
}

if (options.SortAscending || options.SortDescending) && options.Aggregate {
return errors.New("can sort only IPs. sorting can't be used with aggregate")
}
return nil
}

Expand Down Expand Up @@ -390,17 +394,18 @@ func process(wg *sync.WaitGroup, chancidr, outputchan chan string) {
}

if hasSort {
ips := getIPList(allCidrs)
if options.SortDescending {
sort.Slice(allCidrs, func(i, j int) bool {
return bytes.Compare(allCidrs[j].IP, allCidrs[i].IP) < 0
sort.Slice(ips, func(i, j int) bool {
return bytes.Compare(ips[j], ips[i]) < 0
})
} else {
sort.Slice(allCidrs, func(i, j int) bool {
return bytes.Compare(allCidrs[i].IP, allCidrs[j].IP) < 0
sort.Slice(ips, func(i, j int) bool {
return bytes.Compare(ips[i], ips[j]) < 0
})
}
for _, cidr := range allCidrs {
outputchan <- cidr.String()
for _, ip := range ips {
outputchan <- ip.String()
}
}

Expand Down Expand Up @@ -494,3 +499,18 @@ func outputItems(f *os.File, items ...string) {
}
}
}

// returns the list of expanded IPs of given CIDR list
func getIPList(cidrs []*net.IPNet) []net.IP {
var ipList []net.IP
for _, cidr := range cidrs {
ips, err := mapcidr.IPAddressesAsStream(cidr.String())
if err != nil {
gologger.Fatal().Msgf("%s\n", err)
}
for ip := range ips {
ipList = append(ipList, net.ParseIP(ip))
}
}
return ipList
}
54 changes: 54 additions & 0 deletions cmd/mapcidr/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,60 @@ func TestProcess(t *testing.T) {
Aggregate: true,
},
expectedOutput: []string{"166.8.0.0/24"},
}, {
name: "IPsSortAscending",
chancidr: make(chan string),
outputchan: make(chan string),
options: Options{
FileCidr: []string{"1.1.1.1", "8.8.8.8", "255.255.255.255", "2.2.2.2", "2.4.4.4", "2.4.3.2", "9.9.9.9"},
SortAscending: true,
},
expectedOutput: []string{"1.1.1.1", "2.2.2.2", "2.4.3.2", "2.4.4.4", "8.8.8.8", "9.9.9.9", "255.255.255.255"},
}, {
name: "IPsSortDescending",
chancidr: make(chan string),
outputchan: make(chan string),
options: Options{
FileCidr: []string{"1.1.1.1", "255.255.255.255", "2.4.3.2", "2.2.2.2", "8.8.8.8", "2.4.4.4", "9.9.9.9"},
SortDescending: true,
},
expectedOutput: []string{"255.255.255.255", "9.9.9.9", "8.8.8.8", "2.4.4.4", "2.4.3.2", "2.2.2.2", "1.1.1.1"},
}, {
name: "CIDRsIPSortAscending",
chancidr: make(chan string),
outputchan: make(chan string),
options: Options{
FileCidr: []string{"10.40.0.0/30"},
SortAscending: true,
},
expectedOutput: []string{"10.40.0.0", "10.40.0.1", "10.40.0.2", "10.40.0.3"},
}, {
name: "CIDRsIPSortDescending",
chancidr: make(chan string),
outputchan: make(chan string),
options: Options{
FileCidr: []string{"10.40.1.0/30"},
SortDescending: true,
},
expectedOutput: []string{"10.40.1.3", "10.40.1.2", "10.40.1.1", "10.40.1.0"},
}, {
name: "IPRangeIPSortAscending",
chancidr: make(chan string),
outputchan: make(chan string),
options: Options{
FileCidr: []string{"192.168.0.0-192.168.0.3"},
SortAscending: true,
},
expectedOutput: []string{"192.168.0.0", "192.168.0.1", "192.168.0.2", "192.168.0.3"},
}, {
name: "IPRangeIIPSortDescending",
chancidr: make(chan string),
outputchan: make(chan string),
options: Options{
FileCidr: []string{"192.168.1.0-192.168.1.3"},
SortDescending: true,
},
expectedOutput: []string{"192.168.1.3", "192.168.1.2", "192.168.1.1", "192.168.1.0"},
},
}
var wg sync.WaitGroup
Expand Down

0 comments on commit 4bb3bd9

Please sign in to comment.