From d5f46f51b8fcac0275ad04442917eff2f1cf4ba8 Mon Sep 17 00:00:00 2001
From: Simon Zolin <s.zolin@adguard.com>
Date: Tue, 23 Apr 2019 15:14:26 +0300
Subject: [PATCH] - dhcp: fix build on macos #704

---
 dhcpd/os_linux.go   | 45 +++++++++++++++++++++++++++++++++++++++++++++
 dhcpd/os_unix.go    |  5 +----
 dhcpd/os_windows.go |  3 ++-
 3 files changed, 48 insertions(+), 5 deletions(-)
 create mode 100644 dhcpd/os_linux.go

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")
 }