97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
|
package config
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"path"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
leaseFileKey = "dhcp-leasefile"
|
||
|
rangeKey = "dhcp-range"
|
||
|
confFileKey = "conf-file"
|
||
|
confDirKey = "conf-dir"
|
||
|
)
|
||
|
|
||
|
func tryParseLineOption(line, key string) (string, bool) {
|
||
|
if !strings.HasPrefix(line, key) {
|
||
|
return "", false
|
||
|
}
|
||
|
|
||
|
_, val, found := strings.Cut(line, "=")
|
||
|
return val, found
|
||
|
}
|
||
|
|
||
|
type dnsmasqConfOptions struct {
|
||
|
leaseFile string
|
||
|
rangeStart string
|
||
|
rangeEnd string
|
||
|
}
|
||
|
|
||
|
func defaultDNSMasqOptions() map[string]string {
|
||
|
return map[string]string{
|
||
|
confDirKey: "/etc/dnsmasq.d",
|
||
|
confFileKey: "",
|
||
|
leaseFileKey: "/var/lib/misc/dnsmasq.leases",
|
||
|
rangeKey: "",
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func parseDNSMasqConfFile(content string, options map[string]string) {
|
||
|
for _, l := range strings.Split(content, "\n") {
|
||
|
for key := range options {
|
||
|
newVal, found := tryParseLineOption(l, key)
|
||
|
if found {
|
||
|
options[key] = newVal
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func parseDNSMasqOptions(rootFileContent string) (dnsmasqConfOptions, error) {
|
||
|
rawOptions := defaultDNSMasqOptions()
|
||
|
|
||
|
// start with parsing the root file
|
||
|
parseDNSMasqConfFile(rootFileContent, rawOptions)
|
||
|
|
||
|
// get all additional conf files in the provided directory
|
||
|
confDir := rawOptions[confDirKey]
|
||
|
if confDir != "" {
|
||
|
entries, err := os.ReadDir(confDir)
|
||
|
if err != nil {
|
||
|
return dnsmasqConfOptions{}, fmt.Errorf("failed to get list of additional config files: %w", err)
|
||
|
}
|
||
|
for _, e := range entries {
|
||
|
if e.IsDir() || !strings.HasSuffix(e.Name(), ".conf") {
|
||
|
continue
|
||
|
}
|
||
|
fileContent, err := os.ReadFile(path.Join(confDir, e.Name()))
|
||
|
if err != nil {
|
||
|
return dnsmasqConfOptions{}, fmt.Errorf("failed to read sub config file: %w", err)
|
||
|
}
|
||
|
parseDNSMasqConfFile(string(fileContent), rawOptions)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// get any additional config file
|
||
|
if additionalFile := rawOptions[confFileKey]; additionalFile != "" {
|
||
|
filecontent, err := os.ReadFile(additionalFile)
|
||
|
if err != nil {
|
||
|
return dnsmasqConfOptions{}, fmt.Errorf("failed to read additional config file: %w", err)
|
||
|
}
|
||
|
parseDNSMasqConfFile(string(filecontent), rawOptions)
|
||
|
}
|
||
|
|
||
|
dhcpRange := strings.Split(rawOptions[rangeKey], ",")
|
||
|
if len(dhcpRange) < 2 {
|
||
|
return dnsmasqConfOptions{}, fmt.Errorf("invalid value for DHCP range: %s", rawOptions[rangeKey])
|
||
|
}
|
||
|
|
||
|
return dnsmasqConfOptions{
|
||
|
leaseFile: rawOptions[leaseFileKey],
|
||
|
rangeStart: dhcpRange[0],
|
||
|
rangeEnd: dhcpRange[1],
|
||
|
}, nil
|
||
|
}
|