diff --git a/dhcpd/os_linux.go b/dhcpd/os_linux.go new file mode 100644 index 00000000..5cbcfece --- /dev/null +++ b/dhcpd/os_linux.go @@ -0,0 +1,45 @@ +package dhcpd + +import ( + "net" + "os" + "syscall" + + "golang.org/x/net/ipv4" +) + +// Create a socket for receiving broadcast packets +func newBroadcastPacketConn(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, error) { + s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) + if err != nil { + return nil, err + } + + if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1); err != nil { + return nil, err + } + if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil { + return nil, err + } + if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil { + return nil, err + } + + addr := syscall.SockaddrInet4{Port: port} + copy(addr.Addr[:], bindAddr.To4()) + err = syscall.Bind(s, &addr) + if err != nil { + syscall.Close(s) + return nil, err + } + + f := os.NewFile(uintptr(s), "") + c, err := net.FilePacketConn(f) + f.Close() + if err != nil { + return nil, err + } + + p := ipv4.NewPacketConn(c) + return p, nil +} diff --git a/dhcpd/os_unix.go b/dhcpd/os_unix.go index 638f2a6c..11592d33 100644 --- a/dhcpd/os_unix.go +++ b/dhcpd/os_unix.go @@ -1,4 +1,4 @@ -// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris +// +build aix darwin dragonfly freebsd netbsd openbsd solaris package dhcpd @@ -23,9 +23,6 @@ func newBroadcastPacketConn(bindAddr net.IP, port int, ifname string) (*ipv4.Pac if err := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil { return nil, err } - if err := syscall.SetsockoptString(s, syscall.SOL_SOCKET, syscall.SO_BINDTODEVICE, ifname); err != nil { - return nil, err - } addr := syscall.SockaddrInet4{Port: port} copy(addr.Addr[:], bindAddr.To4()) diff --git a/dhcpd/os_windows.go b/dhcpd/os_windows.go index 5eb7223a..607e3d1e 100644 --- a/dhcpd/os_windows.go +++ b/dhcpd/os_windows.go @@ -1,6 +1,7 @@ package dhcpd import ( + "errors" "net" "golang.org/x/net/ipv4" @@ -8,5 +9,5 @@ import ( // Create a socket for receiving broadcast packets func newBroadcastPacketConn(bindAddr net.IP, port int, ifname string) (*ipv4.PacketConn, error) { - return nil, nil + return nil, errors.New("newBroadcastPacketConn(): not supported on Windows") }