summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--dhcpv4/nclient4/client_test.go2
-rw-r--r--dhcpv4/nclient4/conn_linux.go38
-rw-r--r--dhcpv4/server4/conn.go45
-rw-r--r--dhcpv4/server4/server.go4
-rw-r--r--dhcpv4/server4/server_test.go4
5 files changed, 50 insertions, 43 deletions
diff --git a/dhcpv4/nclient4/client_test.go b/dhcpv4/nclient4/client_test.go
index c299697..df851ab 100644
--- a/dhcpv4/nclient4/client_test.go
+++ b/dhcpv4/nclient4/client_test.go
@@ -61,7 +61,7 @@ func serveAndClient(ctx context.Context, responses [][]*dhcpv4.DHCPv4, opts ...C
}
h := &handler{responses: responses}
- s, err := server4.NewServer(nil, h.handle, server4.WithConn(serverConn))
+ s, err := server4.NewServer("", nil, h.handle, server4.WithConn(serverConn))
if err != nil {
panic(err)
}
diff --git a/dhcpv4/nclient4/conn_linux.go b/dhcpv4/nclient4/conn_linux.go
index af6485f..064e6ca 100644
--- a/dhcpv4/nclient4/conn_linux.go
+++ b/dhcpv4/nclient4/conn_linux.go
@@ -10,13 +10,10 @@ import (
"fmt"
"io"
"net"
- "os"
- "github.com/insomniacslk/dhcp/dhcpv4"
"github.com/mdlayher/ethernet"
"github.com/mdlayher/raw"
"github.com/u-root/u-root/pkg/uio"
- "golang.org/x/sys/unix"
)
var (
@@ -26,41 +23,6 @@ var (
BroadcastMac = net.HardwareAddr([]byte{255, 255, 255, 255, 255, 255})
)
-// NewIPv4UDPConn returns a UDP connection bound to both the interface and port
-// given based on a IPv4 DGRAM socket. The UDP connection allows broadcasting.
-//
-// The interface must already be configured.
-func NewIPv4UDPConn(iface string, port int) (net.PacketConn, error) {
- fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_UDP)
- if err != nil {
- return nil, fmt.Errorf("cannot get a UDP socket: %v", err)
- }
- f := os.NewFile(uintptr(fd), "")
- // net.FilePacketConn dups the FD, so we have to close this in any case.
- defer f.Close()
-
- // Allow broadcasting.
- if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_BROADCAST, 1); err != nil {
- return nil, fmt.Errorf("cannot set broadcasting on socket: %v", err)
- }
- // Allow reusing the addr to aid debugging.
- if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
- return nil, fmt.Errorf("cannot set reuseaddr on socket: %v", err)
- }
- if len(iface) != 0 {
- // Bind directly to the interface.
- if err := dhcpv4.BindToInterface(fd, iface); err != nil {
- return nil, fmt.Errorf("cannot bind to interface %s: %v", iface, err)
- }
- }
- // Bind to the port.
- if err := unix.Bind(fd, &unix.SockaddrInet4{Port: port}); err != nil {
- return nil, fmt.Errorf("cannot bind to port %d: %v", port, err)
- }
-
- return net.FilePacketConn(f)
-}
-
// NewRawUDPConn returns a UDP connection bound to the interface and port
// given based on a raw packet socket. All packets are broadcasted.
//
diff --git a/dhcpv4/server4/conn.go b/dhcpv4/server4/conn.go
new file mode 100644
index 0000000..84d6aa3
--- /dev/null
+++ b/dhcpv4/server4/conn.go
@@ -0,0 +1,45 @@
+package server4
+
+import (
+ "fmt"
+ "net"
+ "os"
+
+ "github.com/insomniacslk/dhcp/dhcpv4"
+ "golang.org/x/sys/unix"
+)
+
+// NewIPv4UDPConn returns a UDP connection bound to both the interface and port
+// given based on a IPv4 DGRAM socket. The UDP connection allows broadcasting.
+//
+// The interface must already be configured.
+func NewIPv4UDPConn(iface string, port int) (net.PacketConn, error) {
+ fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_UDP)
+ if err != nil {
+ return nil, fmt.Errorf("cannot get a UDP socket: %v", err)
+ }
+ f := os.NewFile(uintptr(fd), "")
+ // net.FilePacketConn dups the FD, so we have to close this in any case.
+ defer f.Close()
+
+ // Allow broadcasting.
+ if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_BROADCAST, 1); err != nil {
+ return nil, fmt.Errorf("cannot set broadcasting on socket: %v", err)
+ }
+ // Allow reusing the addr to aid debugging.
+ if err := unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
+ return nil, fmt.Errorf("cannot set reuseaddr on socket: %v", err)
+ }
+ if len(iface) != 0 {
+ // Bind directly to the interface.
+ if err := dhcpv4.BindToInterface(fd, iface); err != nil {
+ return nil, fmt.Errorf("cannot bind to interface %s: %v", iface, err)
+ }
+ }
+ // Bind to the port.
+ if err := unix.Bind(fd, &unix.SockaddrInet4{Port: port}); err != nil {
+ return nil, fmt.Errorf("cannot bind to port %d: %v", port, err)
+ }
+
+ return net.FilePacketConn(f)
+}
diff --git a/dhcpv4/server4/server.go b/dhcpv4/server4/server.go
index 5567bae..fe4ef09 100644
--- a/dhcpv4/server4/server.go
+++ b/dhcpv4/server4/server.go
@@ -123,7 +123,7 @@ func WithConn(c net.PacketConn) ServerOpt {
}
// NewServer initializes and returns a new Server object
-func NewServer(addr *net.UDPAddr, handler Handler, opt ...ServerOpt) (*Server, error) {
+func NewServer(ifname string, addr *net.UDPAddr, handler Handler, opt ...ServerOpt) (*Server, error) {
s := &Server{
Handler: handler,
}
@@ -133,7 +133,7 @@ func NewServer(addr *net.UDPAddr, handler Handler, opt ...ServerOpt) (*Server, e
}
if s.conn == nil {
var err error
- conn, err := net.ListenUDP("udp4", addr)
+ conn, err := NewIPv4UDPConn(ifname, addr.Port)
if err != nil {
return nil, err
}
diff --git a/dhcpv4/server4/server_test.go b/dhcpv4/server4/server_test.go
index d24d49b..a596d04 100644
--- a/dhcpv4/server4/server_test.go
+++ b/dhcpv4/server4/server_test.go
@@ -73,7 +73,7 @@ func setUpClientAndServer(t *testing.T, iface net.Interface, handler Handler) (*
IP: loAddr,
Port: randPort(),
}
- s, err := NewServer(&saddr, handler)
+ s, err := NewServer("", &saddr, handler)
if err != nil {
t.Fatal(err)
}
@@ -81,7 +81,7 @@ func setUpClientAndServer(t *testing.T, iface net.Interface, handler Handler) (*
_ = s.Serve()
}()
- clientConn, err := nclient4.NewIPv4UDPConn("", caddr.Port)
+ clientConn, err := NewIPv4UDPConn("", caddr.Port)
if err != nil {
t.Fatal(err)
}