diff --git a/dhcpv4/dhcpv4.go b/dhcpv4/dhcpv4.go index a8754312..36c726f6 100644 --- a/dhcpv4/dhcpv4.go +++ b/dhcpv4/dhcpv4.go @@ -602,6 +602,13 @@ func (d *DHCPv4) NTPServers() []net.IP { return GetIPs(OptionNTPServers, d.Options) } +// NetBIOSNameServers parses the DHCPv4 NetBIOS Name Servers option if present. +// +// The NetBIOS over TCP/IP Name Server option is described by RFC 2132, Section 8.5. +func (d *DHCPv4) NetBIOSNameServers() []net.IP { + return GetIPs(OptionNetBIOSOverTCPIPNameServer, d.Options) +} + // DNS parses the DHCPv4 Domain Name Server option if present. // // The DNS server option is described by RFC 2132, Section 3.8. diff --git a/dhcpv4/option_ips.go b/dhcpv4/option_ips.go index e0ee4cd0..cbb81a22 100644 --- a/dhcpv4/option_ips.go +++ b/dhcpv4/option_ips.go @@ -87,6 +87,16 @@ func OptNTPServers(ntpServers ...net.IP) Option { } } +// OptNetBIOSNameServers returns a new DHCPv4 NetBIOS Name Server option. +// +// The NetBIOS over TCP/IP Name Server option is described by RFC 2132, Section 8.5. +func OptNetBIOSNameServers(netBIOSNameServers ...net.IP) Option { + return Option{ + Code: OptionNetBIOSOverTCPIPNameServer, + Value: IPs(netBIOSNameServers), + } +} + // OptDNS returns a new DHCPv4 Domain Name Server option. // // The DNS server option is described by RFC 2132, Section 3.8. diff --git a/dhcpv4/option_ips_test.go b/dhcpv4/option_ips_test.go index 05b29393..3fb91a9a 100644 --- a/dhcpv4/option_ips_test.go +++ b/dhcpv4/option_ips_test.go @@ -69,6 +69,25 @@ func TestGetNTPServers(t *testing.T) { require.Nil(t, m.NTPServers()) } +func TestOptNetBIOSNameServers(t *testing.T) { + o := OptNetBIOSNameServers(net.IPv4(192, 168, 0, 1), net.IPv4(192, 168, 0, 10)) + require.Equal(t, OptionNetBIOSOverTCPIPNameServer, o.Code) + require.Equal(t, []byte{192, 168, 0, 1, 192, 168, 0, 10}, o.Value.ToBytes()) + require.Equal(t, "NetBIOS over TCP/IP Name Server: 192.168.0.1, 192.168.0.10", o.String()) +} + +func TestGetNetBIOSNameServers(t *testing.T) { + ips := []net.IP{ + net.IP{192, 168, 0, 1}, + net.IP{192, 168, 0, 10}, + } + m, _ := New(WithOption(OptNetBIOSNameServers(ips...))) + require.Equal(t, ips, m.NetBIOSNameServers()) + + m, _ = New() + require.Nil(t, m.NetBIOSNameServers()) +} + func TestOptRouter(t *testing.T) { o := OptRouter(net.IPv4(192, 168, 0, 1), net.IPv4(192, 168, 0, 10)) require.Equal(t, OptionRouter, o.Code) diff --git a/dhcpv4/server4/conn_windows.go b/dhcpv4/server4/conn_windows.go index cbe9d71b..ce4f8688 100644 --- a/dhcpv4/server4/conn_windows.go +++ b/dhcpv4/server4/conn_windows.go @@ -1,11 +1,21 @@ +//go:build windows + package server4 import ( - "errors" + "fmt" "net" ) -// NewIPv4UDPConn fails on Windows. Use WithConn() to pass the connection. +// NewIPv4UDPConn returns an UDPv4 connection bound to the IP and port provider func NewIPv4UDPConn(iface string, addr *net.UDPAddr) (*net.UDPConn, error) { - return nil, errors.New("not implemented on Windows") + connection, err := net.ListenPacket("udp4", addr.String()) + if err != nil { + return nil, fmt.Errorf("We cannot listen on %s and port %d: %v", addr.IP, addr.Port, err) + } + udpConn, ok := connection.(*net.UDPConn) + if !ok { + return nil, fmt.Errorf("The connection is not of the proper type") + } + return udpConn, nil } diff --git a/go.mod b/go.mod index f93fee90..45914480 100644 --- a/go.mod +++ b/go.mod @@ -10,8 +10,8 @@ require ( github.com/mdlayher/packet v1.1.2 github.com/stretchr/testify v1.6.1 github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 - golang.org/x/net v0.23.0 - golang.org/x/sys v0.18.0 + golang.org/x/net v0.33.0 + golang.org/x/sys v0.28.0 ) require ( diff --git a/go.sum b/go.sum index 6b08a535..3e4399f3 100644 --- a/go.sum +++ b/go.sum @@ -27,13 +27,13 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA= github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264= golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 h1:Jvc7gsqn21cJHCmAWx0LiimpP18LZmUxkT5Mp7EZ1mI= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=