136 lines
3.8 KiB
Go
136 lines
3.8 KiB
Go
// Copyright 2021 CNI authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package main
|
|
|
|
import (
|
|
"github.com/d2g/dhcp4"
|
|
"github.com/d2g/dhcp4client"
|
|
)
|
|
|
|
const (
|
|
MaxDHCPLen = 576
|
|
)
|
|
|
|
// Send the Discovery Packet to the Broadcast Channel
|
|
func DhcpSendDiscoverPacket(c *dhcp4client.Client, options dhcp4.Options) (dhcp4.Packet, error) {
|
|
discoveryPacket := c.DiscoverPacket()
|
|
|
|
for opt, data := range options {
|
|
discoveryPacket.AddOption(opt, data)
|
|
}
|
|
|
|
discoveryPacket.PadToMinSize()
|
|
return discoveryPacket, c.SendPacket(discoveryPacket)
|
|
}
|
|
|
|
// Send Request Based On the offer Received.
|
|
func DhcpSendRequest(c *dhcp4client.Client, options dhcp4.Options, offerPacket *dhcp4.Packet) (dhcp4.Packet, error) {
|
|
requestPacket := c.RequestPacket(offerPacket)
|
|
|
|
for opt, data := range options {
|
|
requestPacket.AddOption(opt, data)
|
|
}
|
|
|
|
requestPacket.PadToMinSize()
|
|
|
|
return requestPacket, c.SendPacket(requestPacket)
|
|
}
|
|
|
|
// Send Decline to the received acknowledgement.
|
|
func DhcpSendDecline(c *dhcp4client.Client, acknowledgementPacket *dhcp4.Packet, options dhcp4.Options) (dhcp4.Packet, error) {
|
|
declinePacket := c.DeclinePacket(acknowledgementPacket)
|
|
|
|
for opt, data := range options {
|
|
declinePacket.AddOption(opt, data)
|
|
}
|
|
|
|
declinePacket.PadToMinSize()
|
|
|
|
return declinePacket, c.SendPacket(declinePacket)
|
|
}
|
|
|
|
// Lets do a Full DHCP Request.
|
|
func DhcpRequest(c *dhcp4client.Client, options dhcp4.Options) (bool, dhcp4.Packet, error) {
|
|
discoveryPacket, err := DhcpSendDiscoverPacket(c, options)
|
|
if err != nil {
|
|
return false, discoveryPacket, err
|
|
}
|
|
|
|
offerPacket, err := c.GetOffer(&discoveryPacket)
|
|
if err != nil {
|
|
return false, offerPacket, err
|
|
}
|
|
|
|
requestPacket, err := DhcpSendRequest(c, options, &offerPacket)
|
|
if err != nil {
|
|
return false, requestPacket, err
|
|
}
|
|
|
|
acknowledgement, err := c.GetAcknowledgement(&requestPacket)
|
|
if err != nil {
|
|
return false, acknowledgement, err
|
|
}
|
|
|
|
acknowledgementOptions := acknowledgement.ParseOptions()
|
|
if dhcp4.MessageType(acknowledgementOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK {
|
|
return false, acknowledgement, nil
|
|
}
|
|
|
|
return true, acknowledgement, nil
|
|
}
|
|
|
|
// Renew a lease backed on the Acknowledgement Packet.
|
|
// Returns Successful, The AcknoledgementPacket, Any Errors
|
|
func DhcpRenew(c *dhcp4client.Client, acknowledgement dhcp4.Packet, options dhcp4.Options) (bool, dhcp4.Packet, error) {
|
|
renewRequest := c.RenewalRequestPacket(&acknowledgement)
|
|
|
|
for opt, data := range options {
|
|
renewRequest.AddOption(opt, data)
|
|
}
|
|
|
|
renewRequest.PadToMinSize()
|
|
|
|
err := c.SendPacket(renewRequest)
|
|
if err != nil {
|
|
return false, renewRequest, err
|
|
}
|
|
|
|
newAcknowledgement, err := c.GetAcknowledgement(&renewRequest)
|
|
if err != nil {
|
|
return false, newAcknowledgement, err
|
|
}
|
|
|
|
newAcknowledgementOptions := newAcknowledgement.ParseOptions()
|
|
if dhcp4.MessageType(newAcknowledgementOptions[dhcp4.OptionDHCPMessageType][0]) != dhcp4.ACK {
|
|
return false, newAcknowledgement, nil
|
|
}
|
|
|
|
return true, newAcknowledgement, nil
|
|
}
|
|
|
|
// Release a lease backed on the Acknowledgement Packet.
|
|
// Returns Any Errors
|
|
func DhcpRelease(c *dhcp4client.Client, acknowledgement dhcp4.Packet, options dhcp4.Options) error {
|
|
release := c.ReleasePacket(&acknowledgement)
|
|
|
|
for opt, data := range options {
|
|
release.AddOption(opt, data)
|
|
}
|
|
|
|
release.PadToMinSize()
|
|
|
|
return c.SendPacket(release)
|
|
}
|