mirror of
https://github.com/soypat/lneto.git
synced 2026-08-14 20:03:45 +00:00
157 lines
3.7 KiB
Go
157 lines
3.7 KiB
Go
package dhcpv4
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestClientServer(t *testing.T) {
|
|
svAddr := [4]byte{192, 168, 1, 1}
|
|
clAddr := svAddr
|
|
clAddr[3]++
|
|
var sv Server
|
|
var cl Client
|
|
err := cl.BeginRequest(123, RequestConfig{
|
|
RequestedAddr: clAddr,
|
|
ClientHardwareAddr: [6]byte{1, 2, 3, 4, 5, 6},
|
|
Hostname: "lneto",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
assertClState := func(state ClientState) {
|
|
t.Helper()
|
|
if state != cl.State() {
|
|
t.Errorf("want client state %s, got %s", state.String(), cl.State().String())
|
|
}
|
|
}
|
|
sv.Reset(svAddr, DefaultServerPort)
|
|
// CLIENT DISCOVER.
|
|
assertClState(StateInit)
|
|
var buf [1024]byte
|
|
n, err := cl.Encapsulate(buf[:], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if n == 0 {
|
|
t.Fatal("no client discover")
|
|
}
|
|
assertClState(StateSelecting)
|
|
err = sv.Demux(buf[:n], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// SERVER REPLY OFFER
|
|
n, err = sv.Encapsulate(buf[:], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if n == 0 {
|
|
t.Fatal("no server offer")
|
|
}
|
|
err = cl.Demux(buf[:n], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
assertClState(StateSelecting)
|
|
|
|
// CLIENT SEND OUT REQUEST.
|
|
n, err = cl.Encapsulate(buf[:], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if n == 0 {
|
|
t.Fatal("no client request")
|
|
}
|
|
assertClState(StateRequesting)
|
|
err = sv.Demux(buf[:n], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// SERVER REPLIES WITH ACK.
|
|
n, err = sv.Encapsulate(buf[:], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if n == 0 {
|
|
t.Fatal("no server reply")
|
|
}
|
|
err = cl.Demux(buf[:n], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
assertClState(StateBound)
|
|
}
|
|
|
|
func TestExample(t *testing.T) {
|
|
const (
|
|
xid = 1
|
|
offerLease = 9001
|
|
)
|
|
var cl Client
|
|
clientHwaddr := [6]byte{0, 0, 0, 0, 0, 1}
|
|
clientReqAddr := [4]byte{192, 168, 1, 2}
|
|
clientHostname := "client"
|
|
serverIP := [4]byte{192, 168, 1, 1}
|
|
subnetMask := [4]byte{255, 255, 255, 0}
|
|
routerAddr := [4]byte{192, 168, 1, 0}
|
|
dnsAddr := [4]byte{192, 168, 1, 255}
|
|
cl.BeginRequest(xid, RequestConfig{
|
|
RequestedAddr: clientReqAddr,
|
|
ClientHardwareAddr: clientHwaddr,
|
|
Hostname: clientHostname,
|
|
})
|
|
buf := make([]byte, 2048)
|
|
buf2 := make([]byte, len(buf))
|
|
n, err := cl.Encapsulate(buf, 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if n <= 0 {
|
|
t.Fatal("no data sent out by client after starting request")
|
|
}
|
|
n, err = cl.Encapsulate(buf2, 0)
|
|
if err != nil {
|
|
t.Error("client encaps double tap after discover:", err)
|
|
}
|
|
// Fabricate server OFFER response.
|
|
dfrm, _ := NewFrame(buf)
|
|
dfrm.ClearHeader()
|
|
dfrm.SetOp(OpReply)
|
|
dfrm.SetHardware(1, 6, 0)
|
|
dfrm.SetFlags(0)
|
|
dfrm.SetXID(xid)
|
|
dfrm.SetSecs(1)
|
|
*dfrm.YIAddr() = clientReqAddr
|
|
copy(dfrm.CHAddr()[:], clientHwaddr[:])
|
|
dfrm.SetMagicCookie(MagicCookie)
|
|
ntot := 0
|
|
nopt, _ := EncodeOption(buf[OptionsOffset+ntot:], OptMessageType, byte(MsgOffer))
|
|
ntot += nopt
|
|
nopt, _ = EncodeOption(buf[OptionsOffset+ntot:], OptServerIdentification, serverIP[:]...)
|
|
ntot += nopt
|
|
nopt, _ = EncodeOption32(buf[OptionsOffset+ntot:], OptServerIdentification, offerLease)
|
|
ntot += nopt
|
|
nopt, _ = EncodeOption(buf[OptionsOffset+ntot:], OptSubnetMask, subnetMask[:]...)
|
|
ntot += nopt
|
|
nopt, _ = EncodeOption(buf[OptionsOffset+ntot:], OptRouter, routerAddr[:]...)
|
|
ntot += nopt
|
|
nopt, _ = EncodeOption(buf[OptionsOffset+ntot:], OptDNSServers, dnsAddr[:]...)
|
|
ntot += nopt
|
|
nopt, _ = EncodeOption(buf[OptionsOffset+ntot:], OptEnd, dnsAddr[:]...)
|
|
ntot += nopt
|
|
|
|
err = cl.Demux(buf[:OptionsOffset+ntot], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
n, err = cl.Encapsulate(buf[:], 0)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
} else if n <= 0 {
|
|
t.Fatal("no data written from client in response to offer")
|
|
}
|
|
n, err = cl.Encapsulate(buf[:], 0)
|
|
if err != nil {
|
|
t.Error("encapsulate double tap after request:", err)
|
|
} else if n > 0 {
|
|
t.Error("encapsulate double tap got data!", n)
|
|
}
|
|
}
|