mirror of
https://github.com/soypat/lneto.git
synced 2026-09-10 16:49:37 +00:00
refine DHCP value acquisition
This commit is contained in:
+59
-35
@@ -26,19 +26,41 @@ type Client struct {
|
|||||||
tIPLease uint32
|
tIPLease uint32
|
||||||
currentXID uint32
|
currentXID uint32
|
||||||
state ClientState
|
state ClientState
|
||||||
offer [4]byte
|
offer addr4
|
||||||
svip [4]byte // OptServerIdentification.
|
svip addr4 // OptServerIdentification.
|
||||||
siip [4]byte // SIAddr.
|
siip addr4 // SIAddr.
|
||||||
reqIP [4]byte
|
reqIP addr4
|
||||||
router [4]byte
|
router addr4
|
||||||
subnet [4]byte
|
subnet addr4
|
||||||
broadcast [4]byte
|
broadcast addr4
|
||||||
gateway [4]byte
|
gateway addr4
|
||||||
clientMAC [6]byte
|
clientMAC [6]byte
|
||||||
|
|
||||||
auxbuf [64]byte
|
auxbuf [64]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type addr4 struct {
|
||||||
|
addr [4]byte
|
||||||
|
valid bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *addr4) unpack() ([4]byte, bool) {
|
||||||
|
return a.addr, a.valid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *addr4) setmaybe(data []byte) {
|
||||||
|
if len(data) == 4 {
|
||||||
|
a.set4([4]byte(data[:]))
|
||||||
|
} else {
|
||||||
|
a.valid = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *addr4) set4(addr [4]byte) {
|
||||||
|
a.valid = true
|
||||||
|
a.addr = addr
|
||||||
|
}
|
||||||
|
|
||||||
type RequestConfig struct {
|
type RequestConfig struct {
|
||||||
RequestedAddr [4]byte
|
RequestedAddr [4]byte
|
||||||
ClientHardwareAddr [6]byte
|
ClientHardwareAddr [6]byte
|
||||||
@@ -59,7 +81,7 @@ func (c *Client) BeginRequest(xid uint32, cfg RequestConfig) error {
|
|||||||
c.state = StateInit
|
c.state = StateInit
|
||||||
c.currentXID = xid
|
c.currentXID = xid
|
||||||
c.reqHostname = cfg.Hostname
|
c.reqHostname = cfg.Hostname
|
||||||
c.reqIP = cfg.RequestedAddr
|
c.reqIP = addr4{addr: cfg.RequestedAddr, valid: true}
|
||||||
c.clientMAC = cfg.ClientHardwareAddr
|
c.clientMAC = cfg.ClientHardwareAddr
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -91,7 +113,7 @@ func (c *Client) setIP(b []byte, frameOffset int) {
|
|||||||
func (c *Client) Encapsulate(carrierFrame []byte, frameOffset int) (int, error) {
|
func (c *Client) Encapsulate(carrierFrame []byte, frameOffset int) (int, error) {
|
||||||
if c.isClosed() {
|
if c.isClosed() {
|
||||||
return 0, net.ErrClosed
|
return 0, net.ErrClosed
|
||||||
} else if c.state == StateSelecting && c.offer == [4]byte{} {
|
} else if c.state == StateSelecting && !c.offer.valid {
|
||||||
return 0, nil // No offer received yet.
|
return 0, nil // No offer received yet.
|
||||||
} else if c.state == StateBound {
|
} else if c.state == StateBound {
|
||||||
return 0, nil // Done!
|
return 0, nil // Done!
|
||||||
@@ -123,22 +145,22 @@ func (c *Client) Encapsulate(carrierFrame []byte, frameOffset int) (int, error)
|
|||||||
}
|
}
|
||||||
n, _ = EncodeOption16(opts[numOpts:], OptMaximumMessageSize, uint16(maxlen))
|
n, _ = EncodeOption16(opts[numOpts:], OptMaximumMessageSize, uint16(maxlen))
|
||||||
numOpts += n
|
numOpts += n
|
||||||
if c.reqIP != [4]byte{} {
|
if !c.reqIP.valid {
|
||||||
n, _ = EncodeOption(opts[numOpts:], OptRequestedIPaddress, c.reqIP[:]...)
|
n, _ = EncodeOption(opts[numOpts:], OptRequestedIPaddress, c.reqIP.addr[:]...)
|
||||||
numOpts += n
|
numOpts += n
|
||||||
}
|
}
|
||||||
nextState = StateSelecting
|
nextState = StateSelecting
|
||||||
|
|
||||||
case StateSelecting:
|
case StateSelecting:
|
||||||
if c.offer == ([4]byte{}) {
|
if !c.offer.valid {
|
||||||
return 0, nil // Offer not yet received.
|
return 0, nil // Offer not yet received.
|
||||||
}
|
}
|
||||||
// Send out request, we know we've received an offer by now.
|
// Send out request, we know we've received an offer by now.
|
||||||
n, _ := EncodeOption(opts[numOpts:], OptMessageType, byte(MsgRequest))
|
n, _ := EncodeOption(opts[numOpts:], OptMessageType, byte(MsgRequest))
|
||||||
numOpts += n
|
numOpts += n
|
||||||
n, _ = EncodeOption(opts[numOpts:], OptRequestedIPaddress, c.offer[:]...)
|
n, _ = EncodeOption(opts[numOpts:], OptRequestedIPaddress, c.offer.addr[:]...)
|
||||||
numOpts += n
|
numOpts += n
|
||||||
n, _ = EncodeOption(opts[numOpts:], OptServerIdentification, c.svip[:]...)
|
n, _ = EncodeOption(opts[numOpts:], OptServerIdentification, c.svip.addr[:]...)
|
||||||
numOpts += n
|
numOpts += n
|
||||||
nextState = StateRequesting
|
nextState = StateRequesting
|
||||||
|
|
||||||
@@ -193,11 +215,11 @@ func (c *Client) Demux(carrierData []byte, frameOffset int) error {
|
|||||||
|
|
||||||
switch c.state {
|
switch c.state {
|
||||||
case StateSelecting:
|
case StateSelecting:
|
||||||
if msgType == MsgOffer && c.offer == [4]byte{} {
|
if msgType == MsgOffer && !c.offer.valid {
|
||||||
// Lock in on this offer.
|
// Lock in on this offer.
|
||||||
c.gateway = *frm.GIAddr()
|
c.gateway.set4(*frm.GIAddr())
|
||||||
c.offer = *frm.YIAddr()
|
c.offer.set4(*frm.YIAddr())
|
||||||
c.siip = *frm.SIAddr()
|
c.siip.set4(*frm.SIAddr())
|
||||||
}
|
}
|
||||||
|
|
||||||
case StateRequesting:
|
case StateRequesting:
|
||||||
@@ -237,13 +259,13 @@ func (c *Client) setOptions(frm Frame) error {
|
|||||||
case OptRebindingTimeValue:
|
case OptRebindingTimeValue:
|
||||||
c.tRebind = maybeU32(data)
|
c.tRebind = maybeU32(data)
|
||||||
case OptServerIdentification:
|
case OptServerIdentification:
|
||||||
c.svip = maybe4byte(data)
|
c.svip.setmaybe(data)
|
||||||
case OptRouter:
|
case OptRouter:
|
||||||
c.router = maybe4byte(data)
|
c.router.setmaybe(data)
|
||||||
case OptBroadcastAddress:
|
case OptBroadcastAddress:
|
||||||
c.broadcast = maybe4byte(data)
|
c.broadcast.setmaybe(data)
|
||||||
case OptSubnetMask:
|
case OptSubnetMask:
|
||||||
c.subnet = maybe4byte(data)
|
c.subnet.setmaybe(data)
|
||||||
|
|
||||||
case OptHostName:
|
case OptHostName:
|
||||||
if len(data) < maxHostSize {
|
if len(data) < maxHostSize {
|
||||||
@@ -271,7 +293,7 @@ func (c *Client) setHeader(frm Frame) {
|
|||||||
frm.SetHardware(1, 6, 0)
|
frm.SetHardware(1, 6, 0)
|
||||||
frm.SetSecs(1)
|
frm.SetSecs(1)
|
||||||
if c.state.HasIP() {
|
if c.state.HasIP() {
|
||||||
*frm.CIAddr() = c.offer
|
*frm.CIAddr() = c.offer.addr
|
||||||
}
|
}
|
||||||
if c.state == StateInit {
|
if c.state == StateInit {
|
||||||
siaddr := frm.SIAddr()[:]
|
siaddr := frm.SIAddr()[:]
|
||||||
@@ -279,13 +301,13 @@ func (c *Client) setHeader(frm Frame) {
|
|||||||
siaddr[i] = 255
|
siaddr[i] = 255
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if c.siip == [4]byte{} {
|
if !c.siip.valid {
|
||||||
*frm.SIAddr() = c.svip
|
*frm.SIAddr() = c.svip.addr
|
||||||
} else {
|
} else {
|
||||||
*frm.SIAddr() = c.siip
|
*frm.SIAddr() = c.siip.addr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*frm.YIAddr() = c.offer
|
*frm.YIAddr() = c.offer.addr
|
||||||
copy(frm.CHAddrAs6()[:], c.clientMAC[:])
|
copy(frm.CHAddrAs6()[:], c.clientMAC[:])
|
||||||
frm.SetMagicCookie(MagicCookie)
|
frm.SetMagicCookie(MagicCookie)
|
||||||
}
|
}
|
||||||
@@ -302,11 +324,12 @@ func (c *Client) reset(xid uint32) {
|
|||||||
|
|
||||||
func (d *Client) State() ClientState { return d.state }
|
func (d *Client) State() ClientState { return d.state }
|
||||||
|
|
||||||
func (d *Client) BroadcastAddr() [4]byte { return d.broadcast }
|
func (d *Client) BroadcastAddr() ([4]byte, bool) { return d.broadcast.unpack() }
|
||||||
func (d *Client) AssignedAddr() [4]byte { return d.offer }
|
func (d *Client) AssignedAddr() ([4]byte, bool) { return d.offer.unpack() }
|
||||||
func (d *Client) ServerAddr() [4]byte { return d.svip }
|
func (d *Client) ServerAddr() ([4]byte, bool) { return d.svip.unpack() }
|
||||||
func (d *Client) RouterAddr() [4]byte { return d.router }
|
func (d *Client) RouterAddr() ([4]byte, bool) { return d.router.unpack() }
|
||||||
func (d *Client) GatewayAddr() [4]byte { return d.gateway }
|
func (d *Client) GatewayAddr() ([4]byte, bool) { return d.gateway.unpack() }
|
||||||
|
func (d *Client) Subnet() ([4]byte, bool) { return d.subnet.unpack() }
|
||||||
func (d *Client) RebindingSeconds() uint32 { return d.tRebind }
|
func (d *Client) RebindingSeconds() uint32 { return d.tRebind }
|
||||||
func (d *Client) RenewalSeconds() uint32 { return d.tRenew }
|
func (d *Client) RenewalSeconds() uint32 { return d.tRenew }
|
||||||
func (d *Client) IPLeaseSeconds() uint32 { return d.tIPLease }
|
func (d *Client) IPLeaseSeconds() uint32 { return d.tIPLease }
|
||||||
@@ -318,11 +341,12 @@ func (d *Client) DNSServerFirst() netip.Addr {
|
|||||||
}
|
}
|
||||||
return d.dns[0]
|
return d.dns[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Client) CIDRBits() uint8 {
|
func (d *Client) CIDRBits() uint8 {
|
||||||
if d.subnet == [4]byte{} {
|
if !d.subnet.valid {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
v := binary.BigEndian.Uint32(d.subnet[:])
|
v := binary.BigEndian.Uint32(d.subnet.addr[:])
|
||||||
return 32 - uint8(bits.TrailingZeros32(v))
|
return 32 - uint8(bits.TrailingZeros32(v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-3
@@ -121,18 +121,29 @@ func run() (err error) {
|
|||||||
dhcpIsDone := stack.dhcp.State() == dhcpv4.StateBound
|
dhcpIsDone := stack.dhcp.State() == dhcpv4.StateBound
|
||||||
if dhcpIsDone {
|
if dhcpIsDone {
|
||||||
state = stateInitARP
|
state = stateInitARP
|
||||||
err = stack.ip.SetAddr(netip.AddrFrom4(stack.dhcp.AssignedAddr()))
|
assigned4, ok := stack.dhcp.AssignedAddr()
|
||||||
|
if !ok {
|
||||||
|
return errors.New("DHCP client address not assigned")
|
||||||
|
}
|
||||||
|
err = stack.ip.SetAddr(netip.AddrFrom4(assigned4))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = stack.StartResolveHardwareAddress6(netip.AddrFrom4(stack.dhcp.RouterAddr()))
|
routeraddr, ok := stack.dhcp.RouterAddr()
|
||||||
|
if !ok {
|
||||||
|
return errors.New("DHCP router address not assigned")
|
||||||
|
}
|
||||||
|
err = stack.StartResolveHardwareAddress6(netip.AddrFrom4(routeraddr))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case stateInitARP:
|
case stateInitARP:
|
||||||
router := stack.dhcp.RouterAddr()
|
router, ok := stack.dhcp.RouterAddr()
|
||||||
|
if !ok {
|
||||||
|
return errors.New("DHCP router address not assigned")
|
||||||
|
}
|
||||||
hw, err := stack.ResultResolveHardwareAddress6(netip.AddrFrom4(router))
|
hw, err := stack.ResultResolveHardwareAddress6(netip.AddrFrom4(router))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
stack.link.SetGateway6(hw)
|
stack.link.SetGateway6(hw)
|
||||||
|
|||||||
Reference in New Issue
Block a user