Skip to content

Commit

Permalink
Add Next/PreviousSubnet() to netutil pkg
Browse files Browse the repository at this point in the history
* Add Next/PreviousSubnet()
* Add these examples
  • Loading branch information
yunkon-kim committed Jan 12, 2024
1 parent 8ca744c commit b1c8471
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
72 changes: 72 additions & 0 deletions src/core/common/netutil/netutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,75 @@ func cidrOverlap(cidr1, cidr2 string) bool {
_, net2, _ := net.ParseCIDR(cidr2)
return net1.Contains(net2.IP) || net2.Contains(net1.IP)
}

// ///////////////////////////////////////////////////////////////////////////////////
// NextSubnet find and check the next subnet based on the base/parent network.
func NextSubnet(currentSubnetCIDR string, baseNetworkCIDR string) (string, error) {
// Parse the current subnet
_, currentNet, err := net.ParseCIDR(currentSubnetCIDR)
if err != nil {
return "", err
}

// Parse the base network
_, baseNet, err := net.ParseCIDR(baseNetworkCIDR)
if err != nil {
return "", err
}

// Convert the current subnet's IP to uint32
currentIPInt := IpToUint32(currentNet.IP)

// Calculate the size of the current subnet
maskSize, _ := currentNet.Mask.Size()
subnetSize := uint32(1 << (32 - maskSize))

// Calculate the next subnet's starting IP
nextIPInt := currentIPInt + subnetSize

// Convert the next IP to net.IP
nextIP := Uint32ToIP(nextIPInt)

// Check if the next subnet is within the base network range
if !baseNet.Contains(nextIP) {
return "", fmt.Errorf("the next subnet is outside the base network range")
}

return fmt.Sprintf("%s/%d", nextIP.String(), maskSize), nil
}


// PreviousSubnet find and check the previous subnet based on the base/parent network.
func PreviousSubnet(currentSubnet string, baseNetworkCIDR string) (string, error) {
// Parse the current subnet
_, currentNet, err := net.ParseCIDR(currentSubnet)
if err != nil {
return "", err
}

// Parse the base network
_, baseNet, err := net.ParseCIDR(baseNetworkCIDR)
if err != nil {
return "", err
}

// Convert the current subnet's IP to uint32
currentIPInt := IpToUint32(currentNet.IP)

// Calculate the size of the current subnet
maskSize, _ := currentNet.Mask.Size()
subnetSize := uint32(1 << (32 - maskSize))

// Calculate the previous subnet's starting IP
previousIPInt := currentIPInt - subnetSize

// Convert the previous IP to net.IP
previousIP := Uint32ToIP(previousIPInt)

// Check if the previous subnet is within the base network range
if !baseNet.Contains(previousIP) {
return "", fmt.Errorf("the previous subnet is outside the base network range")
}

return fmt.Sprintf("%s/%d", previousIP.String(), maskSize), nil
}
76 changes: 76 additions & 0 deletions src/examples/netutil/netutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,4 +217,80 @@ func runExample(cmd *cobra.Command, args []string) {
}
fmt.Printf("[Subnetting result]\n%s\n", string(pretty))

///////////////////////////////////////////////////////////////////////////////////////////////////
fmt.Println("\n\nNextSubnet() test example")

baseNetwork := "10.0.0.0/16"
currentSubnet0 := "10.0.0.0/18"
currentSubnet1 := "10.0.64.0/18"
currentSubnet2 := "10.0.128.0/18"
currentSubnet3 := "10.0.192.0/18"

fmt.Printf("[NextSubnet() Case1] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet0)
nextSubnet, err := netutil.NextSubnet(currentSubnet0, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Next Subnet:", nextSubnet)
}

fmt.Printf("[NextSubnet() Case2] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet1)
nextSubnet, err = netutil.NextSubnet(currentSubnet1, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Next Subnet:", nextSubnet)
}

fmt.Printf("[NextSubnet() Case3] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet2)
nextSubnet, err = netutil.NextSubnet(currentSubnet2, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Next Subnet:", nextSubnet)
}

fmt.Printf("[NextSubnet() Case4] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet3)
nextSubnet, err = netutil.NextSubnet(currentSubnet3, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Next Subnet:", nextSubnet)
}

///////////////////////////////////////////////////////////////////////////////////////////////////
fmt.Println("\n\nPreviousSubnet() test example")

fmt.Printf("[PreviousSubnet() Case1] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet0)
previousSubnet, err := netutil.PreviousSubnet(currentSubnet0, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Previous Subnet:", previousSubnet)
}

fmt.Printf("[PreviousSubnet() Case2] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet1)
previousSubnet, err = netutil.PreviousSubnet(currentSubnet1, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Previous Subnet:", previousSubnet)
}

fmt.Printf("[PreviousSubnet() Case3] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet2)
previousSubnet, err = netutil.PreviousSubnet(currentSubnet2, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Previous Subnet:", previousSubnet)
}

fmt.Printf("[PreviousSubnet() Case4] Base Network CIDR: %s, Current Subnet CIDR: %s\n", baseNetwork, currentSubnet3)
previousSubnet, err = netutil.PreviousSubnet(currentSubnet3, baseNetwork)
if err != nil {
fmt.Println(" Error:", err)
} else {
fmt.Println(" Previous Subnet:", previousSubnet)
}

}

0 comments on commit b1c8471

Please sign in to comment.