minor dhcp changes to better match seqs exchange

This commit is contained in:
soypat
2025-07-01 18:38:12 -03:00
parent 5cea9727f0
commit 234d3835a0
3 changed files with 32 additions and 6 deletions
+23 -4
View File
@@ -25,7 +25,8 @@ type Client struct {
currentXID uint32
state ClientState
offer [4]byte
svip [4]byte
svip [4]byte // OptServerIdentification.
siip [4]byte // SIAddr.
reqIP [4]byte
router [4]byte
subnet [4]byte
@@ -80,6 +81,18 @@ func (c *Client) setIP(b []byte, frameOffset int) {
const ecnmask = 0b1100_0000
ifrm.SetToS(ecnmask)
}
src := ifrm.SourceAddr()
for i := range src {
src[i] = 0
}
dst := ifrm.DestinationAddr()[:]
if c.svip == ([4]byte{}) {
for i := range dst {
dst[i] = 255
}
} else {
copy(dst, c.svip[:])
}
}
func (c *Client) Encapsulate(carrierFrame []byte, frameOffset int) (int, error) {
@@ -177,7 +190,7 @@ func (c *Client) Demux(carrierData []byte, frameOffset int) error {
// Lock in on this offer.
c.gateway = *frm.GIAddr()
c.offer = *frm.YIAddr()
c.svip = *frm.SIAddr()
c.siip = *frm.SIAddr()
}
case StateRequesting:
@@ -246,10 +259,16 @@ func (c *Client) setHeader(frm Frame) {
frm.SetXID(c.currentXID)
frm.SetHardware(1, 6, 0)
frm.SetSecs(1)
if c.state == StateRequesting || c.state == StateSelecting || c.state == StateBound || c.state == StateRenewing {
if c.state.HasIP() {
copy(frm.CIAddr()[:], c.offer[:])
}
copy(frm.SIAddr()[:], c.svip[:])
if c.state == StateInit {
siaddr := frm.SIAddr()[:]
for i := range siaddr {
siaddr[i] = 255
}
}
copy(frm.YIAddr()[:], c.offer[:])
copy(frm.CHAddrAs6()[:], c.clientMAC[:])
frm.SetMagicCookie(MagicCookie)
+5
View File
@@ -30,6 +30,11 @@ const (
StateRebooting // rebooting
)
// HasIP returns true if the state indicates the Client has an IP address assigned by server.
func (state ClientState) HasIP() bool {
return state == StateBound || state == StateRenewing || state == StateRebinding
}
func AppendOption(dst []byte, opt OptNum, data ...byte) []byte {
if len(data) > 255 {
panic("option data too long")
+4 -2
View File
@@ -57,9 +57,11 @@ func (frm Frame) SetHardware(Type, Len, Ops uint8) {
frm.buf[1], frm.buf[2], frm.buf[3] = Type, Len, Ops
}
// XID is the transaction ID. Is unique and constant for a DHCP request/response exchange of packets.
func (frm Frame) XID() uint32 { return binary.BigEndian.Uint32(frm.buf[4:8]) }
func (frm Frame) SetXID(xid uint32) { binary.BigEndian.PutUint32(frm.buf[4:8], xid) }
// Secs is seconds elapsed.
func (frm Frame) Secs() uint16 { return binary.BigEndian.Uint16(frm.buf[8:10]) }
func (frm Frame) SetSecs(secs uint16) { binary.BigEndian.PutUint16(frm.buf[8:10], secs) }
@@ -72,7 +74,7 @@ func (frm Frame) CIAddr() *[4]byte {
return (*[4]byte)(frm.buf[12:16])
}
// YIAddr is the IP address offered by the server to the client.
// YIAddr is the IP address offered by the server to the client. Your (client) IP Address.
func (frm Frame) YIAddr() *[4]byte {
return (*[4]byte)(frm.buf[16:20])
}
@@ -83,7 +85,7 @@ func (frm Frame) SIAddr() *[4]byte {
return (*[4]byte)(frm.buf[20:24])
}
// GIAddr is the gateway IP address.
// GIAddr is the gateway IP address. Is also known as the Relay Agent IP Address.
func (frm Frame) GIAddr() *[4]byte {
return (*[4]byte)(frm.buf[24:28])
}