// Copyright 2018 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Binary dhcp4d hands out DHCPv4 leases to clients. package main import ( "bytes" "encoding/json" "flag" "fmt" "html/template" "io" "io/ioutil" "net" "net/http" "os" "os/signal" "sort" "strings" "sync" "syscall" "time" "github.com/gokrazy/gokrazy" "github.com/google/renameio" "github.com/krolaw/dhcp4" "github.com/krolaw/dhcp4/conn" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rtr7/router7/internal/dhcp4d" "github.com/rtr7/router7/internal/multilisten" "github.com/rtr7/router7/internal/notify" "github.com/rtr7/router7/internal/oui" "github.com/rtr7/router7/internal/teelogger" ) var iface = flag.String("interface", "lan0", "ethernet interface to listen for DHCPv4 requests on") var log = teelogger.NewConsole() var nonExpiredLeases = promauto.NewGauge(prometheus.GaugeOpts{ Name: "non_expired_leases", Help: "Number of non-expired DHCP leases", }) func updateNonExpired(leases []*dhcp4d.Lease) { now := time.Now() nonExpired := 0 for _, l := range leases { if l.Expired(now) { continue } nonExpired++ } nonExpiredLeases.Set(float64(nonExpired)) } var ouiDB = oui.NewDB("/perm/dhcp4d/oui") var ( leasesMu sync.Mutex leases []*dhcp4d.Lease ) var ( timefmt = func(t time.Time) string { return t.Format("2006-01-02 15:04") } leasesTmpl = template.Must(template.New("").Funcs(template.FuncMap{ "timefmt": timefmt, "since": func(t time.Time) string { dur := time.Since(t) if dur.Hours() > 24 { return timefmt(t) } return dur.Truncate(1 * time.Second).String() }, }).Parse(`