local.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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, max int) {
  54. if len(ipmap.Ipv4s) > max {
  55. return
  56. }
  57. next := getNextAddr(ipmap.Current.String())
  58. nextNet := getNetwork(next, ipmap.Mask)
  59. currentNet := ipmap.NetworkAddr.String()
  60. if nextNet != currentNet {
  61. return
  62. }
  63. ipmap.Current = net.ParseIP(next)
  64. ipmap.Ipv4s = append(ipmap.Ipv4s, net.ParseIP(next))
  65. addressRecurse(ipmap, max)
  66. }
  67. /*
  68. Retrieve the address of a specific interface
  69. :param name: the name of the interface to get the address of
  70. */
  71. func getAddressByInterface(name string) ([]net.Addr, error) {
  72. interfaces, err := net.Interfaces()
  73. if err != nil {
  74. return nil, err
  75. }
  76. for idx := range interfaces {
  77. if interfaces[idx].Name == name {
  78. return interfaces[idx].Addrs()
  79. }
  80. }
  81. return nil, &NetworkInterfaceNotFound{Passed: name}
  82. }
  83. /*
  84. Get all of the IPv4 addresses in the network that 'addr' belongs to. YOU MUST PASS THE ADDRESS WITH CIDR NOTATION
  85. i.e. '192.168.50.1/24'
  86. :param addr: the ipv4 address to use for subnet discovery
  87. */
  88. func GetNetworkAddresses(addr string) (*IpSubnetMapper, error) {
  89. ipmap := &IpSubnetMapper{Ipv4s: []net.IP{}}
  90. ip, net, err := net.ParseCIDR(addr)
  91. if err != nil {
  92. return nil, err
  93. }
  94. mask, err := strconv.Atoi(strings.Split(addr, "/")[1])
  95. if err != nil {
  96. return nil, err
  97. }
  98. ipmap.NetworkAddr = ip.Mask(net.Mask)
  99. ipmap.Mask = mask
  100. ipmap.Current = ip.Mask(net.Mask)
  101. addressRecurse(ipmap, 65535)
  102. return ipmap, nil
  103. }