lxz il y a 2 jours
Parent
commit
8ccf57f824

+ 58 - 11
DHCP/api/api.go

@@ -5,22 +5,24 @@ import (
 	"dhcp/global"
 	"dhcp/internal/ip"
 	"dhcp/internal/service"
+	"dhcp/model"
 	"dhcp/result"
 	"github.com/gin-gonic/gin"
 )
 
-//
-//func Redirect(c *gin.Context) {
-//	c.Redirect(http.StatusMovedPermanently, "")
-//}
-
 func DHCPServerRegisterRoute(r *gin.Engine) {
-	dhcpserver := r.Group("/dhcpserver")
-	dhcpserver.POST("/start", DHCPServerStart)
-	dhcpserver.POST("/stop", DHCPServerStop)
-	dhcpserver.GET("/info", DHCPServerInfo)
-	dhcpserver.GET("/localip", GetLocalIPAndInterfaces)
-	dhcpserver.POST("/delete", DHCPServerDelete)
+	dhcpServer := r.Group("/dhcpServer")
+	dhcpServer.POST("/start", DHCPServerStart)
+	dhcpServer.POST("/stop", DHCPServerStop)
+	dhcpServer.GET("/info", DHCPServerInfo)
+	dhcpServer.GET("/localip", GetLocalIPAndInterfaces)
+	dhcpServer.POST("/delete", DHCPServerDelete)
+	dhcpInfo := r.Group("/dhcpInfo")
+	dhcpInfo.POST("/add", AddDHCPInfo)
+	dhcpInfo.GET("/get", GetDHCPInfo)
+	dhcpInfo.GET("/delete", DeleteDHCPInfo)
+	dhcpInfo.POST("/update", UpdateDHCPInfo)
+	dhcpInfo.GET("/getByMac", GetDHCPInfoByMac)
 }
 
 func DHCPServerStart(c *gin.Context) {
@@ -81,3 +83,48 @@ func GetLocalIPAndInterfaces(c *gin.Context) {
 	re := ip.GetLocalIPAndInterface()
 	c.JSON(200, re)
 }
+
+func AddDHCPInfo(c *gin.Context) {
+	var req model.DHCP
+	if err := c.ShouldBindJSON(&req); err != nil {
+		c.JSON(200, result.Result{
+			Code: 400,
+			Data: nil,
+			Msg:  "参数错误",
+		})
+		return
+	}
+	re := service.AddDHCPInfo(req)
+	c.JSON(200, re)
+}
+
+func GetDHCPInfo(c *gin.Context) {
+	re := service.GetDHCPInfo()
+	c.JSON(200, re)
+}
+
+func DeleteDHCPInfo(c *gin.Context) {
+	req := c.Query("mac")
+	re := service.DeleteDHCPInfo(req)
+	c.JSON(200, re)
+}
+
+func UpdateDHCPInfo(c *gin.Context) {
+	var req model.DHCP
+	if err := c.ShouldBindJSON(&req); err != nil {
+		c.JSON(200, result.Result{
+			Code: 400,
+			Data: nil,
+			Msg:  "参数错误",
+		})
+		return
+	}
+	re := service.UpdateDHCPInfo(req)
+	c.JSON(200, re)
+}
+
+func GetDHCPInfoByMac(c *gin.Context) {
+	req := c.Query("mac")
+	re := service.GetDHCPInfoByMac(req)
+	c.JSON(200, re)
+}

+ 1 - 1
DHCP/api/request/requst.go

@@ -1,7 +1,7 @@
 package request
 
 type DHCPService struct {
-	Mode           string   `json:"mode"`
+	Mode           string   `json:"model"`
 	BindInterface  string   `json:"bindInterface"`
 	NetworkSegment string   `json:"networkSegment"`
 	DefaultGateway string   `json:"defaultGateway"`

+ 4 - 0
DHCP/global/global.go

@@ -2,10 +2,14 @@ package global
 
 import (
 	"github.com/go-logr/logr"
+	"gorm.io/gorm"
 )
 
 var Log logr.Logger
 
+// 定义数据库指针
+var DB *gorm.DB
+
 type JWTConfig struct {
 	SigningKey string `mapstructure:"key" json:"key"`
 }

+ 0 - 84
DHCP/internal/backend/dhcp.go

@@ -1,84 +0,0 @@
-package backend
-
-import (
-	"github.com/glebarez/sqlite"
-	"gorm.io/gorm"
-	"os"
-	"path/filepath"
-)
-
-type Dhcp struct {
-	Id               int      `json:"id" gorm:"id"`                               // ID
-	MACAddress       string   `json:"mac_address" gorm:"mac_address"`             // MAC地址
-	IPAddress        string   `json:"ip_address" gorm:"ip_address"`               // IP地址
-	SubnetMask       string   `json:"subnet_mask" gorm:"subnet_mask"`             // 子网掩码
-	DefaultGateway   string   `json:"default_gateway" gorm:"default_gateway"`     // 默认网关
-	NameServers      []string `json:"name_servers" gorm:"name_servers"`           // DNS服务器
-	DomainName       string   `json:"domain_name" gorm:"domain_name"`             // 域名
-	BroadcastAddress string   `json:"broadcast_address" gorm:"broadcast_address"` // 广播地址
-	NTPServers       []string `json:"ntp_servers" gorm:"ntp_servers"`             // NTP服务器
-	VLANID           string   `json:"vlan_id" gorm:"vlan_id"`                     // VLAN ID
-	LeaseTime        uint32   `json:"lease_time" gorm:"lease_time"`               // 租约
-	DomainSearch     []string `json:"domain_search" gorm:"domain_search"`         // 域名搜索
-	ServerIP         string   `json:"server_ip" gorm:"server_ip"`                 // 服务器IP
-}
-
-// 定义数据库指针
-var db *gorm.DB
-
-// 初始化数据库指针
-func InitDB() {
-	executablePath, err := os.Executable()
-	if err != nil {
-		panic(err)
-	}
-	dbPath := filepath.Join(filepath.Dir(executablePath), "dhcp.db")
-	db, err = gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
-	if err != nil {
-		panic(err)
-	}
-	db.AutoMigrate(&Dhcp{})
-}
-
-func AddDhcp(dhcp Dhcp) error {
-	var dp Dhcp
-	tx := db.Model(&Dhcp{}).Where("mac_address = ?", dhcp.MACAddress).First(dp)
-	if tx.Error != nil {
-		return tx.Error
-	}
-	if dp.Id == 0 {
-		tx = db.Create(&dhcp)
-	} else {
-		tx = db.Model(&Dhcp{}).Where("mac_address = ?", dhcp.MACAddress).Updates(dhcp)
-	}
-
-	if tx.Error != nil {
-		return tx.Error
-	}
-	return nil
-}
-
-func GetDhcp(macAddress string) (Dhcp, error) {
-	var dhcp Dhcp
-	tx := db.Model(&Dhcp{}).Where("mac_address = ?", macAddress).First(&dhcp)
-	if tx.Error != nil {
-		return dhcp, tx.Error
-	}
-	return dhcp, nil
-}
-
-func DeleteDhcp(macAddress string) error {
-	tx := db.Model(&Dhcp{}).Where("mac_address = ?", macAddress).Delete(&Dhcp{})
-	if tx.Error != nil {
-		return tx.Error
-	}
-	return nil
-}
-
-func UpdateDhcp(dhcp Dhcp) error {
-	tx := db.Model(&Dhcp{}).Where("mac_address = ?", dhcp.MACAddress).Updates(dhcp)
-	if tx.Error != nil {
-		return tx.Error
-	}
-	return nil
-}

+ 62 - 0
DHCP/internal/dao/dhcp.go

@@ -0,0 +1,62 @@
+package dao
+
+import (
+	"dhcp/global"
+	"dhcp/model"
+)
+
+// 初始化数据库指针
+
+var db = global.DB
+
+func AddDHCP(dhcp model.DHCP) error {
+	var dp model.DHCP
+	tx := db.Model(&model.DHCP{}).Where("mac_address = ?", dhcp.MACAddress).First(dp)
+	if tx.Error != nil {
+		return tx.Error
+	}
+	if dp.Id == 0 {
+		tx = db.Create(&dhcp)
+	} else {
+		tx = db.Model(&model.DHCP{}).Where("mac_address = ?", dhcp.MACAddress).Updates(dhcp)
+	}
+
+	if tx.Error != nil {
+		return tx.Error
+	}
+	return nil
+}
+
+func GetDHCPByMac(macAddress string) (model.DHCP, error) {
+	var dhcp model.DHCP
+	tx := db.Model(&model.DHCP{}).Where("mac_address = ?", macAddress).First(&dhcp)
+	if tx.Error != nil {
+		return dhcp, tx.Error
+	}
+	return dhcp, nil
+}
+
+func GetDHCP() ([]model.DHCP, error) {
+	var dhcp []model.DHCP
+	tx := db.Model(&model.DHCP{}).Find(&dhcp)
+	if tx.Error != nil {
+		return nil, tx.Error
+	}
+	return dhcp, nil
+}
+
+func DeleteDHCP(macAddress string) error {
+	tx := db.Model(&model.DHCP{}).Where("mac_address = ?", macAddress).Delete(&model.DHCP{})
+	if tx.Error != nil {
+		return tx.Error
+	}
+	return nil
+}
+
+func UpdateDHCP(dhcp model.DHCP) error {
+	tx := db.Model(&model.DHCP{}).Where("mac_address = ?", dhcp.MACAddress).Updates(dhcp)
+	if tx.Error != nil {
+		return tx.Error
+	}
+	return nil
+}

+ 6 - 4
DHCP/internal/backend/backend.go → DHCP/internal/dhcpServer/backend/backend.go

@@ -2,8 +2,10 @@ package backend
 
 import (
 	"context"
-	"dhcp/internal/data"
-	"dhcp/internal/handler"
+	"dhcp/internal/dao"
+	"dhcp/internal/dhcpServer/data"
+	"dhcp/internal/dhcpServer/handler"
+	"dhcp/model"
 	"errors"
 	"net"
 	"net/netip"
@@ -18,7 +20,7 @@ func NewBackend() handler.BackendReader {
 }
 
 func (b *Backend) GetByMac(ctx context.Context, addr net.HardwareAddr, s string) (*data.DHCP, error) {
-	dp, err := GetDhcp(addr.String())
+	dp, err := dao.GetDHCPByMac(addr.String())
 	if err != nil {
 		return nil, err
 	}
@@ -33,7 +35,7 @@ func (b *Backend) GetByIP(ctx context.Context, ip net.IP, s string) (*data.DHCP,
 	return nil, nil
 }
 
-func translate(dp Dhcp) (*data.DHCP, error) {
+func translate(dp model.DHCP) (*data.DHCP, error) {
 	var d data.DHCP
 	if dp.MACAddress != "" {
 		d.MACAddress = net.HardwareAddr(dp.MACAddress)

+ 162 - 0
DHCP/internal/dhcpServer/backend/generateIP.go

@@ -0,0 +1,162 @@
+package backend
+
+import (
+	"dhcp/global"
+	"dhcp/internal/dao"
+	"dhcp/internal/service"
+	"dhcp/model"
+	"math/rand"
+	"net"
+	"strconv"
+	"sync"
+	"time"
+)
+
+type DHCPTemplate struct {
+	DhcpInterface    string   //DHCP监听的端口
+	IPAddressRanges  string   // ip范围
+	DefaultGateway   string   // 默认网关
+	NameServers      []string // DNS
+	Hostname         string   // 主机名
+	DomainName       string   // 域名
+	BroadcastAddress string   // 广播地址
+	NTPServers       []string // NTP服务器
+	VLANID           string   // VLAN ID
+	LeaseTime        int      // 租约
+	Arch             string   // 架构
+	DomainSearch     []string // 域名搜索
+}
+
+var record = make(map[string]struct{})  //记录分配的ip
+var recordMac = make(map[string]string) //物理地址对应ip
+
+func InitIPRecord() {
+	all, err := dao.GetDHCP()
+	if err != nil {
+		global.Log.Info("初始化IP记录失败", err)
+	}
+	for _, v := range all {
+		record[v.IPAddress] = struct{}{}
+		recordMac[v.MACAddress] = v.IPAddress
+	}
+}
+
+func UpdateRecord(mac string, ip string) {
+	recordMac[mac] = ip
+	delete(record, ip)
+	record[ip] = struct{}{}
+}
+
+func DeleteRecord(mac string, ip string) {
+	delete(record, ip)
+	delete(recordMac, mac)
+}
+
+func CreateRecord(mac string, ip string) {
+	record[ip] = struct{}{}
+	recordMac[mac] = ip
+}
+
+func GenerateIP(mac string, ifName string) (model.DHCP, error) {
+	var m sync.Mutex
+
+	dh := service.DHCPServiceInfoMap[ifName]
+	d := DHCPTemplate{
+		DhcpInterface:   dh.BindInterface,
+		IPAddressRanges: dh.NetworkSegment,
+		DefaultGateway:  dh.DefaultGateway,
+		NameServers:     dh.NameServers,
+		Hostname:        dh.Hostname,
+		LeaseTime:       86400,
+	}
+	var randomIP net.IP
+
+	// 确定网段范围
+	ip, ipNet, err := net.ParseCIDR(d.IPAddressRanges)
+	if err != nil {
+		global.Log.Error(err, "解析网段失败")
+		return model.DHCP{}, err
+	}
+	if v, ok := recordMac[mac]; !ok {
+		network := ip.Mask(ipNet.Mask)
+		minIP := network.To4()
+		maxIP := net.IPv4(minIP[0]|^ipNet.Mask[0],
+			minIP[1]|^ipNet.Mask[1], minIP[2]|^ipNet.Mask[2],
+			minIP[3]|^ipNet.Mask[3]).To4()
+		// 生成随机种子
+		rand.NewSource(time.Now().UnixNano())
+		for {
+			randomIP = generateRandomIP(minIP, maxIP)
+			if _, ok := record[randomIP.String()]; !ok {
+				m.Lock()
+				record[randomIP.String()] = struct{}{}
+				recordMac[mac] = randomIP.String()
+				m.Unlock()
+				break
+			}
+		}
+	} else {
+		randomIP = net.ParseIP(v)
+	}
+
+	// 构建DHCP信息
+	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]))
+	dhcp := buildDHCP(randomIP.String(), subnetMask, mac, d)
+
+	_ = dao.AddDHCP(dhcp)
+
+	return dhcp, err
+}
+
+func generateRandomIP(min, max net.IP) net.IP {
+	// IP地址是32位的,每位都是一个字节
+	ip := make(net.IP, len(min))
+	for i := range min {
+		n := int(max[i] - min[i])
+		if n == 0 {
+			ip[i] = min[i]
+		} else {
+			ip[i] = byte(rand.Intn(n) + int(min[i]))
+		}
+	}
+	if ip.Equal(min) || ip.Equal(max) {
+		return generateRandomIP(min, max)
+	}
+	return ip
+}
+
+func buildDHCP(randomIP string, subnetMask, mac string, d DHCPTemplate) model.DHCP {
+
+	ipinfo := model.DHCP{
+		Interface:        d.DhcpInterface,
+		MACAddress:       mac,
+		IPAddress:        randomIP,
+		SubnetMask:       subnetMask,
+		DefaultGateway:   d.DefaultGateway,
+		NameServers:      d.NameServers,
+		DomainName:       d.DomainName,
+		BroadcastAddress: d.BroadcastAddress,
+		NTPServers:       d.NTPServers,
+		VLANID:           d.VLANID,
+		LeaseTime:        uint32(d.LeaseTime),
+		DomainSearch:     d.DomainSearch,
+	}
+	return ipinfo
+}
+
+func isIPInSubnet(ip, ifName string) bool {
+	// Parse the IP address
+	ipAddr := net.ParseIP(ip)
+	if ipAddr == nil {
+		return false
+	}
+
+	// Parse the subnet
+	_, ipNet, err := net.ParseCIDR(service.DHCPServiceInfoMap[ifName].NetworkSegment)
+	if err != nil {
+		return false
+	}
+
+	// Check if the IP address is in the subnet
+	return ipNet.Contains(ipAddr)
+}

+ 0 - 0
DHCP/internal/data/data.go → DHCP/internal/dhcpServer/data/data.go


+ 1 - 1
DHCP/handler/handler.go → DHCP/internal/dhcpServer/handler/handler.go

@@ -3,7 +3,7 @@ package handler
 
 import (
 	"context"
-	"dhcp/data"
+	"dhcp/internal/dhcpServer/data"
 	"net"
 )
 

+ 2 - 2
DHCP/handler/proxy/proxy.go → DHCP/internal/dhcpServer/handler/proxy/proxy.go

@@ -15,8 +15,8 @@ package proxy
 
 import (
 	"context"
-	"dhcp/data"
-	"dhcp/handler"
+	"dhcp/internal/dhcpServer/data"
+	"dhcp/internal/dhcpServer/handler"
 	"errors"
 	"fmt"
 	"net"

+ 1 - 1
DHCP/handler/reservation/handler.go → DHCP/internal/dhcpServer/handler/reservation/handler.go

@@ -2,7 +2,7 @@ package reservation
 
 import (
 	"context"
-	"dhcp/data"
+	"dhcp/internal/dhcpServer/data"
 	"errors"
 	"github.com/go-logr/logr"
 	"github.com/insomniacslk/dhcp/dhcpv4"

+ 1 - 1
DHCP/handler/reservation/noop.go → DHCP/internal/dhcpServer/handler/reservation/noop.go

@@ -3,7 +3,7 @@ package reservation
 
 import (
 	"context"
-	"dhcp/data"
+	"dhcp/internal/dhcpServer/data"
 	"errors"
 	"net"
 )

+ 1 - 1
DHCP/handler/reservation/option.go → DHCP/internal/dhcpServer/handler/reservation/option.go

@@ -2,7 +2,7 @@ package reservation
 
 import (
 	"context"
-	"dhcp/data"
+	"dhcp/internal/dhcpServer/data"
 	"github.com/insomniacslk/dhcp/dhcpv4"
 	"net/netip"
 )

+ 1 - 1
DHCP/handler/reservation/reservation.go → DHCP/internal/dhcpServer/handler/reservation/reservation.go

@@ -2,7 +2,7 @@
 package reservation
 
 import (
-	"dhcp/handler"
+	"dhcp/internal/dhcpServer/handler"
 	"github.com/go-logr/logr"
 	"net/netip"
 )

+ 1 - 1
DHCP/server/dhcp.go → DHCP/internal/dhcpServer/server/dhcp.go

@@ -3,7 +3,7 @@ package server
 
 import (
 	"context"
-	"dhcp/data"
+	"dhcp/internal/dhcpServer/data"
 	"net"
 
 	"github.com/go-logr/logr"

+ 4 - 4
DHCP/internal/service/dhcp.go

@@ -4,10 +4,10 @@ import (
 	"context"
 	"dhcp/api/request"
 	"dhcp/code"
-	"dhcp/internal/backend"
-	"dhcp/internal/handler/proxy"
+	"dhcp/internal/dhcpServer/backend"
+	"dhcp/internal/dhcpServer/handler/proxy"
+	"dhcp/internal/dhcpServer/server"
 	"dhcp/internal/ip"
-	"dhcp/internal/server"
 	"dhcp/result"
 	"fmt"
 	"github.com/go-logr/logr"
@@ -20,7 +20,7 @@ var DHCPServiceMap = map[string]*DHCPService{}
 var DHCPServiceInfoMap = map[string]request.DHCPService{}
 
 type DhcpConfig struct {
-	Mode              string `yaml:"mode"`                 // 模式
+	Mode              string `yaml:"model"`                // 模式
 	BindAddr          string `yaml:"bind_addr"`            // 绑定地址
 	BindInterface     string `yaml:"bind_interface"`       //	绑定接口
 	IpForPacket       string `yaml:"ip_for_packet"`        // 包的ip

+ 53 - 0
DHCP/internal/service/dhcpInfo.go

@@ -0,0 +1,53 @@
+package service
+
+import (
+	"dhcp/code"
+	"dhcp/internal/dao"
+	"dhcp/model"
+	"dhcp/result"
+)
+
+func AddDHCPInfo(dhcpInfo model.DHCP) result.Result {
+	err := dao.AddDHCP(dhcpInfo)
+	return result.Result{
+		Status: err == nil,
+		Code:   code.SUCCESS,
+		Msg:    "添加成功",
+	}
+}
+
+func GetDHCPInfoByMac(mac string) result.Result {
+	dhcpInfo, err := dao.GetDHCPByMac(mac)
+	return result.Result{
+		Status: err == nil,
+		Code:   code.SUCCESS,
+		Data:   dhcpInfo,
+	}
+}
+
+func GetDHCPInfo() result.Result {
+	dhcpInfo, err := dao.GetDHCP()
+	return result.Result{
+		Status: err == nil,
+		Code:   code.SUCCESS,
+		Data:   dhcpInfo,
+	}
+}
+
+func UpdateDHCPInfo(dhcpInfo model.DHCP) result.Result {
+	err := dao.UpdateDHCP(dhcpInfo)
+	return result.Result{
+		Status: err == nil,
+		Code:   code.SUCCESS,
+		Msg:    "更新成功",
+	}
+}
+
+func DeleteDHCPInfo(mac string) result.Result {
+	err := dao.DeleteDHCP(mac)
+	return result.Result{
+		Status: err == nil,
+		Code:   code.SUCCESS,
+		Msg:    "删除成功",
+	}
+}

+ 0 - 8
DHCP/main.go

@@ -7,14 +7,6 @@ import (
 	"syscall"
 )
 
-//	@title			smee
-//	@version		1.0
-//	@description	ipxe管理.
-
-//  @securityDefinitions.apikey ApiKeyAuth
-//  @in header
-//  @name Authorization
-
 func main() {
 
 	// 初始化日志

+ 18 - 0
DHCP/model/dhcp.go

@@ -0,0 +1,18 @@
+package model
+
+type DHCP struct {
+	Id               int      `json:"id" gorm:"id"`                               // ID
+	MACAddress       string   `json:"mac_address" gorm:"mac_address"`             // MAC地址
+	IPAddress        string   `json:"ip_address" gorm:"ip_address"`               // IP地址
+	SubnetMask       string   `json:"subnet_mask" gorm:"subnet_mask"`             // 子网掩码
+	DefaultGateway   string   `json:"default_gateway" gorm:"default_gateway"`     // 默认网关
+	NameServers      []string `json:"name_servers" gorm:"name_servers"`           // DNS服务器
+	DomainName       string   `json:"domain_name" gorm:"domain_name"`             // 域名
+	BroadcastAddress string   `json:"broadcast_address" gorm:"broadcast_address"` // 广播地址
+	NTPServers       []string `json:"ntp_servers" gorm:"ntp_servers"`             // NTP服务器
+	VLANID           string   `json:"vlan_id" gorm:"vlan_id"`                     // VLAN ID
+	LeaseTime        uint32   `json:"lease_time" gorm:"lease_time"`               // 租约
+	DomainSearch     []string `json:"domain_search" gorm:"domain_search"`         // 域名搜索
+	ServerIP         string   `json:"server_ip" gorm:"server_ip"`                 // 服务器IP
+	Interface        string   `json:"interface" gorm:"interface"`                 // 网卡
+}

+ 1 - 1
demo3.2/main.go

@@ -17,7 +17,7 @@ import (
 		password := "password"
 
 		client, err := ipmi.NewClient(host, port, username, password)
-		// Support local mode client if runs directly on linux
+		// Support local model client if runs directly on linux
 		// client, err := ipmi.NewOpenClient()
 		if err != nil {
 			zap.S().Infof("err: %v", err)