Changed GenerateHosts implementation to take IP, CIDR, and subnet masks arguments for scanning

This commit is contained in:
David J. Allen 2023-10-17 14:45:35 -06:00
parent 555ecf679d
commit 48b2264053
3 changed files with 46 additions and 66 deletions

View file

@ -2,6 +2,7 @@ package cmd
import ( import (
"fmt" "fmt"
"net"
"os" "os"
"path" "path"
@ -16,7 +17,7 @@ var (
begin uint8 begin uint8
end uint8 end uint8
subnets []string subnets []string
subnetMasks []string subnetMasks []net.IP
disableProbing bool disableProbing bool
) )
@ -30,14 +31,20 @@ var scanCmd = &cobra.Command{
hostsToScan = hosts hostsToScan = hosts
} else { } else {
for i, subnet := range subnets { for i, subnet := range subnets {
if len(subnetMasks) > 0 { if len(subnet) <= 0 {
hostsToScan = append(hostsToScan, magellan.GenerateHostsWithSubnet(subnet, subnetMasks[i])...) return
} else { }
hostsToScan = append(hostsToScan, magellan.GenerateHosts(subnet)...)
} if len(subnetMasks) < i + 1 {
subnetMasks = append(subnetMasks, net.IP{255, 255, 255, 0})
}
hostsToScan = append(hostsToScan, magellan.GenerateHosts(subnet, &subnetMasks[i])...)
} }
} }
fmt.Printf("hosts to scan: %v\n", hostsToScan)
// set ports to use for scanning // set ports to use for scanning
portsToScan := []int{} portsToScan := []int{}
if len(ports) > 0 { if len(ports) > 0 {
@ -71,7 +78,7 @@ func init() {
// scanCmd.Flags().Uint8Var(&begin, "begin", 0, "set the starting point for range of IP addresses") // scanCmd.Flags().Uint8Var(&begin, "begin", 0, "set the starting point for range of IP addresses")
// scanCmd.Flags().Uint8Var(&end, "end", 255, "set the ending point for range of IP addresses") // scanCmd.Flags().Uint8Var(&end, "end", 255, "set the ending point for range of IP addresses")
scanCmd.Flags().StringSliceVar(&subnets, "subnet", []string{}, "set additional subnets") scanCmd.Flags().StringSliceVar(&subnets, "subnet", []string{}, "set additional subnets")
scanCmd.Flags().StringSliceVar(&subnetMasks, "subnet-mask", []string{}, "set the subnet masks to use for network") scanCmd.Flags().IPSliceVar(&subnetMasks, "subnet-mask", []net.IP{}, "set the subnet masks to use for network")
scanCmd.Flags().BoolVar(&disableProbing, "disable-probing", false, "disable probing scanned results for BMC nodes") scanCmd.Flags().BoolVar(&disableProbing, "disable-probing", false, "disable probing scanned results for BMC nodes")
rootCmd.AddCommand(scanCmd) rootCmd.AddCommand(scanCmd)

View file

@ -2,6 +2,7 @@ package magellan
import ( import (
"fmt" "fmt"
"math"
"net" "net"
"net/http" "net/http"
"sync" "sync"
@ -50,80 +51,47 @@ func rawConnect(host string, ports []int, timeout int, keepOpenOnly bool) []Scan
return results return results
} }
func GenerateHosts(subnet string, mask string, begin uint8, end uint8) []string {
hosts := []string{}
ip := net.ParseIP(subnet).To4()
for i := begin; i < end; i++ {
ip = util.GetNextIP(ip, 1)
hosts = append(hosts, fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]))
}
return hosts
}
func GenerateHostsWithCIDR(subnet string) []string { func GenerateHosts(subnet string, subnetMask *net.IP) []string {
// check for network with valid CIDR if subnet == "" || subnetMask == nil {
ip, network, err := net.ParseCIDR(subnet)
if err != nil && (network != nil || ip != nil) {
network.Mask = ip.DefaultMask()
}
// check for IP with no CIDR
if ip == nil {
ip = net.ParseIP(subnet)
if ip == nil {
return nil return nil
} }
}
if network == nil { // convert subnets from string to net.IP
network = &net.IPNet{ subnetIp := net.ParseIP(subnet)
Mask: ip.DefaultMask(), if subnetIp == nil {
// try parse CIDR instead
ip, network, err := net.ParseCIDR(subnet)
if err != nil {
return nil
}
subnetIp = ip
if network != nil {
t := net.IP(network.Mask)
subnetMask = &t
} }
} }
// get all IP addresses in network mask := net.IPMask(subnetMask.To4())
return generateHosts(ip, network.Mask)
}
func GenerateHostsWithSubnet(subnet string, subnetMask string) []string {
// if no subnet mask, use a default 24-bit mask (for now) // if no subnet mask, use a default 24-bit mask (for now)
if subnetMask != "" { return generateHosts(&subnetIp, &mask)
ip, network, err := net.ParseCIDR(subnet)
if err != nil && (network != nil || ip != nil) {
network.Mask = ip.DefaultMask()
}
// check for IP with no CIDR
if ip == nil {
ip = net.ParseIP(subnet)
if ip == nil {
return nil
}
}
if network == nil {
network = &net.IPNet{
Mask: ip.DefaultMask(),
}
}
return generateHosts(ip, network.Mask)
} else {
ip := net.ParseIP(subnetMask)
if ip != nil {
return []string{}
}
return generateHosts(ip, ip.DefaultMask())
}
} }
func generateHosts(ip net.IP, mask net.IPMask) []string { func generateHosts(ip *net.IP, mask *net.IPMask) []string {
// get all IP addresses in network // get all IP addresses in network
ones, _ := mask.Size() ones, _ := mask.Size()
hosts := []string{} hosts := []string{}
fmt.Printf("ones: %d\n", ones) end := int(math.Pow(2, float64((32-ones))))-1
for i := 0; i < 32-ones; i++ { for i := 0; i < end; i++ {
// ip[3] = byte(i) // ip[3] = byte(i)
ip = util.GetNextIP(ip, 1) ip = util.GetNextIP(ip, 1)
hosts = append(hosts, fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3])) if ip == nil {
continue
}
// host := fmt.Sprintf("%v.%v.%v.%v", (*ip)[0], (*ip)[1], (*ip)[2], (*ip)[3])
// fmt.Printf("host: %v\n", ip.String())
hosts = append(hosts, ip.String())
} }
return hosts return hosts
} }

