package scan import ( "fmt" "log" "net" "net/netip" "strings" ) type AllAddress struct { Addr []net.IP `json:"addresses"` } type NetworkInterfaceNotFound struct {Passed string} // Implementing error interface func (n *NetworkInterfaceNotFound) Error() string { return fmt.Sprintf("Interface: '%s' not found.", n.Passed) } /* Recursive function to get all of the IPv4 addresses for each IPv4 network that the host is on :param addr: the address to recursively find the next address for :param out: a pointer to a struct containing a list of addresses */ func addressRecurse(addr netip.Addr, out *AllAddress) { ref := net.ParseIP(addr.String()) next := net.ParseIP(addr.Next().String()) v, err := netip.ParseAddr(next.String()) if err != nil { log.Fatal(err) } if ref.Mask(ref.DefaultMask()).String() == next.Mask(next.DefaultMask()).String() { out.Addr = append(out.Addr, next) addressRecurse(v, out) } } /* Retrieve the address of a specific interface :param name: the name of the interface to get the address of */ func getAddressByInterface(name string) ([]net.Addr, error) { interfaces, err := net.Interfaces() if err != nil { return nil, err } for idx := range interfaces { if interfaces[idx].Name == name { return interfaces[idx].Addrs() } } return nil, &NetworkInterfaceNotFound{Passed: name} } /* Utilized a recursive function to find all addresses in the address space that the host belongs. Returns a pointer to an AllAddresses struct who has a list of net.IP structs inside */ func GetAllAddresses(name string) (*AllAddress, error){ addresses, err := getAddressByInterface(name) if err != nil { return nil, err } out := &AllAddress{} for idx := range addresses { ip := net.ParseIP(strings.Split(addresses[idx].String(), "/")[0]) root, err := netip.ParseAddr(ip.Mask(ip.DefaultMask()).String()) if err != nil { continue } if root.IsLoopback() { continue } addressRecurse(root, out) } return out, nil }