generateIP.go 3.8 KB

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