local.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package kyoketsu
  2. import (
  3. "fmt"
  4. "log"
  5. "net"
  6. "net/netip"
  7. "strconv"
  8. "strings"
  9. )
  10. type NetworkInterfaceNotFound struct{ Passed string }
  11. // Implementing error interface
  12. func (n *NetworkInterfaceNotFound) Error() string {
  13. return fmt.Sprintf("Interface: '%s' not found.", n.Passed)
  14. }
  15. type IpSubnetMapper struct {
  16. Ipv4s []net.IP `json:"addresses"`
  17. NetworkAddr net.IP
  18. Current net.IP
  19. Mask int
  20. }
  21. /*
  22. Get the next IPv4 address of the address specified in the 'addr' argument,
  23. :param addr: the address to get the next address of
  24. */
  25. func getNextAddr(addr string) string {
  26. parsed, err := netip.ParseAddr(addr)
  27. if err != nil {
  28. log.Fatal("failed while parsing address in getNextAddr() ", err, "\n")
  29. }
  30. return parsed.Next().String()
  31. }
  32. /*
  33. get the network address of the ip address in 'addr' with the subnet mask from 'cidr'
  34. :param addr: the ipv4 address to get the network address of
  35. :param cidr: the CIDR notation of the subbet
  36. */
  37. func getNetwork(addr string, cidr int) string {
  38. addr = fmt.Sprintf("%s/%v", addr, cidr)
  39. ip, net, err := net.ParseCIDR(addr)
  40. if err != nil {
  41. log.Fatal("failed whilst attempting to parse cidr in getNetwork() ", err, "\n")
  42. }
  43. return ip.Mask(net.Mask).String()
  44. }
  45. /*
  46. Recursive function to get all of the IPv4 addresses for each IPv4 network that the host is on
  47. :param ipmap: a pointer to an IpSubnetMapper struct which contains domain details such as
  48. the subnet mask, the original network mask, and the current IP address used in the
  49. recursive function
  50. :param max: This is safety feature to prevent stack overflows, so you can manually set the depth to
  51. call the function
  52. */
  53. func addressRecurse(ipmap *IpSubnetMapper) {
  54. next := getNextAddr(ipmap.Current.String())
  55. nextNet := getNetwork(next, ipmap.Mask)
  56. currentNet := ipmap.NetworkAddr.String()
  57. if nextNet != currentNet {
  58. return
  59. }
  60. ipmap.Current = net.ParseIP(next)
  61. ipmap.Ipv4s = append(ipmap.Ipv4s, net.ParseIP(next))
  62. addressRecurse(ipmap)
  63. }
  64. /*
  65. Get all of the IPv4 addresses in the network that 'addr' belongs to. YOU MUST PASS THE ADDRESS WITH CIDR NOTATION
  66. i.e. '192.168.50.1/24'
  67. :param addr: the ipv4 address to use for subnet discovery
  68. */
  69. func GetNetworkAddresses(addr string) (*IpSubnetMapper, error) {
  70. ipmap := &IpSubnetMapper{Ipv4s: []net.IP{}}
  71. ip, net, err := net.ParseCIDR(addr)
  72. if err != nil {
  73. return nil, err
  74. }
  75. mask, err := strconv.Atoi(strings.Split(addr, "/")[1])
  76. if err != nil {
  77. return nil, err
  78. }
  79. ipmap.NetworkAddr = ip.Mask(net.Mask)
  80. ipmap.Mask = mask
  81. ipmap.Current = ip.Mask(net.Mask)
  82. addressRecurse(ipmap)
  83. return ipmap, nil
  84. }