diff options
author | borna-blazevic <54031251+borna-blazevic@users.noreply.github.com> | 2019-08-14 10:20:28 +0200 |
---|---|---|
committer | Pablo Mazzini <pmazzini@gmail.com> | 2019-08-14 09:20:28 +0100 |
commit | 393ae75a101b4e8d93f82dd7242401dd50ac0868 (patch) | |
tree | 725ec5a42fd2066e71ba284bb9823d08bb0d138b /dhcpv4/server4/conn.go | |
parent | 6d0d21cc633742eb4de9b08ad7a53572a6907623 (diff) |
Bind interface fix (#310)
Added a bind to interface functionality.
Diffstat (limited to 'dhcpv4/server4/conn.go')
-rw-r--r-- | dhcpv4/server4/conn.go | 45 |
1 files changed, 45 insertions, 0 deletions
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) +} |