*(dhcpd): refactoring, use dhcpd/network_utils where possible
This commit is contained in:
@@ -93,10 +93,9 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
s.conf.ConfigModified()
|
||||
|
||||
if newconfig.Enabled {
|
||||
|
||||
staticIP, err := hasStaticIP(newconfig.InterfaceName)
|
||||
staticIP, err := HasStaticIP(newconfig.InterfaceName)
|
||||
if !staticIP && err == nil {
|
||||
err = setStaticIP(newconfig.InterfaceName)
|
||||
err = SetStaticIP(newconfig.InterfaceName)
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Failed to configure static IP: %s", err)
|
||||
return
|
||||
@@ -122,7 +121,7 @@ type netInterfaceJSON struct {
|
||||
func (s *Server) handleDHCPInterfaces(w http.ResponseWriter, r *http.Request) {
|
||||
response := map[string]interface{}{}
|
||||
|
||||
ifaces, err := getValidNetInterfaces()
|
||||
ifaces, err := GetValidNetInterfaces()
|
||||
if err != nil {
|
||||
httpError(r, w, http.StatusInternalServerError, "Couldn't get interfaces: %s", err)
|
||||
return
|
||||
@@ -213,14 +212,14 @@ func (s *Server) handleDHCPFindActiveServer(w http.ResponseWriter, r *http.Reque
|
||||
othSrv["found"] = foundVal
|
||||
|
||||
staticIP := map[string]interface{}{}
|
||||
isStaticIP, err := hasStaticIP(interfaceName)
|
||||
isStaticIP, err := HasStaticIP(interfaceName)
|
||||
staticIPStatus := "yes"
|
||||
if err != nil {
|
||||
staticIPStatus = "error"
|
||||
staticIP["error"] = err.Error()
|
||||
} else if !isStaticIP {
|
||||
staticIPStatus = "no"
|
||||
staticIP["ip"] = getFullIP(interfaceName)
|
||||
staticIP["ip"] = GetFullIP(interfaceName)
|
||||
}
|
||||
staticIP["static"] = staticIPStatus
|
||||
|
||||
|
||||
@@ -10,12 +10,13 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/AdguardTeam/golibs/file"
|
||||
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
)
|
||||
|
||||
// getValidNetInterfaces returns interfaces that are eligible for DNS and/or DHCP
|
||||
// GetValidNetInterfaces returns interfaces that are eligible for DNS and/or DHCP
|
||||
// invalid interface is a ppp interface or the one that doesn't allow broadcasts
|
||||
func getValidNetInterfaces() ([]net.Interface, error) {
|
||||
func GetValidNetInterfaces() ([]net.Interface, error) {
|
||||
ifaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Couldn't get list of interfaces: %s", err)
|
||||
@@ -38,22 +39,76 @@ func getValidNetInterfaces() ([]net.Interface, error) {
|
||||
|
||||
// Check if network interface has a static IP configured
|
||||
// Supports: Raspbian.
|
||||
func hasStaticIP(ifaceName string) (bool, error) {
|
||||
if runtime.GOOS == "windows" {
|
||||
return false, errors.New("Can't detect static IP: not supported on Windows")
|
||||
func HasStaticIP(ifaceName string) (bool, error) {
|
||||
if runtime.GOOS == "linux" {
|
||||
body, err := ioutil.ReadFile("/etc/dhcpcd.conf")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return hasStaticIPDhcpcdConf(string(body), ifaceName), nil
|
||||
}
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
return hasStaticIPDarwin(ifaceName)
|
||||
}
|
||||
|
||||
return false, fmt.Errorf("Cannot check if IP is static: not supported on %s", runtime.GOOS)
|
||||
}
|
||||
|
||||
// Get IP address with netmask
|
||||
func GetFullIP(ifaceName string) string {
|
||||
cmd := exec.Command("ip", "-oneline", "-family", "inet", "address", "show", ifaceName)
|
||||
log.Tracef("executing %s %v", cmd.Path, cmd.Args)
|
||||
d, err := cmd.Output()
|
||||
if err != nil || cmd.ProcessState.ExitCode() != 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
fields := strings.Fields(string(d))
|
||||
if len(fields) < 4 {
|
||||
return ""
|
||||
}
|
||||
_, _, err = net.ParseCIDR(fields[3])
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fields[3]
|
||||
}
|
||||
|
||||
// Set a static IP for network interface
|
||||
// Supports: Raspbian.
|
||||
func SetStaticIP(ifaceName string) error {
|
||||
ip := GetFullIP(ifaceName)
|
||||
if len(ip) == 0 {
|
||||
return errors.New("Can't get IP address")
|
||||
}
|
||||
|
||||
ip4, _, err := net.ParseCIDR(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gatewayIP := getGatewayIP(ifaceName)
|
||||
add := setStaticIPDhcpcdConf(ifaceName, ip, gatewayIP, ip4.String())
|
||||
|
||||
body, err := ioutil.ReadFile("/etc/dhcpcd.conf")
|
||||
if err != nil {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
|
||||
return hasStaticIPDhcpcdConf(string(body), ifaceName), nil
|
||||
body = append(body, []byte(add)...)
|
||||
err = file.SafeWrite("/etc/dhcpcd.conf", body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// for dhcpcd.conf
|
||||
func hasStaticIPDhcpcdConf(data, ifaceName string) bool {
|
||||
lines := strings.Split(data, "\n")
|
||||
func hasStaticIPDhcpcdConf(dhcpConf, ifaceName string) bool {
|
||||
lines := strings.Split(dhcpConf, "\n")
|
||||
nameLine := fmt.Sprintf("interface %s", ifaceName)
|
||||
withinInterfaceCtx := false
|
||||
|
||||
@@ -90,27 +145,6 @@ func hasStaticIPDhcpcdConf(data, ifaceName string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Get IP address with netmask
|
||||
func getFullIP(ifaceName string) string {
|
||||
cmd := exec.Command("ip", "-oneline", "-family", "inet", "address", "show", ifaceName)
|
||||
log.Tracef("executing %s %v", cmd.Path, cmd.Args)
|
||||
d, err := cmd.Output()
|
||||
if err != nil || cmd.ProcessState.ExitCode() != 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
fields := strings.Fields(string(d))
|
||||
if len(fields) < 4 {
|
||||
return ""
|
||||
}
|
||||
_, _, err = net.ParseCIDR(fields[3])
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return fields[3]
|
||||
}
|
||||
|
||||
// Get gateway IP address
|
||||
func getGatewayIP(ifaceName string) string {
|
||||
cmd := exec.Command("ip", "route", "show", "dev", ifaceName)
|
||||
@@ -133,35 +167,6 @@ func getGatewayIP(ifaceName string) string {
|
||||
return fields[2]
|
||||
}
|
||||
|
||||
// Set a static IP for network interface
|
||||
// Supports: Raspbian.
|
||||
func setStaticIP(ifaceName string) error {
|
||||
ip := getFullIP(ifaceName)
|
||||
if len(ip) == 0 {
|
||||
return errors.New("Can't get IP address")
|
||||
}
|
||||
|
||||
ip4, _, err := net.ParseCIDR(ip)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gatewayIP := getGatewayIP(ifaceName)
|
||||
add := setStaticIPDhcpcdConf(ifaceName, ip, gatewayIP, ip4.String())
|
||||
|
||||
body, err := ioutil.ReadFile("/etc/dhcpcd.conf")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body = append(body, []byte(add)...)
|
||||
err = file.SafeWrite("/etc/dhcpcd.conf", body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// for dhcpcd.conf
|
||||
func setStaticIPDhcpcdConf(ifaceName, ip, gatewayIP, dnsIP string) string {
|
||||
var body []byte
|
||||
|
||||
8
dhcpd/network_utils_darwin.go
Normal file
8
dhcpd/network_utils_darwin.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package dhcpd
|
||||
|
||||
// Check if network interface has a static IP configured
|
||||
// Supports: Raspbian.
|
||||
func hasStaticIPDarwin(ifaceName string) (bool, error) {
|
||||
|
||||
return false, nil
|
||||
}
|
||||
61
dhcpd/network_utils_test.go
Normal file
61
dhcpd/network_utils_test.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package dhcpd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHasStaticIPDhcpcdConf(t *testing.T) {
|
||||
dhcpdConf := `#comment
|
||||
# comment
|
||||
|
||||
interface eth0
|
||||
static ip_address=192.168.0.1/24
|
||||
|
||||
# interface wlan0
|
||||
static ip_address=192.168.1.1/24
|
||||
|
||||
# comment
|
||||
`
|
||||
assert.True(t, !hasStaticIPDhcpcdConf(dhcpdConf, "wlan0"))
|
||||
|
||||
dhcpdConf = `#comment
|
||||
# comment
|
||||
|
||||
interface eth0
|
||||
static ip_address=192.168.0.1/24
|
||||
|
||||
# interface wlan0
|
||||
static ip_address=192.168.1.1/24
|
||||
|
||||
# comment
|
||||
|
||||
interface wlan0
|
||||
# comment
|
||||
static ip_address=192.168.2.1/24
|
||||
`
|
||||
assert.True(t, hasStaticIPDhcpcdConf(dhcpdConf, "wlan0"))
|
||||
}
|
||||
|
||||
func TestSetStaticIPDhcpcdConf(t *testing.T) {
|
||||
dhcpcdConf := `
|
||||
interface wlan0
|
||||
static ip_address=192.168.0.2/24
|
||||
static routers=192.168.0.1
|
||||
static domain_name_servers=192.168.0.2
|
||||
|
||||
`
|
||||
s := setStaticIPDhcpcdConf("wlan0", "192.168.0.2/24", "192.168.0.1", "192.168.0.2")
|
||||
assert.Equal(t, dhcpcdConf, s)
|
||||
|
||||
// without gateway
|
||||
dhcpcdConf = `
|
||||
interface wlan0
|
||||
static ip_address=192.168.0.2/24
|
||||
static domain_name_servers=192.168.0.2
|
||||
|
||||
`
|
||||
s = setStaticIPDhcpcdConf("wlan0", "192.168.0.2/24", "", "192.168.0.2")
|
||||
assert.Equal(t, dhcpcdConf, s)
|
||||
}
|
||||
Reference in New Issue
Block a user