f-46: dhcpd: build dhcp replies over insomniacslk/dhcp #46

internal/dhcpd décide quelles options partent vers quelle MAC, sans I/O ni
état. L'encodage RFC 3442 de l'option 121 est délégué à la bibliothèque, qui le
teste elle-même.

L'option 3 est omise plutôt qu'envoyée vide : la dhcp-option=3 nue n'existait
que pour empêcher dnsmasq d'annoncer sa propre adresse. La route par défaut est
conditionnée au subnet (DefaultGateway) et à l'interface (Host.DefaultRoute),
ce qui remplace le mécanisme de tags.

24 tests plus un fuzz sur BuildReply. Les assertions d'encodage sont validées
par mutation.

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-08-31 15:51:36 +02:00
commit 5918feed83
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
6 changed files with 570 additions and 22 deletions

View file

@ -0,0 +1,59 @@
package dhcpd
import (
"net"
"testing"
"github.com/insomniacslk/dhcp/dhcpv4"
)
func FuzzBuildReply(f *testing.F) {
mac, err := net.ParseMAC("00:22:33:00:00:0a")
if err != nil {
f.Fatalf("ParseMAC: %v", err)
}
for _, kind := range []dhcpv4.MessageType{
dhcpv4.MessageTypeDiscover,
dhcpv4.MessageTypeRequest,
dhcpv4.MessageTypeRelease,
dhcpv4.MessageTypeDecline,
} {
req, err := dhcpv4.New(dhcpv4.WithMessageType(kind), dhcpv4.WithHwAddr(mac))
if err != nil {
f.Fatalf("New request: %v", err)
}
f.Add(req.ToBytes())
}
_, network, err := net.ParseCIDR("10.0.5.0/24")
if err != nil {
f.Fatalf("ParseCIDR: %v", err)
}
_, vpcRoute, err := net.ParseCIDR("10.0.0.0/16")
if err != nil {
f.Fatalf("ParseCIDR: %v", err)
}
c := SubnetConfig{
Network: network,
InterfaceIP: net.ParseIP("10.0.5.1"),
VPCRoute: vpcRoute,
DefaultGateway: net.ParseIP("10.0.5.254"),
}
h := Host{MAC: mac, IP: net.ParseIP("10.0.5.10"), VM: "vm-fuzz", DefaultRoute: true}
f.Fuzz(func(t *testing.T, raw []byte) {
req, err := dhcpv4.FromBytes(raw)
if err != nil {
return
}
reply, err := BuildReply(c, h, req)
if err != nil {
return
}
if reply == nil {
t.Fatal("nil reply without an error")
}
reply.ToBytes()
})
}