diff --git a/capture/collector.go b/capture/collector.go index a4ac35e..7043765 100644 --- a/capture/collector.go +++ b/capture/collector.go @@ -16,7 +16,7 @@ type Collector struct { } // NewCollector creates a Collector struct -func NewCollector(handler data.Handler, ifaces []IFaceConfig) *Collector { +func NewCollector(handler data.Handler, ifaces []*IFaceConfig) *Collector { coll := &Collector{ handler: handler, @@ -26,6 +26,12 @@ func NewCollector(handler data.Handler, ifaces []IFaceConfig) *Collector { } for _, iface := range ifaces { + if iface.Port == 0 { + iface.Port = Port + } + if iface.IPAddress == "" { + iface.IPAddress = MulticastAddressDefault + } coll.listenUDP(iface) } @@ -43,7 +49,7 @@ func (coll *Collector) Close() { close(coll.queue) } -func (coll *Collector) listenUDP(iface IFaceConfig) { +func (coll *Collector) listenUDP(iface *IFaceConfig) { ip := net.ParseIP(iface.IPAddress) var conn *net.UDPConn var err error diff --git a/cmd/controller.go b/cmd/controller.go index c2c70b2..2cdf299 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -3,48 +3,35 @@ package cmd import ( "os" "os/signal" - "strings" "syscall" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "dev.sum7.eu/genofire/golang-lib/file" + "dev.sum7.eu/wifictld/analyzer/config" "dev.sum7.eu/wifictld/analyzer/capture" "dev.sum7.eu/wifictld/analyzer/controller" "dev.sum7.eu/wifictld/analyzer/database" ) -var ( - central bool -) - // queryCmd represents the query command var controllerCmd = &cobra.Command{ Use: "controller ", Short: "simulate a wifictld controller", - Example: `analyzer controller "eth0,wlan0"`, + Example: `analyzer controller "/etc/wifictld.conf"`, Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { - ifaces := strings.Split(args[0], ",") + configObj := &config.Config{} - log.Infof("listen on: %s", ifaces) + file.ReadTOML(args[0], configObj) - var ifacesConfigs []capture.IFaceConfig - for _, iface := range ifaces { - ifaceConfig := capture.IFaceConfig{ - InterfaceName: iface, - Port: port, - IPAddress: ipAddress, - } - ifacesConfigs = append(ifacesConfigs, ifaceConfig) - } + db := database.NewDB(configObj.StatePath) - db := database.NewDB() - - ctr := controller.NewController(db, central) + ctr := controller.NewController(db) defer ctr.Close() - coll := capture.NewCollector(ctr.Handler, ifacesConfigs) + coll := capture.NewCollector(ctr.Handler, configObj.Interfaces) defer coll.Close() ctr.Send = coll.Send @@ -61,7 +48,4 @@ var controllerCmd = &cobra.Command{ func init() { RootCmd.AddCommand(controllerCmd) - controllerCmd.Flags().IntVar(&port, "port", capture.Port, "define a port to listen (if not set or set to 0 the kernel will use a random free port at its own)") - controllerCmd.Flags().StringVar(&ipAddress, "listen", capture.MulticastAddressDefault, "") - controllerCmd.Flags().BoolVar(¢ral, "central", false, "") } diff --git a/cmd/dump.go b/cmd/dump.go index 5c89624..6eae152 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -30,9 +30,9 @@ var dumpCmd = &cobra.Command{ log.Infof("listen on: %s", ifaces) - var ifacesConfigs []capture.IFaceConfig + var ifacesConfigs []*capture.IFaceConfig for _, iface := range ifaces { - ifaceConfig := capture.IFaceConfig{ + ifaceConfig := &capture.IFaceConfig{ InterfaceName: iface, Port: port, IPAddress: ipAddress, diff --git a/config/config.go b/config/config.go new file mode 100644 index 0000000..f89da45 --- /dev/null +++ b/config/config.go @@ -0,0 +1,10 @@ +package config + +import ( + "dev.sum7.eu/wifictld/analyzer/capture" +) + +type Config struct { + StatePath string `toml:"state_path"` + Interfaces []*capture.IFaceConfig `toml:"interfaces"` +} diff --git a/controller/main.go b/controller/main.go index 8334fed..de15da5 100644 --- a/controller/main.go +++ b/controller/main.go @@ -18,11 +18,10 @@ type Controller struct { central bool } -func NewController(db *database.DB, central bool) *Controller { +func NewController(db *database.DB) *Controller { ctl := &Controller{ - ticker: time.NewTicker(60 * time.Second), - db: db, - central: central, + ticker: time.NewTicker(time.Minute), + db: db, } go ctl.Repeated() return ctl @@ -34,6 +33,6 @@ func (c *Controller) Close() { func (c *Controller) Repeated() { for range c.ticker.C { - log.Infof("lerned: %d APs, %d Clients", len(c.db.APs), len(c.db.Clients)) + log.Debug("lerned: %d APs, %d Clients", len(c.db.APs), len(c.db.Clients)) } } diff --git a/database/ap.go b/database/ap.go index ccfb583..2b0712a 100644 --- a/database/ap.go +++ b/database/ap.go @@ -1,4 +1,7 @@ package database +import "net" + type AP struct { + IP *net.IP } diff --git a/database/client.go b/database/client.go index 8baf11b..a775d35 100644 --- a/database/client.go +++ b/database/client.go @@ -24,12 +24,16 @@ type Client struct { func (db *DB) LearnClient(apIP net.IP, clientWifictl *data.WifiClient) bool { ret := false + // learn ap apAddr := apIP.String() ap, ok := db.APs[apAddr] if !ok { ap = &AP{} db.APs[apAddr] = ap } + ap.IP = &apIP + + // learn client clientAddr := clientWifictl.Addr.String() client, ok := db.Clients[clientAddr] if !ok { diff --git a/database/main.go b/database/main.go index 222a96b..6d06000 100644 --- a/database/main.go +++ b/database/main.go @@ -1,13 +1,40 @@ package database +import ( + "time" + + log "github.com/sirupsen/logrus" + + "dev.sum7.eu/genofire/golang-lib/file" + "dev.sum7.eu/genofire/golang-lib/worker" +) + type DB struct { Clients map[string]*Client `json:"client"` APs map[string]*AP `json:"ap"` + worker *worker.Worker } -func NewDB() *DB { - return &DB{ +func NewDB(path string) *DB { + db := &DB{ Clients: make(map[string]*Client), APs: make(map[string]*AP), } + + file.ReadJSON(path, db) + + db.worker = worker.NewWorker(time.Minute, func() { + file.SaveJSON(path, db) + log.Debug("save db state") + }) + + db.worker.Start() + + return db +} + +func (db *DB) Close() { + if db.worker != nil { + db.worker.Close() + } } diff --git a/example.conf b/example.conf new file mode 100644 index 0000000..f7151a0 --- /dev/null +++ b/example.conf @@ -0,0 +1,6 @@ +state_path = "/tmp/wifictld.json" + +[[interfaces]] +ifname = "mmfd0" +#port = 1000 +#ip_address = "ff02::31f1"