123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- package accesscontrol
- import (
- "bytes"
- "errors"
- "net"
- "strconv"
- "strings"
- )
- //Break an ip range text into independent ip strings
- func BreakdownIpRange(ipRange string) []string {
- ipRange = strings.ReplaceAll(ipRange, " ", "")
- err := ValidateIpRange(ipRange)
- if err != nil {
- return []string{}
- }
- if !strings.Contains(ipRange, "-") {
- //This is not an ip range but a single ip
- return []string{ipRange}
- }
- //Break down the IP range
- results := []string{}
- ips := strings.Split(ipRange, "-")
- subnet := ips[0][:strings.LastIndex(ips[0], ".")]
- startD := ips[0][strings.LastIndex(ips[0], ".")+1:]
- if err != nil {
- return []string{}
- }
- endD := ips[1][strings.LastIndex(ips[0], ".")+1:]
- if err != nil {
- return []string{}
- }
- startDInt, err := strconv.Atoi(startD)
- endDInt, err := strconv.Atoi(endD)
- currentDInt := startDInt
- for currentDInt < endDInt+1 {
- results = append(results, subnet+"."+strconv.Itoa(currentDInt))
- currentDInt++
- }
- return results
- }
- //Check if an given ip in the given range
- func IpInRange(ip string, ipRange string) bool {
- ip = strings.TrimSpace(ip)
- ipRange = strings.ReplaceAll(ipRange, " ", "")
- if ip == ipRange {
- //For fields that the ipRange is the ip itself
- return true
- }
- //Try matching range
- if strings.Contains(ipRange, "-") {
- //Parse the source IP
- trial := net.ParseIP(ip)
- //Parse the IP range
- ips := strings.Split(ipRange, "-")
- ip1 := net.ParseIP(ips[0])
- if ip1 == nil {
- return false
- }
- ip2 := net.ParseIP(ips[1])
- if ip2 == nil {
- return false
- }
- if trial.To4() == nil {
- return false
- }
- if bytes.Compare(trial, ip1) >= 0 && bytes.Compare(trial, ip2) <= 0 {
- return true
- }
- return false
- }
- return false
- }
- //Check if the given IP Range string is actually an IP range
- func ValidateIpRange(ipRange string) error {
- ipRange = strings.TrimSpace(ipRange)
- ipRange = strings.ReplaceAll(ipRange, " ", "")
- if strings.Contains(ipRange, "-") {
- //This is a range
- if strings.Count(ipRange, "-") != 1 {
- //Invalid range defination
- return errors.New("Invalid ip range defination")
- }
- ips := strings.Split(ipRange, "-")
- //Check if the starting IP and ending IP are both valid
- if net.ParseIP(ips[0]) == nil {
- return errors.New("Starting ip is invalid")
- }
- if net.ParseIP(ips[1]) == nil {
- return errors.New("Ending ip is invalid")
- }
- //Check if the ending IP is larger than the starting IP
- startingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[0], ".", ""))
- endingIpInt, _ := strconv.Atoi(strings.ReplaceAll(ips[1], ".", ""))
- if startingIpInt >= endingIpInt {
- return errors.New("Invalid ip range: Starting IP is larger or equal to ending ip")
- }
- //Check if they are in the same subnet
- startSubnet := ips[0][:strings.LastIndex(ips[0], ".")]
- endSubnet := ips[1][:strings.LastIndex(ips[1], ".")]
- if startSubnet != endSubnet {
- //They are not in the same subnet
- return errors.New("IP range subnet mismatch")
- }
- } else {
- //This is a single IP instead of range. Check if it is a valid IP addr
- if net.ParseIP(ipRange) != nil {
- //Ok
- return nil
- } else {
- return errors.New("Invalid ip given")
- }
- }
- return nil
- }
|