View file

@ -18,7 +18,10 @@ func PathExists(path string) (bool, error) {
return false, err return false, err
} }
func GetNextIP(ip net.IP, inc uint) net.IP { func GetNextIP(ip *net.IP, inc uint) *net.IP {
if ip == nil {
return &net.IP{}
}
i := ip.To4() i := ip.To4()
v := uint(i[0])<<24 + uint(i[1])<<16 + uint(i[2])<<8 + uint(i[3]) v := uint(i[0])<<24 + uint(i[1])<<16 + uint(i[2])<<8 + uint(i[3])
v += inc v += inc
@ -26,7 +29,9 @@ func GetNextIP(ip net.IP, inc uint) net.IP {
v2 := byte((v >> 8) & 0xFF) v2 := byte((v >> 8) & 0xFF)
v1 := byte((v >> 16) & 0xFF) v1 := byte((v >> 16) & 0xFF)
v0 := byte((v >> 24) & 0xFF) v0 := byte((v >> 24) & 0xFF)
return net.IPv4(v0, v1, v2, v3) // return &net.IP{[]byte{v0, v1, v2, v3}}
r := net.IPv4(v0, v1, v2, v3)
return &r
} }
func MakeRequest(url string, httpMethod string, body []byte, headers map[string]string) (*http.Response, []byte, error) { func MakeRequest(url string, httpMethod string, body []byte, headers map[string]string) (*http.Response, []byte, error) {