本文整理汇总了Golang中github.com/krolaw/dhcp4.Packet.CHAddr方法的典型用法代码示例。如果您正苦于以下问题:Golang Packet.CHAddr方法的具体用法?Golang Packet.CHAddr怎么用?Golang Packet.CHAddr使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/krolaw/dhcp4.Packet
的用法示例。
在下文中一共展示了Packet.CHAddr方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: informReplyPacket
// ReplyPacket creates a reply packet that a Server would send to a client.
// It uses the req Packet param to copy across common/necessary fields to
// associate the reply with the request.
func informReplyPacket(req dhcp4.Packet, mt dhcp4.MessageType, serverID net.IP, options []dhcp4.Option) dhcp4.Packet {
p := dhcp4.NewPacket(dhcp4.BootReply)
p.SetXId(req.XId())
p.SetHType(req.HType())
p[2] = req.HLen() // dhcp4 library does not provide a setter
p.SetFlags(req.Flags())
p.SetCIAddr(req.CIAddr())
p.SetCHAddr(req.CHAddr())
p.AddOption(dhcp4.OptionDHCPMessageType, []byte{byte(mt)})
p.AddOption(dhcp4.OptionServerIdentifier, []byte(serverID))
for _, o := range options {
p.AddOption(o.Code, o.Value)
}
p.PadToMinSize()
return p
}
示例2: ServeDHCP
func (h *DHCPHandler) ServeDHCP(p dhcp.Packet, msgType dhcp.MessageType, options dhcp.Options) (d dhcp.Packet) {
switch msgType {
case dhcp.Discover:
log.Info("discover received")
fallthrough
case dhcp.Request:
if msgType == dhcp.Request {
log.Info("request received")
}
hwaddr := p.CHAddr().String()
var msg dhcp.MessageType
if msgType == dhcp.Discover {
msg = dhcp.Offer
} else if msgType == dhcp.Request {
msg = dhcp.ACK
}
if _, ok := h.leases[hwaddr]; ok {
log.Infof("Replying with existing lease %s", h.leases[hwaddr].String())
return dhcp.ReplyPacket(p, msg, h.myIP, h.leases[hwaddr], time.Hour, nil)
} else {
log.Info("new interface; attempting to allocate ip")
h.allocatorMutex.Lock()
if h.latest == nil {
h.latest = h.allocator.IP
}
h.latest = dhcp.IPAdd(h.latest, 1)
h.leases[hwaddr] = h.latest.To4()
h.allocatorMutex.Unlock()
log.Infof("Replying with address %s for hardware addr %s", h.leases[hwaddr].String(), hwaddr)
return dhcp.ReplyPacket(p, msg, h.myIP, h.leases[hwaddr], time.Hour, nil)
}
}
return nil
}
示例3: ServeDHCP
func (h *DHCPHandler) ServeDHCP(p dhcp.Packet, msgType dhcp.MessageType, options dhcp.Options) (d dhcp.Packet) {
switch msgType {
case dhcp.Discover:
free, nic := -1, p.CHAddr().String()
for i, v := range h.leases { // Find previous lease
if v.nic == nic {
free = i
goto reply
}
}
if free = h.freeLease(); free == -1 {
return
}
reply:
return dhcp.ReplyPacket(p, dhcp.Offer, h.ip, dhcp.IPAdd(h.start, free), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
case dhcp.Request:
if server, ok := options[dhcp.OptionServerIdentifier]; ok && !net.IP(server).Equal(h.ip) {
return nil // Message not for this dhcp server
}
reqIP := net.IP(options[dhcp.OptionRequestedIPAddress])
if reqIP == nil {
reqIP = net.IP(p.CIAddr())
}
if len(reqIP) == 4 && !reqIP.Equal(net.IPv4zero) {
if leaseNum := dhcp.IPRange(h.start, reqIP) - 1; leaseNum >= 0 && leaseNum < h.leaseRange {
if l, exists := h.leases[leaseNum]; !exists || l.nic == p.CHAddr().String() {
h.leases[leaseNum] = lease{nic: p.CHAddr().String(), expiry: time.Now().Add(h.leaseDuration)}
return dhcp.ReplyPacket(p, dhcp.ACK, h.ip, net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
}
}
}
return dhcp.ReplyPacket(p, dhcp.NAK, h.ip, nil, 0, nil)
case dhcp.Release, dhcp.Decline:
nic := p.CHAddr().String()
for i, v := range h.leases {
if v.nic == nic {
delete(h.leases, i)
break
}
}
}
return nil
}
示例4: ServeDHCP
//ServeDHCP : function for every dhcp request
func (h *DHCPHandler) ServeDHCP(p dhcp.Packet, msgType dhcp.MessageType, options dhcp.Options) (d dhcp.Packet) {
// get an existing lease or make a new one
TheLease, err := h.leases.GetLease(p.CHAddr())
logger.Info("%s has an ip of %s ", TheLease.MAC, TheLease.IP)
if err != nil {
logger.Critical("lease get fail , %s", err)
return nil
}
// handle the DHCP transactions
switch msgType {
case dhcp.Discover:
logger.Debug("Discover %s", p.CHAddr())
return dhcp.ReplyPacket(p, dhcp.Offer, h.config.BaseIP.To4(), TheLease.GetIP(), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
case dhcp.Request:
logger.Debug("Request %s", p.CHAddr())
userClass := string(options[77])
switch userClass {
// initial hardware boot
case "iPXE":
logger.Notice("iPXE from %s on %v", TheLease.MAC, TheLease.Name)
rp := dhcp.ReplyPacket(p, dhcp.ACK, h.config.BaseIP.To4(), net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
rp.SetSIAddr(h.ip)
return rp
// scondary iPXE boot from tftp server
case "skinny":
logger.Notice("Booting Machine %s into %s", TheLease.Name, TheLease.Class)
if TheLease.Active == true {
h.skinnyOptions[dhcp.OptionHostName] = []byte(TheLease.Name)
h.skinnyOptions[dhcp.OptionBootFileName] = []byte("http://" + h.ip.String() + "/boot/" + TheLease.Distro + "/${net0/mac}")
}
rp := dhcp.ReplyPacket(p, dhcp.ACK, h.config.BaseIP.To4(), net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
h.skinnyOptions.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
return rp
default:
logger.Info("normal dhcp request")
if TheLease.Active == true {
h.skinnyOptions[dhcp.OptionHostName] = []byte(TheLease.Name)
}
rp := dhcp.ReplyPacket(p, dhcp.ACK, h.config.BaseIP.To4(), net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
return rp
}
case dhcp.Release:
logger.Debug("Release")
break
case dhcp.Decline:
logger.Debug("Decline")
break
}
return nil
}
示例5: ServeDHCP
func (h *DHCPHandler) ServeDHCP(p dhcp.Packet, msgType dhcp.MessageType, options dhcp.Options) (d dhcp.Packet) {
// options for booting device
skinnyOptions := dhcp.Options{
dhcp.OptionSubnetMask: []byte(h.config.Subnet.To4()),
dhcp.OptionBootFileName: []byte("http://" + h.ip.String() + "/choose"),
dhcp.OptionRouter: []byte(h.config.Gateway.To4()),
dhcp.OptionDomainNameServer: []byte(h.config.DNSServer.To4()),
dhcp.OptionDomainName: []byte(h.config.Domain),
}
// get an existing lease or make a new one
TheLease, err := h.leases.GetLease(p.CHAddr())
logger.Critical("IP for the lease is %s", TheLease.IP)
logger.Debug("%s", TheLease)
if err != nil {
logger.Critical("lease get fail , %s", err)
return nil
}
// handle the DHCP transactions
switch msgType {
case dhcp.Discover:
logger.Debug("Discover %s", p.CHAddr())
return dhcp.ReplyPacket(p, dhcp.Offer, h.config.BaseIP.To4(), TheLease.GetIP(), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
case dhcp.Request:
logger.Debug("Request %s", p.CHAddr())
userClass := string(options[77])
switch userClass {
// initial hardware boot
case "iPXE":
logger.Info("iPXE request")
rp := dhcp.ReplyPacket(p, dhcp.ACK, h.config.BaseIP.To4(), net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
h.options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
rp.SetSIAddr(h.ip)
return rp
// scondary iPXE boot from tftp server
case "skinny":
logger.Info("skinny request")
if TheLease.Active == true {
skinnyOptions[dhcp.OptionHostName] = []byte(TheLease.Name)
skinnyOptions[dhcp.OptionBootFileName] = []byte("http://" + h.ip.String() + "/boot/" + TheLease.Distro + "/${net0/mac}")
}
rp := dhcp.ReplyPacket(p, dhcp.ACK, h.config.BaseIP.To4(), net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
skinnyOptions.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
return rp
default:
logger.Info("normal dhcp request")
if TheLease.Active == true {
skinnyOptions[dhcp.OptionHostName] = []byte(TheLease.Name)
}
rp := dhcp.ReplyPacket(p, dhcp.ACK, h.config.BaseIP.To4(), net.IP(options[dhcp.OptionRequestedIPAddress]), h.leaseDuration,
skinnyOptions.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
return rp
}
case dhcp.Release:
fmt.Println("Release")
break
case dhcp.Decline:
fmt.Println("Decline")
break
}
return nil
}
示例6: ServeDHCP
func (h *DHCPHandler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dhcp4.Options) (d dhcp4.Packet) {
var macAddress string = strings.Join(strings.Split(p.CHAddr().String(), ":"), "")
switch msgType {
case dhcp4.Discover:
ip, err := h.leasePool.Assign(p.CHAddr().String())
if err != nil {
logging.Debug("DHCP", "err in lease pool - %s", err.Error())
return nil // pool is full
}
replyOptions := h.dhcpOptions.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList])
packet := dhcp4.ReplyPacket(p, dhcp4.Offer, h.settings.ServerIP, ip, h.settings.LeaseDuration, replyOptions)
// this is a pxe request
guidVal, is_pxe := options[97]
if is_pxe {
logging.Log("DHCP", "dhcp discover with PXE - CHADDR %s - IP %s - our ip %s", p.CHAddr().String(), ip.String(), h.settings.ServerIP.String())
guid := guidVal[1:]
packet.AddOption(60, []byte("PXEClient"))
packet.AddOption(97, guid)
packet.AddOption(43, h.fillPXE())
} else {
logging.Log("DHCP", "dhcp discover - CHADDR %s - IP %s", p.CHAddr().String(), ip.String())
}
return packet
case dhcp4.Request:
if server, ok := options[dhcp4.OptionServerIdentifier]; ok && !net.IP(server).Equal(h.settings.ServerIP) {
return nil // this message is not ours
}
requestedIP := net.IP(options[dhcp4.OptionRequestedIPAddress])
if requestedIP == nil {
requestedIP = net.IP(p.CIAddr())
}
if len(requestedIP) != 4 || requestedIP.Equal(net.IPv4zero) {
logging.Debug("DHCP", "dhcp request - CHADDR %s - bad request", p.CHAddr().String())
return nil
}
_, err := h.leasePool.Request(p.CHAddr().String(), requestedIP)
if err != nil {
logging.Debug("DHCP", "dhcp request - CHADDR %s - Requested IP %s - NO MATCH", p.CHAddr().String(), requestedIP.String())
return dhcp4.ReplyPacket(p, dhcp4.NAK, h.settings.ServerIP, nil, 0, nil)
}
replyOptions := h.dhcpOptions.SelectOrderOrAll(options[dhcp4.OptionParameterRequestList])
packet := dhcp4.ReplyPacket(p, dhcp4.ACK, h.settings.ServerIP, requestedIP, h.settings.LeaseDuration, replyOptions)
// this is a pxe request
guidVal, is_pxe := options[97]
if is_pxe {
logging.Log("DHCP", "dhcp request with PXE - CHADDR %s - Requested IP %s - our ip %s - ACCEPTED", p.CHAddr().String(), requestedIP.String(), h.settings.ServerIP.String())
guid := guidVal[1:]
packet.AddOption(60, []byte("PXEClient"))
packet.AddOption(97, guid)
packet.AddOption(43, h.fillPXE())
} else {
logging.Log("DHCP", "dhcp request - CHADDR %s - Requested IP %s - ACCEPTED", p.CHAddr().String(), requestedIP.String())
}
packet.AddOption(12, []byte("node"+macAddress)) // host name option
return packet
case dhcp4.Release, dhcp4.Decline:
return nil
}
return nil
}
示例7: ServeDHCP
// ServeDHCP is called by dhcp4.ListenAndServe when the service is started
func (d *DHCPService) ServeDHCP(packet dhcp4.Packet, msgType dhcp4.MessageType, reqOptions dhcp4.Options) (response dhcp4.Packet) {
switch msgType {
case dhcp4.Discover:
// RFC 2131 4.3.1
// FIXME: send to StatHat and/or increment a counter
mac := packet.CHAddr()
// Check MAC blacklist
if !d.isMACPermitted(mac) {
log.Printf("DHCP Discover from %s\n is not permitted", mac.String())
return nil
}
log.Printf("DHCP Discover from %s\n", mac.String())
// Look up the MAC entry with cascaded attributes
lease, found, err := d.db.GetMAC(mac, true)
if err != nil {
return nil
}
// Existing Lease
if found {
options := d.getOptionsFromMAC(lease)
log.Printf("DHCP Discover from %s (we offer %s from current lease)\n", lease.MAC.String(), lease.IP.String())
// for x, y := range reqOptions {
// log.Printf("\tR[%v] %v %s\n", x, y, y)
// }
// for x, y := range options {
// log.Printf("\tO[%v] %v %s\n", x, y, y)
// }
return dhcp4.ReplyPacket(packet, dhcp4.Offer, d.ip.To4(), lease.IP.To4(), d.getLeaseDurationForRequest(reqOptions, lease.Duration), options.SelectOrderOrAll(reqOptions[dhcp4.OptionParameterRequestList]))
}
// New Lease
ip := d.getIPFromPool()
if ip != nil {
options := d.getOptionsFromMAC(lease)
log.Printf("DHCP Discover from %s (we offer %s from pool)\n", mac.String(), ip.String())
// for x, y := range reqOptions {
// log.Printf("\tR[%v] %v %s\n", x, y, y)
// }
// for x, y := range options {
// log.Printf("\tO[%v] %v %s\n", x, y, y)
// }
return dhcp4.ReplyPacket(packet, dhcp4.Offer, d.ip.To4(), ip.To4(), d.getLeaseDurationForRequest(reqOptions, d.leaseDuration), options.SelectOrderOrAll(reqOptions[dhcp4.OptionParameterRequestList]))
}
log.Printf("DHCP Discover from %s (no offer due to no addresses available in pool)\n", mac.String())
// FIXME: Send to StatHat and/or increment a counter
// TODO: Send an email?
return nil
case dhcp4.Request:
// RFC 2131 4.3.2
// FIXME: send to StatHat and/or increment a counter
mac := packet.CHAddr()
// Check MAC blacklist
if !d.isMACPermitted(mac) {
log.Printf("DHCP Request from %s\n is not permitted", mac.String())
return nil
}
// Check IP presence
state, requestedIP := d.getRequestState(packet, reqOptions)
log.Printf("DHCP Request (%s) from %s...\n", state, mac.String())
if len(requestedIP) == 0 || requestedIP.IsUnspecified() { // no IP provided at all... why? FIXME
log.Printf("DHCP Request (%s) from %s (empty IP, so we're just ignoring this request)\n", state, mac.String())
return nil
}
// Check IPv4
if len(requestedIP) != net.IPv4len {
log.Printf("DHCP Request (%s) from %s wanting %s (IPv6 address requested, so we're just ignoring this request)\n", state, mac.String(), requestedIP.String())
return nil
}
// Check IP subnet
if !d.subnet.Contains(requestedIP) {
log.Printf("DHCP Request (%s) from %s wanting %s (we reject due to wrong subnet)\n", state, mac.String(), requestedIP.String())
return dhcp4.ReplyPacket(packet, dhcp4.NAK, d.ip.To4(), nil, 0, nil)
}
// Check Target Server
targetServerIP := packet.SIAddr()
if len(targetServerIP) > 0 && !targetServerIP.IsUnspecified() {
log.Printf("DHCP Request (%s) from %s wanting %s is in response to a DHCP offer from %s\n", state, mac.String(), requestedIP.String(), targetServerIP.String())
if d.ip.Equal(targetServerIP) {
return nil
}
}
// Process Request
log.Printf("DHCP Request (%s) from %s wanting %s...\n", state, mac.String(), requestedIP.String())
lease, found, err := d.db.GetMAC(mac, true)
if err != nil {
return nil
}
//.........这里部分代码省略.........
示例8: ServeDHCP
// ServeDHCP replies a dhcp request
func (h *Handler) ServeDHCP(p dhcp4.Packet, msgType dhcp4.MessageType, options dhcp4.Options) (d dhcp4.Packet) {
switch msgType {
case dhcp4.Discover, dhcp4.Request:
if server, ok := options[dhcp4.OptionServerIdentifier]; ok && !net.IP(server).Equal(h.serverIP) {
if msgType == dhcp4.Discover {
log.WithField("where", "dhcp.ServeDHCP").Debugf(
"identifying dhcp server in Discover?! (%v)", p)
}
return nil // this message is not ours
}
machineInterface := h.datasource.MachineInterface(p.CHAddr())
machine, err := machineInterface.Machine(true, nil)
if err != nil {
log.WithField("where", "dhcp.ServeDHCP").WithError(err).Warn(
"failed to get machine")
return nil
}
netConfStr, err := machineInterface.GetVariable(datasource.SpecialKeyNetworkConfiguration)
if err != nil {
log.WithField("where", "dhcp.ServeDHCP").WithError(err).Warn(
"failed to get network configuration")
return nil
}
netConf, err := datasource.UnmarshalNetworkConfiguration(netConfStr)
if err != nil {
log.WithField("where", "dhcp.ServeDHCP").WithError(err).Warn(
"failed to unmarshal network-configuration=%q", netConfStr)
return nil
}
instanceInfos, err := h.datasource.Instances()
if err != nil {
log.WithField("where", "dhcp.ServeDHCP").WithError(err).Warn(
"failed to get instances")
return nil
}
hostname := strings.Join(strings.Split(p.CHAddr().String(), ":"), "")
hostname += "." + h.datasource.ClusterName()
dhcpOptions := dhcp4.Options{
dhcp4.OptionSubnetMask: netConf.Netmask.To4(),
dhcp4.OptionDomainNameServer: dnsAddressesForDHCP(&instanceInfos),
dhcp4.OptionHostName: []byte(hostname),
}
if netConf.Router != nil {
dhcpOptions[dhcp4.OptionRouter] = netConf.Router.To4()
}
if len(netConf.ClasslessRouteOption) != 0 {
var res []byte
for _, part := range netConf.ClasslessRouteOption {
res = append(res, part.ToBytes()...)
}
dhcpOptions[dhcp4.OptionClasslessRouteFormat] = res
}
responseMsgType := dhcp4.Offer
if msgType == dhcp4.Request {
responseMsgType = dhcp4.ACK
requestedIP := net.IP(options[dhcp4.OptionRequestedIPAddress])
if requestedIP == nil {
requestedIP = net.IP(p.CIAddr())
}
if len(requestedIP) != 4 || requestedIP.Equal(net.IPv4zero) {
log.WithFields(log.Fields{
"where": "dhcp.ServeDHCP",
"object": p.CHAddr().String(),
"subject": msgType,
}).Debugf("bad request")
return nil
}
if !requestedIP.Equal(machine.IP) {
log.WithFields(log.Fields{
"where": "dhcp.ServeDHCP",
"object": p.CHAddr().String(),
"subject": msgType,
}).Debugf("requestedIP(%s) != assignedIp(%s)",
requestedIP.String(), machine.IP.String())
return nil
}
machineInterface.CheckIn()
}
guidVal, isPxe := options[97]
log.WithFields(log.Fields{
"where": "dhcp.ServeDHCP",
"action": "debug",
"object": p.CHAddr().String(),
"subject": msgType,
}).Infof("assignedIp=%s isPxe=%v", machine.IP.String(), isPxe)
//.........这里部分代码省略.........
示例9: ServeDHCP
func (h *DHCPHandler) ServeDHCP(p dhcp.Packet, msgType dhcp.MessageType, options dhcp.Options) (d dhcp.Packet) {
// First find the subnet to use. giaddr field to lookup subnet if not all zeros.
// If all zeros, use the interfaces Addrs to find a subnet, first wins.
var subnet *Subnet
subnet = nil
giaddr := p.GIAddr()
if !giaddr.Equal(net.IPv4zero) {
subnet = h.info.FindSubnet(giaddr)
} else {
log.Println("Received Broadcast/Local message on ", h.intf.Name)
addrs, err := h.intf.Addrs()
if err != nil {
log.Println("Can't find addresses for ", h.intf.Name, ": ", err)
}
for _, a := range addrs {
aip, _, _ := net.ParseCIDR(a.String())
// Only operate on v4 addresses
if aip.To4() == nil {
continue
}
subnet = h.info.FindSubnet(aip)
if subnet != nil {
break
}
}
if ignore_anonymus {
// Search all subnets for a binding. First wins
log.Println("Looking up bound subnet for ", p.CHAddr().String())
subnet = h.info.FindBoundIP(p.CHAddr())
}
if subnet == nil {
// We didn't find a subnet for the interface. Look for the assigned server IP
subnet = h.info.FindSubnet(h.ip)
}
}
if subnet == nil {
log.Println("Can not find subnet for packet, ignoring")
return
}
nic := p.CHAddr().String()
switch msgType {
case dhcp.Discover:
lease, binding := subnet.find_or_get_info(h.info, nic, p.CIAddr())
if lease == nil {
log.Println("Out of IPs for ", subnet.Name, ", ignoring")
return nil
}
// Ignore unknown MAC address
if ignore_anonymus && binding == nil {
log.Println("Ignoring request from unknown MAC address")
return dhcp.ReplyPacket(p, dhcp.NAK, h.ip, nil, 0, nil)
}
options, lease_time := subnet.build_options(lease, binding)
reply := dhcp.ReplyPacket(p, dhcp.Offer,
h.ip,
lease.Ip,
lease_time,
subnet.Options.SelectOrderOrAll(options[dhcp.OptionParameterRequestList]))
log.Println("Discover: Handing out: ", reply.YIAddr(), " to ", reply.CHAddr())
return reply
case dhcp.Request:
server, ok := options[dhcp.OptionServerIdentifier]
if ok && !net.IP(server).Equal(h.ip) {
return nil // Message not for this dhcp server
}
reqIP := net.IP(options[dhcp.OptionRequestedIPAddress])
if reqIP == nil {
reqIP = net.IP(p.CIAddr())
}
if len(reqIP) != 4 || reqIP.Equal(net.IPv4zero) {
return dhcp.ReplyPacket(p, dhcp.NAK, h.ip, nil, 0, nil)
}
lease, binding := subnet.find_info(h.info, nic)
// Ignore unknown MAC address
if ignore_anonymus && binding == nil {
log.Println("Ignoring request from unknown MAC address")
return dhcp.ReplyPacket(p, dhcp.NAK, h.ip, nil, 0, nil)
}
if lease == nil || !lease.Ip.Equal(reqIP) {
return dhcp.ReplyPacket(p, dhcp.NAK, h.ip, nil, 0, nil)
}
options, lease_time := subnet.build_options(lease, binding)
//.........这里部分代码省略.........