package kyoketsu 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) } func getNextAddr(addr net.IP) (net.IP, error) { next, err := netip.ParseAddr(addr.String()) if err != nil { return nil, err } return net.ParseIP(next.Next().String()), nil } /* 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(ipmap *IpSubnetMapper, max int) { if len(ipmap.Ipv4s) > max { return } next, err := getNextAddr(ipmap.NetworkAddr) if err != nil { log.Println(err) return } ip, net, err := net.ParseCIDR(next.String()) if err != nil { log.Println(err) return } if ip.Mask(net.Mask).String() != ipmap.NetworkAddr.String() { return } ipmap.Ipv4s = append(ipmap.Ipv4s, next) addressRecurse(ipmap, max) } /* 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, maxDepth int) (*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(ip, ip, out, maxDepth) } return out, nil } /* 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 GetAllRemoteAddresses(addrs []string, maxDepth int) (*AllAddress, error) { out := &AllAddress{} var addresses []net.IP for i := range addrs { ip, _, err := net.ParseCIDR(addrs[i]) if err != nil { return nil, err } addresses = append(addresses, ip) } 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(ip, ip, out, maxDepth) } return out, nil } type IpSubnetMapper struct { Ipv4s []net.IP NetworkAddr net.IP Mask net.IPMask } func RefactorGetAllRemAddr(addr string) (*AllAddress, error) { // out := &AllAddress{} ipmap := &IpSubnetMapper{Ipv4s: []net.IP{}} ip, net, err := net.ParseCIDR(addr) if err != nil { return nil, err } ipmap.NetworkAddr = ip.Mask(net.Mask) ipmap.Mask = ip.DefaultMask() fmt.Printf("%+v\n", ip.Mask(net.Mask)) fmt.Println(ip.DefaultMask()) fmt.Printf("%s\n", net.IP.DefaultMask()) addressRecurse(ipmap, 2000) return nil, nil }