mirror of
https://github.com/RoganDawes/P4wnP1_aloa.git
synced 2025-11-15 00:17:08 +01:00
Server: monitor dnsmasq, create events for DHCP lease trigger, fix teelogger
This commit is contained in:
@@ -178,7 +178,7 @@ func ConstructEventTrigger(triggerType common_web.EvtTriggerType) *pb.Event {
|
||||
}
|
||||
}
|
||||
|
||||
func ConstructEventTriggerDHCPLease(iface, mac, ip string) *pb.Event {
|
||||
func ConstructEventTriggerDHCPLease(iface, mac, ip string, hostname string) *pb.Event {
|
||||
return &pb.Event{
|
||||
Type: common_web.EVT_TRIGGER,
|
||||
Values: []*pb.EventValue{
|
||||
@@ -186,6 +186,7 @@ func ConstructEventTriggerDHCPLease(iface, mac, ip string) *pb.Event {
|
||||
{Val: &pb.EventValue_Tstring{Tstring: iface}},
|
||||
{Val: &pb.EventValue_Tstring{Tstring: mac}},
|
||||
{Val: &pb.EventValue_Tstring{Tstring: ip}},
|
||||
{Val: &pb.EventValue_Tstring{Tstring: hostname}},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +1,27 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
//"github.com/docker/libcontainer/netlink"
|
||||
"github.com/mame82/P4wnP1_go/netlink"
|
||||
"net"
|
||||
"log"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"fmt"
|
||||
|
||||
pb "github.com/mame82/P4wnP1_go/proto"
|
||||
"errors"
|
||||
"github.com/mame82/P4wnP1_go/service/util"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUnmanagedInterface = errors.New("Not a managed network interface")
|
||||
)
|
||||
|
||||
func NewNetworkManager() (nm *NetworkManager, err error){
|
||||
func NewNetworkManager(rootService *Service) (nm *NetworkManager, err error){
|
||||
nm = &NetworkManager{
|
||||
rootSvc: rootService,
|
||||
ManagedInterfaces: make(map[string]*NetworkInterfaceManager),
|
||||
}
|
||||
|
||||
@@ -42,10 +45,11 @@ func NewNetworkManager() (nm *NetworkManager, err error){
|
||||
|
||||
type NetworkManager struct {
|
||||
ManagedInterfaces map[string]*NetworkInterfaceManager
|
||||
rootSvc *Service
|
||||
}
|
||||
|
||||
func (nm *NetworkManager) AddManagedInterface(startupConfig *pb.EthernetInterfaceSettings) (err error) {
|
||||
nim,err := NewNetworkInterfaceManager(startupConfig.Name, startupConfig)
|
||||
nim,err := NewNetworkInterfaceManager(nm, startupConfig.Name, startupConfig)
|
||||
if err != nil { return err }
|
||||
nm.ManagedInterfaces[startupConfig.Name] = nim
|
||||
return
|
||||
@@ -78,14 +82,41 @@ type NetworkInterfaceState struct {
|
||||
|
||||
// ToDo: interface watcher (up/down --> auto redeploy)
|
||||
type NetworkInterfaceManager struct {
|
||||
nm *NetworkManager
|
||||
InterfaceName string
|
||||
state *NetworkInterfaceState
|
||||
|
||||
CmdDnsmasq *exec.Cmd
|
||||
mutexDnsmasq *sync.Mutex
|
||||
LoggerDnsmasq *util.TeeLogger
|
||||
leaseMonitor *dnsmasqLeaseMonitor
|
||||
}
|
||||
|
||||
func (nim *NetworkInterfaceManager) GetState() (res *NetworkInterfaceState) {
|
||||
return nim.state
|
||||
}
|
||||
|
||||
func (nim *NetworkInterfaceManager) OnHandedOutDhcpLease(lease *DhcpLease) {
|
||||
fmt.Printf("Lease monitor %s LEASE: %v\n", nim.InterfaceName, lease)
|
||||
// should never happen (dnsmasq output parsing error otherwise)
|
||||
if nim.InterfaceName != lease.Iface {
|
||||
fmt.Println("Interface of handed out DHCP lease doesn't match managed interface, ignoring ...")
|
||||
return
|
||||
}
|
||||
|
||||
//generate trigger event
|
||||
nim.nm.rootSvc.SubSysEvent.Emit(ConstructEventTriggerDHCPLease(lease.Iface, lease.Mac.String(), lease.Ip.String(), lease.Host))
|
||||
}
|
||||
|
||||
func (nim *NetworkInterfaceManager) OnReceivedDhcpRelease(release *DhcpLease) {
|
||||
fmt.Printf("Lease monitor %s RELEASE: %v\n", nim.InterfaceName, release)
|
||||
// should never happen (dnsmasq output parsing error otherwise)
|
||||
if nim.InterfaceName != release.Iface {
|
||||
fmt.Println("Interface for received DHCP release doesn't match managed interface, ignoring ...")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (nim *NetworkInterfaceManager) ReDeploy() (err error) {
|
||||
/*
|
||||
if settings, existing := ServiceState.StoredNetworkSettings[ifName]; existing {
|
||||
@@ -110,10 +141,8 @@ func (nim *NetworkInterfaceManager) DeploySettings(settings *pb.EthernetInterfac
|
||||
}
|
||||
|
||||
//stop DHCP server / client if still running
|
||||
running, _, err := IsDHCPServerRunning(settings.Name)
|
||||
if (err == nil) && running {StopDHCPServer(settings.Name)}
|
||||
running, _, err = IsDHCPClientRunning(settings.Name)
|
||||
if (err == nil) && running {StopDHCPClient(settings.Name)}
|
||||
nim.StopDHCPServer()
|
||||
nim.StopDHCPClient()
|
||||
|
||||
switch settings.Mode {
|
||||
case pb.EthernetInterfaceSettings_MANUAL:
|
||||
@@ -172,7 +201,7 @@ func (nim *NetworkInterfaceManager) DeploySettings(settings *pb.EthernetInterfac
|
||||
err = DHCPCreateConfigFile(settings.DhcpServerSettings, confName)
|
||||
if err != nil {return err}
|
||||
//stop already running DHCPServers for the interface
|
||||
StopDHCPServer(ifName)
|
||||
nim.StopDHCPServer()
|
||||
|
||||
//special case: if the interface name is USB_ETHERNET_BRIDGE_NAME, we delete the old lease file
|
||||
// the flushing of still running leases is needed, as after USB reinit, RNDIS hosts aren't guaranteed to
|
||||
@@ -189,7 +218,7 @@ func (nim *NetworkInterfaceManager) DeploySettings(settings *pb.EthernetInterfac
|
||||
}
|
||||
|
||||
//start the DHCP server
|
||||
err = StartDHCPServer(ifName, confName)
|
||||
err = nim.StartDHCPServer(confName)
|
||||
if err != nil {return err}
|
||||
} else {
|
||||
log.Printf("Setting Interface %s to DOWN\n", iface.Name)
|
||||
@@ -206,7 +235,7 @@ func (nim *NetworkInterfaceManager) DeploySettings(settings *pb.EthernetInterfac
|
||||
err = netlink.NetworkSetMulticast(iface, true)
|
||||
if err != nil { return err }
|
||||
|
||||
StartDHCPClient(settings.Name)
|
||||
nim.StartDHCPClient()
|
||||
} else {
|
||||
log.Printf("Setting Interface %s to DOWN\n", iface.Name)
|
||||
err = netlink.NetworkLinkDown(iface)
|
||||
@@ -224,40 +253,23 @@ func (nim *NetworkInterfaceManager) DeploySettings(settings *pb.EthernetInterfac
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewNetworkInterfaceManager(ifaceName string, startupSettings *pb.EthernetInterfaceSettings) (nim *NetworkInterfaceManager, err error) {
|
||||
func NewNetworkInterfaceManager(nm *NetworkManager, ifaceName string, startupSettings *pb.EthernetInterfaceSettings) (nim *NetworkInterfaceManager, err error) {
|
||||
nim = &NetworkInterfaceManager{
|
||||
nm: nm,
|
||||
InterfaceName: ifaceName,
|
||||
state: &NetworkInterfaceState{},
|
||||
mutexDnsmasq: &sync.Mutex{},
|
||||
LoggerDnsmasq: util.NewTeeLogger(false),
|
||||
}
|
||||
nim.leaseMonitor = NewDnsmasqLeaseMonitor(nim)
|
||||
|
||||
//nim.LoggerDnsmasq.SetPrefix("dnsmasq-" + ifaceName + ": ")
|
||||
nim.LoggerDnsmasq.AddOutput(nim.leaseMonitor)
|
||||
|
||||
|
||||
nim.state.CurrentSettings = startupSettings
|
||||
nim.ReDeploy()
|
||||
|
||||
// Deploy startup configuration, to have an initial, defined state
|
||||
|
||||
/*
|
||||
// Startup settings (always DHCP client, Interface up)
|
||||
nim.state.CurrentSettings = &pb.EthernetInterfaceSettings{
|
||||
Name: ifaceName,
|
||||
Mode: pb.EthernetInterfaceSettings_DHCP_CLIENT,
|
||||
Enabled: true,
|
||||
SettingsInUse: true,
|
||||
DhcpServerSettings: &pb.DHCPServerSettings{
|
||||
CallbackScript: "",
|
||||
DoNotBindInterface: false,
|
||||
LeaseFile: nameLeaseFileDHCPSrv(ifaceName),
|
||||
ListenInterface: ifaceName,
|
||||
ListenPort: 0,
|
||||
NotAuthoritative: false,
|
||||
Options: map[uint32]string{
|
||||
3: "",
|
||||
6: "",
|
||||
},
|
||||
Ranges: []*pb.DHCPServerRange{},
|
||||
StaticHosts: []*pb.DHCPServerStaticHost{},
|
||||
},
|
||||
}
|
||||
*/
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
229
service/dhcp.go
229
service/dhcp.go
@@ -3,17 +3,22 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
pb "github.com/mame82/P4wnP1_go/proto"
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/mame82/P4wnP1_go/common_web"
|
||||
pb "github.com/mame82/P4wnP1_go/proto"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"log"
|
||||
"errors"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"strings"
|
||||
"github.com/mame82/P4wnP1_go/common_web"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
/*
|
||||
@@ -35,14 +40,13 @@ func leaseFileDHCPSrv(s *pb.DHCPServerSettings) (lf string) {
|
||||
return common_web.NameLeaseFileDHCPSrv(s.ListenInterface) //default lease file
|
||||
}
|
||||
|
||||
|
||||
|
||||
func NameConfigFileDHCPSrv(nameIface string) string {
|
||||
return fmt.Sprintf("/tmp/dnsmasq_%s.conf", nameIface)
|
||||
}
|
||||
|
||||
|
||||
func StartDHCPClient(nameIface string) (err error) {
|
||||
func (nim *NetworkInterfaceManager) StartDHCPClient() (err error) {
|
||||
nameIface := nim.InterfaceName
|
||||
log.Printf("Starting DHCP client for interface '%s'...\n", nameIface)
|
||||
|
||||
//check if interface is valid
|
||||
@@ -65,7 +69,8 @@ func StartDHCPClient(nameIface string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func IsDHCPClientRunning(nameIface string) (running bool, pid int, err error) {
|
||||
func (nim *NetworkInterfaceManager) IsDHCPClientRunning() (running bool, pid int, err error) {
|
||||
nameIface := nim.InterfaceName
|
||||
if_exists,_ := CheckInterfaceExistence(nameIface)
|
||||
if !if_exists {
|
||||
return false, 0, errors.New(fmt.Sprintf("The given interface '%s' doesn't exist", nameIface))
|
||||
@@ -102,8 +107,9 @@ func IsDHCPClientRunning(nameIface string) (running bool, pid int, err error) {
|
||||
}
|
||||
|
||||
|
||||
func StopDHCPClient(nameIface string) (err error) {
|
||||
log.Printf("Stoping DHCP client for interface '%s'...\n", nameIface)
|
||||
func (nim *NetworkInterfaceManager) StopDHCPClient() (err error) {
|
||||
nameIface := nim.InterfaceName
|
||||
log.Printf("Stopping DHCP client for interface '%s'...\n", nameIface)
|
||||
|
||||
//check if interface is valid
|
||||
if_exists,_ := CheckInterfaceExistence(nameIface)
|
||||
@@ -125,10 +131,20 @@ func StopDHCPClient(nameIface string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nim *NetworkInterfaceManager) StartDHCPServer(configPath string) (err error) {
|
||||
nim.mutexDnsmasq.Lock()
|
||||
defer nim.mutexDnsmasq.Unlock()
|
||||
|
||||
//stop dnsmasq if already running
|
||||
if nim.CmdDnsmasq != nil {
|
||||
// avoid deadlock
|
||||
nim.mutexDnsmasq.Unlock()
|
||||
nim.StopDHCPServer()
|
||||
nim.mutexDnsmasq.Lock()
|
||||
}
|
||||
|
||||
func StartDHCPServer(nameIface string, configPath string) (err error) {
|
||||
log.Printf("Starting DHCP server for interface '%s' with config '%s'...\n", nameIface, configPath)
|
||||
nameIface := nim.InterfaceName
|
||||
log.Printf("Starting dnsmasq for interface '%s' with config '%s'...\n", nameIface, configPath)
|
||||
|
||||
//check if interface is valid
|
||||
if_exists,_ := CheckInterfaceExistence(nameIface)
|
||||
@@ -136,91 +152,46 @@ func StartDHCPServer(nameIface string, configPath string) (err error) {
|
||||
return errors.New(fmt.Sprintf("The given interface '%s' doesn't exist", nameIface))
|
||||
}
|
||||
|
||||
//Check if there's already a DHCP server running for the given interface
|
||||
running, _, err := IsDHCPServerRunning(nameIface)
|
||||
if err != nil { return errors.New(fmt.Sprintf("Error fetching state of DHCP server: %v\n", err)) }
|
||||
if running {return errors.New(fmt.Sprintf("Error starting DHCP server for interface '%s', there is already a DHCP server running\n", nameIface))}
|
||||
|
||||
//We use the run command and allow dnsmasq to daemonize
|
||||
proc := exec.Command("/usr/sbin/dnsmasq", "-x", pidFileDHCPSrv(nameIface), "-C", configPath)
|
||||
//dnsmasq_out, err := proc.CombinedOutput()
|
||||
err = proc.Run()
|
||||
if err != nil { return err}
|
||||
//fmt.Printf("Dnsmasq out %s\n", dnsmasq_out)
|
||||
nim.CmdDnsmasq = exec.Command("/usr/sbin/dnsmasq", "--log-facility=-", "-k", "-x", pidFileDHCPSrv(nameIface), "-C", configPath)
|
||||
nim.CmdDnsmasq.Stdout = nim.LoggerDnsmasq.LogWriter
|
||||
nim.CmdDnsmasq.Stderr = nim.LoggerDnsmasq.LogWriter
|
||||
|
||||
|
||||
err = nim.CmdDnsmasq.Start()
|
||||
if err != nil {
|
||||
nim.CmdDnsmasq.Wait()
|
||||
return errors.New(fmt.Sprintf("Error starting dnsmasq '%v'", err))
|
||||
}
|
||||
|
||||
|
||||
|
||||
log.Printf("... DHCP server for interface '%s' started\n", nameIface)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (nim *NetworkInterfaceManager) StopDHCPServer() (err error) {
|
||||
eSuccess := fmt.Sprintf("... dnsmasq for interface '%s' stopped", nim.InterfaceName)
|
||||
eCantStop := fmt.Sprintf("... couldn't terminate dnsmasq for interface '%s'", nim.InterfaceName)
|
||||
|
||||
func IsDHCPServerRunning(nameIface string) (running bool, pid int, err error) {
|
||||
if_exists,_ := CheckInterfaceExistence(nameIface)
|
||||
if !if_exists {
|
||||
return false, 0, errors.New(fmt.Sprintf("The given interface '%s' doesn't exist", nameIface))
|
||||
log.Println("... killing dnsmasq")
|
||||
nim.mutexDnsmasq.Lock()
|
||||
defer nim.mutexDnsmasq.Unlock()
|
||||
|
||||
if nim.CmdDnsmasq == nil {
|
||||
log.Printf("... dnsmasq for interface '%s' isn't running, no need to stop it\n", nim.InterfaceName)
|
||||
return nil
|
||||
}
|
||||
|
||||
pid_file := pidFileDHCPSrv(nameIface)
|
||||
err = ProcSoftKill(nim.CmdDnsmasq, time.Second)
|
||||
if err != nil { return errors.New(eCantStop) }
|
||||
|
||||
//Check if the pidFile exists
|
||||
if _, err := os.Stat(pid_file); os.IsNotExist(err) {
|
||||
return false, 0,nil //file doesn't exist, so we assume dnsmasq isn't running
|
||||
}
|
||||
|
||||
//File exists, read the PID
|
||||
content, err := ioutil.ReadFile(pid_file)
|
||||
if err != nil { return false, 0, err}
|
||||
pid, err = strconv.Atoi(strings.TrimSuffix(string(content), "\n"))
|
||||
if err != nil { return false, 0, errors.New(fmt.Sprintf("Error parsing PID file %s: %v", pid_file, err))}
|
||||
|
||||
//With PID given, check if the process is indeed running (pid_file could stay, even if the dnsmasq process has died already)
|
||||
err_kill := syscall.Kill(pid, 0) //sig 0: doesn't send a signal, but error checking is still performed
|
||||
switch err_kill{
|
||||
case nil:
|
||||
//ToDo: Check if the running process image is indeed dnsmasq
|
||||
return true, pid, nil //Process is running
|
||||
case syscall.ESRCH:
|
||||
//Process doesn't exist
|
||||
return false, pid, nil
|
||||
case syscall.EPERM:
|
||||
//process exists, but we have no access permission
|
||||
return true, pid, err_kill
|
||||
default:
|
||||
return false, pid, err_kill
|
||||
}
|
||||
}
|
||||
|
||||
func StopDHCPServer(nameIface string) (err error) {
|
||||
//don't check if interface is valid, to allow closing of orphaned DHCP procs (interface went down while running)
|
||||
log.Printf("Stopping DHCP server for interface '%s' ...\n", nameIface)
|
||||
running,pid,err := IsDHCPServerRunning(nameIface)
|
||||
if err != nil { return }
|
||||
|
||||
if running {
|
||||
//send SIGTERM
|
||||
err = syscall.Kill(pid, syscall.SIGTERM)
|
||||
if err != nil { return }
|
||||
} else {
|
||||
log.Printf("... DHCP server for interface '%s' wasn't started\n", nameIface)
|
||||
}
|
||||
|
||||
running,pid,err = IsDHCPServerRunning(nameIface)
|
||||
if err != nil { return }
|
||||
if (running) {
|
||||
log.Printf("... couldn't terminate DHCP server for interface '%s'\n", nameIface)
|
||||
} else {
|
||||
log.Printf("... DHCP server for interface '%s' stopped\n", nameIface)
|
||||
}
|
||||
|
||||
//Delete PID file
|
||||
os.Remove(pidFileDHCPSrv(nameIface))
|
||||
|
||||
//Deleting leaseFile
|
||||
os.Remove(common_web.NameLeaseFileDHCPSrv(nameIface))
|
||||
nim.CmdDnsmasq = nil
|
||||
log.Println(eSuccess)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func DHCPCreateConfigFile(s *pb.DHCPServerSettings, filename string) (err error) {
|
||||
file_content, err := DHCPCreateConfigFileString(s)
|
||||
if err != nil {return}
|
||||
@@ -245,12 +216,19 @@ func DHCPCreateConfigFileString(s *pb.DHCPServerSettings) (config string, err er
|
||||
//Iterate over Ranges
|
||||
for _, pRange := range s.Ranges {
|
||||
//ToDo: regex check for leaseTime
|
||||
/*
|
||||
If the lease time is
|
||||
given, then leases will be given for that length of time. The
|
||||
lease time is in seconds, or minutes (eg 45m) or hours (eg 1h)
|
||||
or "infinite". If not given, the default lease time is one
|
||||
hour. The minimum lease time is two minutes
|
||||
*/
|
||||
//ToDo: check rangeLower + rangeUpper to be valid IP addresses
|
||||
if len(pRange.LeaseTime) > 0 {
|
||||
config += fmt.Sprintf("dhcp-range=%s,%s,%s\n", pRange.RangeLower, pRange.RangeUpper, pRange.LeaseTime)
|
||||
} else {
|
||||
//default to 5 minute lease
|
||||
config += fmt.Sprintf("dhcp-range=%s,%s,5m\n", pRange.RangeLower, pRange.RangeUpper)
|
||||
config += fmt.Sprintf("dhcp-range=%s,%s\n", pRange.RangeLower, pRange.RangeUpper)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -282,3 +260,86 @@ func DHCPCreateConfigFileString(s *pb.DHCPServerSettings) (config string, err er
|
||||
return
|
||||
}
|
||||
|
||||
// Lease/Release tracker
|
||||
var reLease = regexp.MustCompile(".*DHCPACK\\((.*)\\) ([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}) ([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}) (.*)")
|
||||
var reRelease = regexp.MustCompile(".*DHCPRELEASE\\((.*)\\) ([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}) ([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})")
|
||||
|
||||
|
||||
type DhcpLease struct {
|
||||
Release bool
|
||||
Iface string
|
||||
Ip net.IP
|
||||
Mac net.HardwareAddr
|
||||
Host string //only used for lease, not release
|
||||
}
|
||||
|
||||
type dnsmasqLeaseMonitor struct {
|
||||
nim *NetworkInterfaceManager
|
||||
}
|
||||
|
||||
func (m *dnsmasqLeaseMonitor) Write(p []byte) (n int, err error) {
|
||||
|
||||
/*
|
||||
dnsmasq-wlan0: 16:53:49 dnsmasq-dhcp[1855]: 1450307105 DHCPACK(wlan0) 172.24.0.18 34:e6:xx:xx:xx:xx who-knows
|
||||
dnsmasq-wlan0: 16:53:58 dnsmasq-dhcp[1855]: 4200697351 DHCPRELEASE(wlan0) 172.24.0.18 34:e6:xx:xx:xx:xx
|
||||
*/
|
||||
lineScanner := bufio.NewScanner(bytes.NewReader(p))
|
||||
lineScanner.Split(bufio.ScanLines)
|
||||
for lineScanner.Scan() {
|
||||
line := string(lineScanner.Bytes())
|
||||
switch {
|
||||
case strings.Contains(line, "DHCPACK"):
|
||||
//fmt.Printf("Lease monitor %s LEASE: %s\n", m.nim.InterfaceName, line)
|
||||
|
||||
leaseMatches := reLease.FindStringSubmatch(line)
|
||||
if len(leaseMatches) > 3 {
|
||||
lease := &DhcpLease{}
|
||||
lease.Iface = leaseMatches[1]
|
||||
lease.Ip = net.ParseIP(leaseMatches[2])
|
||||
mac,errP := net.ParseMAC(leaseMatches[3])
|
||||
if errP != nil { continue } //ignore if mac address couldn't be parsed
|
||||
lease.Mac = mac
|
||||
if len(leaseMatches) > 4 {
|
||||
//assume 4th match is hostname
|
||||
lease.Host = leaseMatches[4]
|
||||
}
|
||||
m.nim.OnHandedOutDhcpLease(lease)
|
||||
}
|
||||
|
||||
/*
|
||||
for i,m := range leaseMatches {
|
||||
fmt.Printf("\tRegex lease %d: %s\n", i, m)
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
case strings.Contains(line, "DHCPRELEASE"):
|
||||
//fmt.Printf("Lease monitor %s RELEASE: %s\n", m.nim.InterfaceName, line)
|
||||
leaseMatches := reRelease.FindStringSubmatch(line)
|
||||
if len(leaseMatches) > 3 {
|
||||
release := &DhcpLease{}
|
||||
release.Iface = leaseMatches[1]
|
||||
release.Ip = net.ParseIP(leaseMatches[2])
|
||||
mac,errP := net.ParseMAC(leaseMatches[3])
|
||||
if errP != nil { continue } //ignore if mac address couldn't be parsed
|
||||
release.Mac = mac
|
||||
release.Release = true
|
||||
|
||||
m.nim.OnReceivedDhcpRelease(release)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return len(p),nil
|
||||
}
|
||||
|
||||
|
||||
func NewDnsmasqLeaseMonitor(nim *NetworkInterfaceManager) *dnsmasqLeaseMonitor {
|
||||
return &dnsmasqLeaseMonitor{
|
||||
nim: nim,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ func NewService() (svc *Service, err error) {
|
||||
svc.SubSysEvent = NewEventManager(20)
|
||||
|
||||
svc.SubSysLed = NewLedService()
|
||||
svc.SubSysNetwork, err = NewNetworkManager()
|
||||
svc.SubSysNetwork, err = NewNetworkManager(svc) //Depends on EvenSubSys
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ func (tam *TriggerActionManager) executeActionStartHidScript(evt *pb.Event, ta *
|
||||
case triggerTypeGpioIn:
|
||||
gpioPin := ta.Trigger.(*pb.TriggerAction_GpioIn).GpioIn.GpioNum
|
||||
gpioPinName := pb.GPIONum_name[int32(gpioPin)]
|
||||
preScript += fmt.Sprintf("var GPIO_PIN=%s;\n", gpioPinName)
|
||||
preScript += fmt.Sprintf("var GPIO_PIN='%s';\n", gpioPinName)
|
||||
case triggerTypeGroupReceiveSequence:
|
||||
groupName := ta.Trigger.(*pb.TriggerAction_GroupReceiveSequence).GroupReceiveSequence.GroupName
|
||||
values := ta.Trigger.(*pb.TriggerAction_GroupReceiveSequence).GroupReceiveSequence.Values
|
||||
@@ -425,12 +425,14 @@ func (tam *TriggerActionManager) executeActionStartHidScript(evt *pb.Event, ta *
|
||||
iface := evt.Values[1].GetTstring()
|
||||
mac := evt.Values[2].GetTstring()
|
||||
ip := evt.Values[3].GetTstring()
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_IFACE=%s;\n", iface)
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_MAC=%s;\n", mac)
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_IP=%s;\n", ip)
|
||||
host := evt.Values[4].GetTstring()
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_IFACE='%s';\n", iface)
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_MAC='%s';\n", mac)
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_IP='%s';\n", ip)
|
||||
preScript += fmt.Sprintf("var DHCP_LEASE_HOST='%s';\n", host)
|
||||
case triggerTypeSshLogin:
|
||||
loginUser := evt.Values[1].GetTstring()
|
||||
preScript += fmt.Sprintf("var SSH_LOGIN_USER=%s;\n", loginUser)
|
||||
preScript += fmt.Sprintf("var SSH_LOGIN_USER='%s';\n", loginUser)
|
||||
|
||||
}
|
||||
|
||||
@@ -490,10 +492,12 @@ func (tam *TriggerActionManager) executeActionBashScript(evt *pb.Event, ta *pb.T
|
||||
iface := evt.Values[1].GetTstring()
|
||||
mac := evt.Values[2].GetTstring()
|
||||
ip := evt.Values[3].GetTstring()
|
||||
host := evt.Values[4].GetTstring()
|
||||
env = append(env,
|
||||
fmt.Sprintf("DHCP_LEASE_IFACE=%s", iface),
|
||||
fmt.Sprintf("DHCP_LEASE_MAC=%s", mac),
|
||||
fmt.Sprintf("DHCP_LEASE_IP=%s", ip),
|
||||
fmt.Sprintf("DHCP_LEASE_HOST=\"%s\"", host),
|
||||
)
|
||||
case triggerTypeSshLogin:
|
||||
loginUser := evt.Values[1].GetTstring()
|
||||
@@ -530,7 +534,8 @@ func (tam *TriggerActionManager) executeActionLog(evt *pb.Event, ta *pb.TriggerA
|
||||
iface := evt.Values[1].GetTstring()
|
||||
mac := evt.Values[2].GetTstring()
|
||||
ip := evt.Values[3].GetTstring()
|
||||
logMessage += fmt.Sprintf(" (DHCP_LEASE_IFACE=%s, DHCP_LEASE_MAC=%s, DHCP_LEASE_IP=%s)", iface, mac, ip)
|
||||
host := evt.Values[4].GetTstring()
|
||||
logMessage += fmt.Sprintf(" (DHCP_LEASE_IFACE=%s, DHCP_LEASE_MAC=%s, DHCP_LEASE_IP=%s, DHCP_LEASE_HOST='%s')", iface, mac, ip, host)
|
||||
case triggerTypeSshLogin:
|
||||
loginUser := evt.Values[1].GetTstring()
|
||||
logMessage += fmt.Sprintf(" (SSH_LOGIN_USER=%s)", loginUser)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"sync"
|
||||
"os"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type TeeLogger struct {
|
||||
@@ -18,11 +20,29 @@ type sublogger struct {
|
||||
*TeeLogger
|
||||
}
|
||||
|
||||
/*
|
||||
// struct to present an additional io.Writer, wrapping TeeLogger to ise its Print() method
|
||||
func (sl sublogger) Write(p []byte) (n int, err error) {
|
||||
sl.TeeLogger.Print(string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// struct to present an additional io.Writer, wrapping TeeLogger to ise its Print() method
|
||||
func (sl sublogger) Write(p []byte) (n int, err error) {
|
||||
//fmt.Printf("%s: %s", lw.Prefix, string(p))
|
||||
|
||||
lineScanner := bufio.NewScanner(bytes.NewReader(p))
|
||||
lineScanner.Split(bufio.ScanLines)
|
||||
for lineScanner.Scan() {
|
||||
sl.TeeLogger.Print(string(lineScanner.Bytes()))
|
||||
//fmt.Printf("%s: %s\n", lw.Prefix, string(lineScanner.Bytes()))
|
||||
}
|
||||
|
||||
|
||||
return len(p),nil
|
||||
}
|
||||
|
||||
|
||||
func NewTeeLogger(addStdout bool) (res *TeeLogger) {
|
||||
res = &TeeLogger{
|
||||
@@ -38,6 +58,7 @@ func NewTeeLogger(addStdout bool) (res *TeeLogger) {
|
||||
res.LogWriter = sublogger{ TeeLogger: res }
|
||||
res.SetFlags(log.Ltime)
|
||||
res.SetOutput(res)
|
||||
log.Println()
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user