generateIP.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package backend
  2. import (
  3. "dhcp/global"
  4. "dhcp/internal/dao"
  5. "dhcp/internal/service"
  6. "dhcp/model"
  7. "math/rand"
  8. "net"
  9. "strconv"
  10. "sync"
  11. "time"
  12. )
  13. type DHCPTemplate struct {
  14. DhcpInterface string //DHCP监听的端口
  15. IPAddressRanges string // ip范围
  16. DefaultGateway string // 默认网关
  17. NameServers []string // DNS
  18. Hostname string // 主机名
  19. DomainName string // 域名
  20. BroadcastAddress string // 广播地址
  21. NTPServers []string // NTP服务器
  22. VLANID string // VLAN ID
  23. LeaseTime int // 租约
  24. Arch string // 架构
  25. DomainSearch []string // 域名搜索
  26. }
  27. var record = make(map[string]struct{}) //记录分配的ip
  28. var recordMac = make(map[string]string) //物理地址对应ip
  29. func InitIPRecord() {
  30. all, err := dao.GetDHCP()
  31. if err != nil {
  32. global.Log.Info("初始化IP记录失败", err)
  33. }
  34. for _, v := range all {
  35. record[v.IPAddress] = struct{}{}
  36. recordMac[v.MACAddress] = v.IPAddress
  37. }
  38. }
  39. func UpdateRecord(mac string, ip string) {
  40. recordMac[mac] = ip
  41. delete(record, ip)
  42. record[ip] = struct{}{}
  43. }
  44. func DeleteRecord(mac string, ip string) {
  45. delete(record, ip)
  46. delete(recordMac, mac)
  47. }
  48. func CreateRecord(mac string, ip string) {
  49. record[ip] = struct{}{}
  50. recordMac[mac] = ip
  51. }
  52. func GenerateIP(mac string, ifName string) (model.DHCP, error) {
  53. var m sync.Mutex
  54. dh := service.DHCPServiceInfoMap[ifName]
  55. d := DHCPTemplate{
  56. DhcpInterface: dh.BindInterface,
  57. IPAddressRanges: dh.NetworkSegment,
  58. DefaultGateway: dh.DefaultGateway,
  59. NameServers: dh.NameServers,
  60. Hostname: dh.Hostname,
  61. LeaseTime: 86400,
  62. }
  63. var randomIP net.IP
  64. // 确定网段范围
  65. ip, ipNet, err := net.ParseCIDR(d.IPAddressRanges)
  66. if err != nil {
  67. global.Log.Error(err, "解析网段失败")
  68. return model.DHCP{}, err
  69. }
  70. if v, ok := recordMac[mac]; !ok {
  71. network := ip.Mask(ipNet.Mask)
  72. minIP := network.To4()
  73. maxIP := net.IPv4(minIP[0]|^ipNet.Mask[0],
  74. minIP[1]|^ipNet.Mask[1], minIP[2]|^ipNet.Mask[2],
  75. minIP[3]|^ipNet.Mask[3]).To4()
  76. // 生成随机种子
  77. rand.NewSource(time.Now().UnixNano())
  78. for {
  79. randomIP = generateRandomIP(minIP, maxIP)
  80. if _, ok := record[randomIP.String()]; !ok {
  81. m.Lock()
  82. record[randomIP.String()] = struct{}{}
  83. recordMac[mac] = randomIP.String()
  84. m.Unlock()
  85. break
  86. }
  87. }
  88. } else {
  89. randomIP = net.ParseIP(v)
  90. }
  91. // 构建DHCP信息
  92. subnetMask := strconv.Itoa(int(ipNet.Mask[0])) + "." + strconv.Itoa(int(ipNet.Mask[1])) + "." + strconv.Itoa(int(ipNet.Mask[2])) + "." + strconv.Itoa(int(ipNet.Mask[3]))
  93. dhcp := buildDHCP(randomIP.String(), subnetMask, mac, d)
  94. _ = dao.AddDHCP(dhcp)
  95. return dhcp, err
  96. }
  97. func generateRandomIP(min, max net.IP) net.IP {
  98. // IP地址是32位的,每位都是一个字节
  99. ip := make(net.IP, len(min))
  100. for i := range min {
  101. n := int(max[i] - min[i])
  102. if n == 0 {
  103. ip[i] = min[i]
  104. } else {
  105. ip[i] = byte(rand.Intn(n) + int(min[i]))
  106. }
  107. }
  108. if ip.Equal(min) || ip.Equal(max) {
  109. return generateRandomIP(min, max)
  110. }
  111. return ip
  112. }
  113. func buildDHCP(randomIP string, subnetMask, mac string, d DHCPTemplate) model.DHCP {
  114. ipinfo := model.DHCP{
  115. Interface: d.DhcpInterface,
  116. MACAddress: mac,
  117. IPAddress: randomIP,
  118. SubnetMask: subnetMask,
  119. DefaultGateway: d.DefaultGateway,
  120. NameServers: d.NameServers,
  121. DomainName: d.DomainName,
  122. BroadcastAddress: d.BroadcastAddress,
  123. NTPServers: d.NTPServers,
  124. VLANID: d.VLANID,
  125. LeaseTime: uint32(d.LeaseTime),
  126. DomainSearch: d.DomainSearch,
  127. }
  128. return ipinfo
  129. }
  130. func isIPInSubnet(ip, ifName string) bool {
  131. // Parse the IP address
  132. ipAddr := net.ParseIP(ip)
  133. if ipAddr == nil {
  134. return false
  135. }
  136. // Parse the subnet
  137. _, ipNet, err := net.ParseCIDR(service.DHCPServiceInfoMap[ifName].NetworkSegment)
  138. if err != nil {
  139. return false
  140. }
  141. // Check if the IP address is in the subnet
  142. return ipNet.Contains(ipAddr)
  143. }