+ Replace dnsmasq on OpenWRT (minimal configuration)
This commit is contained in:
@@ -64,6 +64,7 @@ Contents:
|
|||||||
* API: Log in
|
* API: Log in
|
||||||
* API: Log out
|
* API: Log out
|
||||||
* API: Get current user info
|
* API: Get current user info
|
||||||
|
* Replace dnsmasq on OpenWRT
|
||||||
|
|
||||||
|
|
||||||
## Relations between subsystems
|
## Relations between subsystems
|
||||||
@@ -1594,3 +1595,66 @@ Response:
|
|||||||
}
|
}
|
||||||
|
|
||||||
If no client is configured then authentication is disabled and server sends an empty response.
|
If no client is configured then authentication is disabled and server sends an empty response.
|
||||||
|
|
||||||
|
|
||||||
|
## Replace dnsmasq on OpenWRT
|
||||||
|
|
||||||
|
`/etc/init.d/dnsmasq` script creates a dnsmasq.conf file and then starts dnsmasq.
|
||||||
|
To replace dnsmasq we have to read system configuration files and update (create new, if necessary) our .yaml file accordingly.
|
||||||
|
|
||||||
|
If started as:
|
||||||
|
|
||||||
|
./AdGuardHome --auto-config
|
||||||
|
|
||||||
|
* Read `/etc/config/network`:
|
||||||
|
|
||||||
|
config interface 'lan'
|
||||||
|
option netmask '255.255.255.0'
|
||||||
|
option ipaddr '192.168.8.1'
|
||||||
|
|
||||||
|
* Read `/etc/config/dhcp`:
|
||||||
|
|
||||||
|
config dhcp 'lan'
|
||||||
|
option start '100'
|
||||||
|
option limit '150'
|
||||||
|
option leasetime '12h'
|
||||||
|
|
||||||
|
* Write this yaml configuration:
|
||||||
|
|
||||||
|
dhcp:
|
||||||
|
enabled: true
|
||||||
|
interface_name: "br-lan"
|
||||||
|
gateway_ip: "192.168.8.1"
|
||||||
|
subnet_mask: "255.255.255.0"
|
||||||
|
range_start: "192.168.8.100"
|
||||||
|
range_end: "192.168.8.249"
|
||||||
|
lease_duration: 86400
|
||||||
|
icmp_timeout_msec: 1000
|
||||||
|
|
||||||
|
* Read `/etc/config/dhcp`:
|
||||||
|
|
||||||
|
config host '123412341234'
|
||||||
|
option mac '12:34:12:34:12:34'
|
||||||
|
option ip '192.168.8.2'
|
||||||
|
option name 'hostname'
|
||||||
|
|
||||||
|
* Add a static lease to leases.db:
|
||||||
|
|
||||||
|
12:34:12:34:12:34 | 192.168.8.2 | hostname
|
||||||
|
|
||||||
|
* Read `/etc/resolv.conf`:
|
||||||
|
|
||||||
|
nameserver <IP1>
|
||||||
|
nameserver <IP2>
|
||||||
|
|
||||||
|
* Write this yaml configuration:
|
||||||
|
|
||||||
|
dns:
|
||||||
|
bootstrap_dns:
|
||||||
|
- IP1
|
||||||
|
- IP2
|
||||||
|
|
||||||
|
And service script starts AGH like this:
|
||||||
|
|
||||||
|
.../AdGuardHome --auto-config
|
||||||
|
.../AdGuardHome
|
||||||
|
|||||||
@@ -139,6 +139,11 @@ func (s *Server) Init(config ServerConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save - save leases in DB
|
||||||
|
func (s *Server) Save() {
|
||||||
|
s.dbStore()
|
||||||
|
}
|
||||||
|
|
||||||
// SetOnLeaseChanged - set callback
|
// SetOnLeaseChanged - set callback
|
||||||
func (s *Server) SetOnLeaseChanged(onLeaseChanged onLeaseChangedT) {
|
func (s *Server) SetOnLeaseChanged(onLeaseChanged onLeaseChangedT) {
|
||||||
s.onLeaseChanged = onLeaseChanged
|
s.onLeaseChanged = onLeaseChanged
|
||||||
@@ -608,6 +613,11 @@ func (s *Server) handleDecline(p dhcp4.Packet, options dhcp4.Options) dhcp4.Pack
|
|||||||
|
|
||||||
// AddStaticLease adds a static lease (thread-safe)
|
// AddStaticLease adds a static lease (thread-safe)
|
||||||
func (s *Server) AddStaticLease(l Lease) error {
|
func (s *Server) AddStaticLease(l Lease) error {
|
||||||
|
return s.AddStaticLeaseWithFlags(l, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddStaticLeaseWithFlags - add a static lease (thread-safe)
|
||||||
|
func (s *Server) AddStaticLeaseWithFlags(l Lease, flush bool) error {
|
||||||
if len(l.IP) != 4 {
|
if len(l.IP) != 4 {
|
||||||
return fmt.Errorf("Invalid IP")
|
return fmt.Errorf("Invalid IP")
|
||||||
}
|
}
|
||||||
@@ -627,7 +637,9 @@ func (s *Server) AddStaticLease(l Lease) error {
|
|||||||
}
|
}
|
||||||
s.leases = append(s.leases, &l)
|
s.leases = append(s.leases, &l)
|
||||||
s.reserveIP(l.IP, l.HWAddr)
|
s.reserveIP(l.IP, l.HWAddr)
|
||||||
s.dbStore()
|
if flush {
|
||||||
|
s.dbStore()
|
||||||
|
}
|
||||||
s.leasesLock.Unlock()
|
s.leasesLock.Unlock()
|
||||||
s.notify(LeaseChangedAddedStatic)
|
s.notify(LeaseChangedAddedStatic)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
21
home/home.go
21
home/home.go
@@ -138,12 +138,9 @@ func Main(version string, channel string, armVer string) {
|
|||||||
// run is a blocking method!
|
// run is a blocking method!
|
||||||
// nolint
|
// nolint
|
||||||
func run(args options) {
|
func run(args options) {
|
||||||
// config file path can be overridden by command-line arguments:
|
Context.configFilename = "AdGuardHome.yaml"
|
||||||
if args.configFilename != "" {
|
if args.configFilename != "" {
|
||||||
Context.configFilename = args.configFilename
|
Context.configFilename = args.configFilename
|
||||||
} else {
|
|
||||||
// Default config file name
|
|
||||||
Context.configFilename = "AdGuardHome.yaml"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// configure working dir and config path
|
// configure working dir and config path
|
||||||
@@ -459,6 +456,7 @@ type options struct {
|
|||||||
pidFile string // File name to save PID to
|
pidFile string // File name to save PID to
|
||||||
checkConfig bool // Check configuration and exit
|
checkConfig bool // Check configuration and exit
|
||||||
disableUpdate bool // If set, don't check for updates
|
disableUpdate bool // If set, don't check for updates
|
||||||
|
hasAutoConfig bool // 'auto-config' argument is specified
|
||||||
|
|
||||||
// service control action (see service.ControlAction array + "status" command)
|
// service control action (see service.ControlAction array + "status" command)
|
||||||
serviceControlAction string
|
serviceControlAction string
|
||||||
@@ -498,6 +496,9 @@ func loadOptions() options {
|
|||||||
{"pidfile", "", "Path to a file where PID is stored", func(value string) { o.pidFile = value }, nil},
|
{"pidfile", "", "Path to a file where PID is stored", func(value string) { o.pidFile = value }, nil},
|
||||||
{"check-config", "", "Check configuration and exit", nil, func() { o.checkConfig = true }},
|
{"check-config", "", "Check configuration and exit", nil, func() { o.checkConfig = true }},
|
||||||
{"no-check-update", "", "Don't check for updates", nil, func() { o.disableUpdate = true }},
|
{"no-check-update", "", "Don't check for updates", nil, func() { o.disableUpdate = true }},
|
||||||
|
{"auto-config", "", "Create or update YAML configuration file from OpenWRT system configuration", nil, func() {
|
||||||
|
o.hasAutoConfig = true
|
||||||
|
}},
|
||||||
{"verbose", "v", "Enable verbose output", nil, func() { o.verbose = true }},
|
{"verbose", "v", "Enable verbose output", nil, func() { o.verbose = true }},
|
||||||
{"version", "", "Show the version and exit", nil, func() {
|
{"version", "", "Show the version and exit", nil, func() {
|
||||||
fmt.Printf("AdGuardHome %s\n", versionString)
|
fmt.Printf("AdGuardHome %s\n", versionString)
|
||||||
@@ -550,6 +551,18 @@ func loadOptions() options {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if o.verbose {
|
||||||
|
log.SetLevel(log.DEBUG)
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.hasAutoConfig {
|
||||||
|
err := autoConfig(o.configFilename)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%s", err)
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
344
home/openwrt.go
Normal file
344
home/openwrt.go
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
package home
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/dhcpd"
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/util"
|
||||||
|
"github.com/AdguardTeam/golibs/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type openwrtConfig struct {
|
||||||
|
// network:
|
||||||
|
netmask string
|
||||||
|
ipaddr string
|
||||||
|
|
||||||
|
// dhcp:
|
||||||
|
dhcpStart string
|
||||||
|
dhcpLimit string
|
||||||
|
dhcpLeasetime string
|
||||||
|
|
||||||
|
// dhcp static leases:
|
||||||
|
leases []dhcpd.Lease
|
||||||
|
|
||||||
|
// resolv.conf:
|
||||||
|
nameservers []string
|
||||||
|
|
||||||
|
// yaml.dhcp:
|
||||||
|
iface string
|
||||||
|
gwIP string
|
||||||
|
snMask string
|
||||||
|
rangeStart string
|
||||||
|
rangeEnd string
|
||||||
|
leaseDur uint32
|
||||||
|
|
||||||
|
// yaml.dns.bootstrap_dns:
|
||||||
|
bsDNS []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse command line: "option name 'value'"
|
||||||
|
func parseCmd(line string) (string, string, string) {
|
||||||
|
word1 := util.SplitNext(&line, ' ')
|
||||||
|
word2 := util.SplitNext(&line, ' ')
|
||||||
|
word3 := util.SplitNext(&line, ' ')
|
||||||
|
if len(word3) > 2 && word3[0] == '\'' && word3[len(word3)-1] == '\'' {
|
||||||
|
// 'value' -> value
|
||||||
|
word3 = word3[1:]
|
||||||
|
word3 = word3[:len(word3)-1]
|
||||||
|
}
|
||||||
|
return word1, word2, word3
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse system configuration data
|
||||||
|
// nolint(gocyclo)
|
||||||
|
func (oc *openwrtConfig) readConf(data []byte, section string, iface string) {
|
||||||
|
state := 0
|
||||||
|
sr := strings.NewReader(string(data))
|
||||||
|
r := bufio.NewReader(sr)
|
||||||
|
for {
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if len(line) == 0 {
|
||||||
|
if state == 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
state = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
word1, word2, word3 := parseCmd(line)
|
||||||
|
|
||||||
|
switch state {
|
||||||
|
case 0:
|
||||||
|
if word1 == "config" {
|
||||||
|
state = 1
|
||||||
|
if word2 == section && word3 == iface {
|
||||||
|
// found the needed section
|
||||||
|
if word2 == "interface" {
|
||||||
|
state = 2 // found the needed interface
|
||||||
|
} else if word2 == "dhcp" {
|
||||||
|
state = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// not interested
|
||||||
|
break
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if word1 != "option" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch word2 {
|
||||||
|
case "netmask":
|
||||||
|
oc.netmask = word3
|
||||||
|
case "ipaddr":
|
||||||
|
oc.ipaddr = word3
|
||||||
|
}
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if word1 != "option" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch word2 {
|
||||||
|
case "start":
|
||||||
|
oc.dhcpStart = word3
|
||||||
|
case "limit":
|
||||||
|
oc.dhcpLimit = word3
|
||||||
|
case "leasetime":
|
||||||
|
oc.dhcpLeasetime = word3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func (oc *openwrtConfig) readConfDHCPStatic(data []byte) error {
|
||||||
|
state := 0
|
||||||
|
sr := strings.NewReader(string(data))
|
||||||
|
r := bufio.NewReader(sr)
|
||||||
|
lease := dhcpd.Lease{}
|
||||||
|
for {
|
||||||
|
line, err := r.ReadString('\n')
|
||||||
|
line = strings.TrimSpace(line)
|
||||||
|
if len(line) == 0 {
|
||||||
|
if len(lease.HWAddr) != 0 && len(lease.IP) != 0 {
|
||||||
|
oc.leases = append(oc.leases, lease)
|
||||||
|
}
|
||||||
|
lease = dhcpd.Lease{}
|
||||||
|
state = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
word1, word2, word3 := parseCmd(line)
|
||||||
|
|
||||||
|
switch state {
|
||||||
|
case 0:
|
||||||
|
if word1 == "config" {
|
||||||
|
state = 1
|
||||||
|
if word2 == "host" {
|
||||||
|
state = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
// not interested
|
||||||
|
break
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if word1 != "option" {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
switch word2 {
|
||||||
|
case "mac":
|
||||||
|
lease.HWAddr, err = net.ParseMAC(word3)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
case "ip":
|
||||||
|
lease.IP = net.ParseIP(word3)
|
||||||
|
if lease.IP == nil || lease.IP.To4() == nil {
|
||||||
|
return fmt.Errorf("Invalid IP address")
|
||||||
|
}
|
||||||
|
|
||||||
|
case "name":
|
||||||
|
lease.Hostname = word3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(lease.HWAddr) != 0 && len(lease.IP) != 0 {
|
||||||
|
oc.leases = append(oc.leases, lease)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse "/etc/resolv.conf" data
|
||||||
|
func (oc *openwrtConfig) readResolvConf(data []byte) {
|
||||||
|
lines := string(data)
|
||||||
|
|
||||||
|
for len(lines) != 0 {
|
||||||
|
line := util.SplitNext(&lines, '\n')
|
||||||
|
key := util.SplitNext(&line, ' ')
|
||||||
|
if key == "nameserver" {
|
||||||
|
val := util.SplitNext(&line, ' ')
|
||||||
|
oc.nameservers = append(oc.nameservers, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert system config parameters to the format suitable by our yaml config
|
||||||
|
func (oc *openwrtConfig) prepareOutput() error {
|
||||||
|
oc.iface = "br-lan"
|
||||||
|
|
||||||
|
ipAddr := net.ParseIP(oc.ipaddr)
|
||||||
|
if ipAddr == nil || ipAddr.To4() == nil {
|
||||||
|
return fmt.Errorf("Invalid IP: %s", oc.ipaddr)
|
||||||
|
}
|
||||||
|
oc.gwIP = oc.ipaddr
|
||||||
|
|
||||||
|
ip := net.ParseIP(oc.netmask)
|
||||||
|
if ip == nil || ip.To4() == nil {
|
||||||
|
return fmt.Errorf("Invalid IP: %s", oc.netmask)
|
||||||
|
}
|
||||||
|
oc.snMask = oc.netmask
|
||||||
|
|
||||||
|
nStart, err := strconv.Atoi(oc.dhcpStart)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Invalid 'start': %s", oc.dhcpStart)
|
||||||
|
}
|
||||||
|
rangeStart := make(net.IP, 4)
|
||||||
|
copy(rangeStart, ipAddr.To4())
|
||||||
|
rangeStart[3] = byte(nStart)
|
||||||
|
oc.rangeStart = rangeStart.String()
|
||||||
|
|
||||||
|
nLim, err := strconv.Atoi(oc.dhcpLimit)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Invalid 'start': %s", oc.dhcpLimit)
|
||||||
|
}
|
||||||
|
n := nStart + nLim - 1
|
||||||
|
if n <= 0 || n > 255 {
|
||||||
|
return fmt.Errorf("Invalid 'start' or 'limit': %s/%s", oc.dhcpStart, oc.dhcpLimit)
|
||||||
|
}
|
||||||
|
rangeEnd := make(net.IP, 4)
|
||||||
|
copy(rangeEnd, ipAddr.To4())
|
||||||
|
rangeEnd[3] = byte(n)
|
||||||
|
oc.rangeEnd = rangeEnd.String()
|
||||||
|
|
||||||
|
if len(oc.dhcpLeasetime) == 0 || oc.dhcpLeasetime[len(oc.dhcpLeasetime)-1] != 'h' {
|
||||||
|
return fmt.Errorf("Invalid leasetime: %s", oc.dhcpLeasetime)
|
||||||
|
}
|
||||||
|
n, err = strconv.Atoi(oc.dhcpLeasetime[:len(oc.dhcpLeasetime)-1])
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Invalid leasetime: %s", oc.dhcpLeasetime)
|
||||||
|
}
|
||||||
|
oc.leaseDur = uint32(n) * 60 * 60
|
||||||
|
|
||||||
|
for _, s := range oc.nameservers {
|
||||||
|
if net.ParseIP(s) == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
oc.bsDNS = append(oc.bsDNS, s)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (oc *openwrtConfig) Start() error {
|
||||||
|
data, err := ioutil.ReadFile("/etc/config/network")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
oc.readConf(data, "interface", "lan")
|
||||||
|
|
||||||
|
data, err = ioutil.ReadFile("/etc/config/dhcp")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
oc.readConf(data, "dhcp", "lan")
|
||||||
|
|
||||||
|
err = oc.prepareOutput()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oc.readConfDHCPStatic(data)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read system configuration files and write our configuration files
|
||||||
|
func autoConfig(configFn string) error {
|
||||||
|
oc := openwrtConfig{}
|
||||||
|
err := oc.Start()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// config file path can be overridden by command-line arguments:
|
||||||
|
Context.configFilename = "AdGuardHome.yaml"
|
||||||
|
if len(configFn) != 0 {
|
||||||
|
Context.configFilename = configFn
|
||||||
|
}
|
||||||
|
|
||||||
|
initConfig()
|
||||||
|
if util.FileExists(config.getConfigFilename()) {
|
||||||
|
err = upgradeConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = parseConfig()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
config.DNS.BootstrapDNS = oc.bsDNS
|
||||||
|
|
||||||
|
config.DHCP.Enabled = true
|
||||||
|
config.DHCP.InterfaceName = oc.iface
|
||||||
|
config.DHCP.GatewayIP = oc.gwIP
|
||||||
|
config.DHCP.SubnetMask = oc.snMask
|
||||||
|
config.DHCP.RangeStart = oc.rangeStart
|
||||||
|
config.DHCP.RangeEnd = oc.rangeEnd
|
||||||
|
config.DHCP.LeaseDuration = oc.leaseDur
|
||||||
|
|
||||||
|
err = config.write()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
dconf := dhcpd.ServerConfig{
|
||||||
|
WorkDir: Context.workDir,
|
||||||
|
}
|
||||||
|
ds := dhcpd.Create(dconf)
|
||||||
|
if ds == nil {
|
||||||
|
return fmt.Errorf("can't initialize DHCP module")
|
||||||
|
}
|
||||||
|
for _, ocl := range oc.leases {
|
||||||
|
l := dhcpd.Lease{
|
||||||
|
HWAddr: ocl.HWAddr,
|
||||||
|
IP: ocl.IP.To4(),
|
||||||
|
Hostname: ocl.Hostname,
|
||||||
|
}
|
||||||
|
ds.AddStaticLeaseWithFlags(l, false)
|
||||||
|
log.Debug("Static DHCP lease: %s -> %s (%s)",
|
||||||
|
l.HWAddr, l.IP, l.Hostname)
|
||||||
|
}
|
||||||
|
ds.Save()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
60
home/openwrt_test.go
Normal file
60
home/openwrt_test.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package home
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestReadConf(t *testing.T) {
|
||||||
|
oc := openwrtConfig{}
|
||||||
|
data := []byte(` config interface 'lan'
|
||||||
|
option netmask '255.255.255.0'
|
||||||
|
option ipaddr '192.168.8.1'`)
|
||||||
|
oc.readConf(data, "interface", "lan")
|
||||||
|
assert.Equal(t, "255.255.255.0", oc.netmask)
|
||||||
|
assert.Equal(t, "192.168.8.1", oc.ipaddr)
|
||||||
|
|
||||||
|
data = []byte(` config dhcp 'unknown'
|
||||||
|
|
||||||
|
config dhcp 'lan'
|
||||||
|
option start '100'
|
||||||
|
option limit '150'
|
||||||
|
option leasetime '12h'
|
||||||
|
|
||||||
|
config dhcp 'unknown'`)
|
||||||
|
oc.readConf(data, "dhcp", "lan")
|
||||||
|
assert.Equal(t, "100", oc.dhcpStart)
|
||||||
|
assert.Equal(t, "150", oc.dhcpLimit)
|
||||||
|
assert.Equal(t, "12h", oc.dhcpLeasetime)
|
||||||
|
|
||||||
|
data = []byte(` # comment
|
||||||
|
nameserver abab::1234
|
||||||
|
|
||||||
|
nameserver 1.2.3.4`)
|
||||||
|
oc.readResolvConf(data)
|
||||||
|
assert.Equal(t, "abab::1234", oc.nameservers[0])
|
||||||
|
assert.Equal(t, "1.2.3.4", oc.nameservers[1])
|
||||||
|
|
||||||
|
err := oc.prepareOutput()
|
||||||
|
assert.Equal(t, nil, err)
|
||||||
|
assert.Equal(t, "br-lan", oc.iface)
|
||||||
|
assert.Equal(t, "192.168.8.1", oc.gwIP)
|
||||||
|
assert.Equal(t, "255.255.255.0", oc.snMask)
|
||||||
|
assert.Equal(t, "192.168.8.100", oc.rangeStart)
|
||||||
|
assert.Equal(t, "192.168.8.249", oc.rangeEnd)
|
||||||
|
assert.Equal(t, uint32(43200), oc.leaseDur)
|
||||||
|
assert.Equal(t, "abab::1234", oc.bsDNS[0])
|
||||||
|
assert.Equal(t, "1.2.3.4", oc.bsDNS[1])
|
||||||
|
|
||||||
|
data = []byte(`config host '123412341234'
|
||||||
|
option mac '12:34:12:34:12:34'
|
||||||
|
option ip '192.168.8.2'
|
||||||
|
option name 'hostname'`)
|
||||||
|
assert.True(t, nil == oc.readConfDHCPStatic(data))
|
||||||
|
assert.Equal(t, 1, len(oc.leases))
|
||||||
|
assert.Equal(t, "12:34:12:34:12:34", oc.leases[0].HWAddr.String())
|
||||||
|
assert.Equal(t, "192.168.8.2", oc.leases[0].IP.String())
|
||||||
|
assert.Equal(t, "hostname", oc.leases[0].Hostname)
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user