Compare commits

...

51 Commits

Author SHA1 Message Date
Jeff Carr 406472ecb2 move this code to go.wit.com/lib/hostname 2025-03-23 10:18:04 -05:00
Jeff Carr 3185270746 use go-cmd/cmd 2024-11-08 06:43:57 -06:00
Jeff Carr 7e1460f9f6 getDomainname()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-11-01 21:41:46 -05:00
Jeff Carr 40e811b3b3 Init() is a better function name here 2024-02-25 18:39:27 -06:00
Jeff Carr 4641eceda8 remove testing code
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-31 13:34:13 -06:00
Jeff Carr 1a9b13dda5 use SetText() not SetValue()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-31 12:41:28 -06:00
Jeff Carr 513c38922b new release
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-28 22:53:43 -06:00
Jeff Carr e15bf07c7c release automation
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 13:22:19 -06:00
Jeff Carr a65f8584f2 release automation testing
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-27 10:13:43 -06:00
Jeff Carr ef588e8e22 absolutely never directories
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-24 22:15:57 -06:00
Jeff Carr 99f53dd97b new gui release
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-24 17:41:55 -06:00
Jeff Carr 433d83e636 fix name changes
new gadgets
    correct go mod
    updated paths

Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-21 02:23:47 -06:00
Jeff Carr fdac7e7b89 restore the files after garbage collection
hopefully this actually is a valid git repo
2024-01-15 19:24:48 -06:00
Jeff Carr 94aa368cff garbage collect after cleaning to retain history 2024-01-15 19:00:41 -06:00
Jeff Carr d0fe8be370 old code
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-13 21:30:52 -06:00
Jeff Carr 5a218aa810 autofix!
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-10 20:22:25 -06:00
Jeff Carr 9278bab222 go.wit.com/log change
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-08 23:54:02 -06:00
Jeff Carr eadd72a066 go.wit.com/log NewFlag()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-08 22:34:08 -06:00
Jeff Carr e538ae8009 errors are always displayed
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-08 11:05:40 -06:00
Jeff Carr 8e91fdd993 error button disables
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-07 11:52:15 -06:00
Jeff Carr b107cd2b6a error window v0.1
error box starts doing something
    start a window for errors to fix
    more status cleanups & housecleaning

    Signed-off-by: Jeff Carr <jcarr@wit.com>

Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-07 10:38:17 -06:00
Jeff Carr 963f9e2155 finds and reports OS nameservers
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-07 07:34:12 -06:00
Jeff Carr d1d5e15cca fix real IPv4 display
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-07 07:21:36 -06:00
Jeff Carr a811226c53 window titles update to correct values
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-07 07:09:59 -06:00
Jeff Carr b1c7bb8a31 update worked correctly for the first time
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 21:02:41 -06:00
Jeff Carr 7a7b4b2ae4 knows which AAAA records are broken!
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 19:58:58 -06:00
Jeff Carr 39a32b3933 ready to compare host and dns AAAA values
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 19:00:51 -06:00
Jeff Carr 1191d15484 purge years of old test code
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 17:51:41 -06:00
Jeff Carr a385734bc9 all engines running and stable
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 16:59:33 -06:00
Jeff Carr bd3e75e687 LinuxStatus() detects VALID hostname
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 16:36:34 -06:00
Jeff Carr c6dbbc3542 more cleaning
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 15:38:40 -06:00
Jeff Carr f89ba90467 more cleanups after removing old window
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 15:07:30 -06:00
Jeff Carr b8991ccf58 old window is nearly deprecated
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 14:57:51 -06:00
Jeff Carr 73811178b5 more isolation of Update() pieces
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 14:23:19 -06:00
Jeff Carr a8f4ba1b05 works in sierpinski carpet mode
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 13:55:46 -06:00
Jeff Carr f6f5bdba4e stepping through init on a window with state
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 11:12:10 -06:00
Jeff Carr c59247824f more window handling
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 05:55:51 -06:00
Jeff Carr 1de593fd63 move UID code
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 05:32:52 -06:00
Jeff Carr 4529b473dc add LinuxStatus()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 05:24:11 -06:00
Jeff Carr a808bb5518 all engines still firing
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 02:21:56 -06:00
Jeff Carr 46f58f7651 make new resolverStatus()
also fix dns-https

Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-06 01:41:33 -06:00
Jeff Carr 2800b23f81 all engines firing quietly
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-05 14:49:42 -06:00
Jeff Carr a8bc9d51ea all engines are starting without the rocket exploding
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-05 00:42:15 -06:00
Jeff Carr c3f55d5452 almost starting all the engines on startup
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-05 00:30:58 -06:00
Jeff Carr 6fc08df071 convert to gadget.BasicWindow()
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-05 00:07:13 -06:00
Jeff Carr c420145c2e use 'go.wit.com/log'
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-03 19:33:13 -06:00
Jeff Carr 3be643036f fixed stuff
Signed-off-by: Jeff Carr <jcarr@wit.com>
2024-01-03 12:40:31 -06:00
Jeff Carr f332c0eaf6 move to go.wit.com/gui/gadgets
Signed-off-by: Jeff Carr <jcarr@wit.com>
2023-12-29 02:43:00 -06:00
Jeff Carr beb076375e add digital ocean & DNS state windows
lists digital ocean droplets
    create a new digital ocean droplet
    knows what needs to be done to get IPv4 and IPv6 to work
    update windows on Show()
    make a window for the state of DNS specific to the hostname

Signed-off-by: Jeff Carr <jcarr@wit.com>
2023-12-29 01:36:10 -06:00
Jeff Carr a84e307c77 DNS status window Show() and Hide()
display HTTPS results from dns.google.com for go.wit.com
    use a grid instead of boxes
    start go.wit.com/log

Signed-off-by: Jeff Carr <jcarr@wit.com>
2023-12-28 15:36:05 -06:00
Jeff Carr 88fb976119 Detect that a VPN is needed
IPv6() returns true if it's working
    display duration
    a 'DNS Lookup Status' window
    actual dig results
    display status and failure counters
    count lookup failures and successes
    add TCP dns lookup
    logic to test if dns is working at all
    add DNS over HTTPS
    cloudflare new & update kind of working
    holy shit, go.wit.com finally works with git mod tidy
    working, but cloudflare api stuff is broken
    AAAA '(none)' logic detection is better
    cloudflare control panel
    display the working real AAAA addresses

Signed-off-by: Jeff Carr <jcarr@wit.com>
2023-12-28 09:43:45 -06:00
34 changed files with 742 additions and 2156 deletions

7
.gitignore vendored
View File

@ -1,7 +1,10 @@
*.swp
go.sum
go.mod
control-panel-dns
/files/*
/*.deb
*.swp
/plugins/*
examples/cloudflare/cloudflare
control-panel-dns

17
Makefile Normal file
View File

@ -0,0 +1,17 @@
all: goimports vet
vet:
GO111MODULE=off go vet
goimports:
goimports -w *.go
redomod:
rm -f go.*
goimports -w *.go
GO111MODULE= go mod init
GO111MODULE= go mod tidy
clean:
-rm -f go.*
-go-mod-clean --purge

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# linuxstatus
this is being moved to go.wit.com/lib/hostname

38
args.go Normal file
View File

@ -0,0 +1,38 @@
package linuxstatus
/*
this enables command line options from other packages like 'gui' and 'log'
*/
import (
"go.wit.com/log"
)
var NOW *log.LogFlag
var INFO *log.LogFlag
var NET *log.LogFlag
var DNS *log.LogFlag
var PROC *log.LogFlag
var SPEW *log.LogFlag
var WARN *log.LogFlag
var CHANGE *log.LogFlag
var STATUS *log.LogFlag
func init() {
full := "go.wit.com/control-panels/dns/linuxstatus"
short := "linux"
NOW = log.NewFlag("NOW", true, full, short, "temp debugging stuff")
INFO = log.NewFlag("INFO", false, full, short, "normal debugging stuff")
NET = log.NewFlag("NET", false, full, short, "Network logging")
DNS = log.NewFlag("DNS", false, full, short, "dnsStatus.update()")
PROC = log.NewFlag("PROC", false, full, short, "/proc loggging")
WARN = log.NewFlag("WARN", true, full, short, "bad things")
SPEW = log.NewFlag("SPEW", false, full, short, "spew stuff")
CHANGE = log.NewFlag("CHANGE", true, full, short, "when host or dns change")
STATUS = log.NewFlag("STATUS", false, full, short, "Update() details")
}

60
bash.go
View File

@ -1,60 +0,0 @@
package main
import (
"io"
"log"
"os"
"os/exec"
"os/signal"
"syscall"
"github.com/creack/pty"
"golang.org/x/term"
)
func test() error {
// Create arbitrary command.
c := exec.Command("bash")
// Start the command with a pty.
ptmx, err := pty.Start(c)
if err != nil {
return err
}
// Make sure to close the pty at the end.
defer func() { _ = ptmx.Close() }() // Best effort.
// Handle pty size.
ch := make(chan os.Signal, 1)
signal.Notify(ch, syscall.SIGWINCH)
go func() {
for range ch {
if err := pty.InheritSize(os.Stdin, ptmx); err != nil {
log.Println("error resizing pty: %s", err)
}
}
}()
ch <- syscall.SIGWINCH // Initial resize.
defer func() { signal.Stop(ch); close(ch) }() // Cleanup signals when done.
// Set stdin in raw mode.
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
panic(err)
}
defer func() { _ = term.Restore(int(os.Stdin.Fd()), oldState) }() // Best effort.
// Copy stdin to the pty and the pty to stdout.
// NOTE: The goroutine will keep reading until the next keystroke before returning.
go func() { _, _ = io.Copy(ptmx, os.Stdin) }()
_, _ = io.Copy(os.Stdout, ptmx)
return nil
}
func mainBash() {
if err := test(); err != nil {
debug(LogError, "exit in mainBash()")
exit(err)
}
}

63
common.go Normal file
View File

@ -0,0 +1,63 @@
// This creates a simple hello world window
package linuxstatus
import (
"go.wit.com/log"
)
// reports externally if something has changed
// since the last time it was asked about it
func (ls *LinuxStatus) Changed() bool {
if !ls.Ready() {
return false
}
if ls.changed {
ls.changed = false
return true
}
return false
}
func (ls *LinuxStatus) Show() {
if !ls.Ready() {
return
}
log.Log(CHANGE, "Show() window ready =", ls.ready)
ls.window.Show()
ls.hidden = false
}
func (ls *LinuxStatus) Hide() {
if !ls.Ready() {
return
}
log.Log(CHANGE, "Hide() window ready =", ls.ready)
ls.window.Hide()
ls.hidden = true
}
func (ls *LinuxStatus) Toggle() {
if !ls.Ready() {
return
}
log.Log(CHANGE, "Toggle() window ready =", ls.ready)
if ls.hidden {
ls.Show()
} else {
ls.Hide()
}
}
func (ls *LinuxStatus) Ready() bool {
log.Log(SPEW, "Ready() maybe not ready? ls =", ls)
if me == nil {
return false
}
if ls == nil {
return false
}
if ls.window == nil {
return false
}
return me.ready
}

50
debian/Makefile vendored
View File

@ -1,50 +0,0 @@
# GITVERSION=$(shell git rev-parse FETCH_HEAD)
VERSION=$(shell git describe --tags $(git rev-list --tags --max-count=1) | sed 's/^v//')
BASENAME=control-panel-dns
all: help deb
help:
@echo
@echo "make deb # attempt to build the .deb package using dpkg"
@echo
deb: clean extract DEBIAN build
clean:
rm -rf ../files
rm -f ../*.deb
rm -f ../*.tar.xz data.tar.xz
rm -rf DEBIAN
extract:
mkdir -p ../files/usr/bin
mkdir -p ../files/usr/lib/control-panel-dns/
-cp ~/go/src/go.wit.com/gui/toolkit/*.so ../files/usr/lib/control-panel-dns/
cp ../README.md ../files/usr/lib/control-panel-dns/
cp ../control-panel-dns ../files/usr/bin/
# makes the DEBIAN/ directory
DEBIAN:
mkdir -p DEBIAN
# make the md5sum file
cd ../files/ && find -type f -exec md5sum '{}' \; |sort -k2 >../md5sums
mv ../md5sums DEBIAN/
# make the control there
mkdir -p DEBIAN
cp control DEBIAN/
echo Version: ${VERSION} >>DEBIAN/control
cp postinst DEBIAN
build:
mv DEBIAN ../files/
cd .. && dpkg-deb --build files ${BASENAME}_${VERSION}_amd64.deb
@echo
@echo '#######################'
cd .. && dpkg-deb --info ${BASENAME}_${VERSION}_amd64.deb
@echo '#######################'
@echo

1
debian/compat vendored
View File

@ -1 +0,0 @@
10

9
debian/control vendored
View File

@ -1,9 +0,0 @@
Source: control-panel-dns
Build-Depends: golang
Package: control-panel-dns
Maintainer: Jeff Carr <jcarr@wit.com>
Architecture: amd64
Depends:
Recommends: libgtk-3-0, ddclient, ddupdate
Description: a control panel for DNS and IPv6 settings
Goals: show the settings, validate & update DNS

1
debian/postinst vendored
View File

@ -1 +0,0 @@
#!/bin/sh

View File

@ -1,44 +0,0 @@
package dnssecsocket
//
// By using the package "github.com/alexflint/go-arg",
// these can be configured from the command line
//
import (
// arg "github.com/alexflint/go-arg"
// "log"
// "os"
)
type Args struct {
VerboseDnssec bool `arg:"--verbose-dnssec" help:"debug dnssec lookups"`
Foo string `arg:"env:USER"`
}
var args struct {
Args
Verbose bool
}
func Parse (b bool) {
args.Verbose = b
args.VerboseDnssec = b
}
// I attempted to pass the *arg.Parser down
// to see if I could find the value somewhere but I couldn't find it
/*
var conf arg.Config
func Parse (p *arg.Parser) {
// conf.Program = "control-panel-dns"
// conf.IgnoreEnv = false
// arg.NewParser(conf, &args)
log.Println("fuckit", p, args.VerboseDnssec)
for i, v := range p.SubcommandNames() {
log.Println("dnssec.Parse", i, v)
}
p.Jcarr()
}
*/

View File

@ -1,131 +0,0 @@
// inspired from:
// https://github.com/mactsouk/opensource.com.git
// and
// https://coderwall.com/p/wohavg/creating-a-simple-tcp-server-in-go
package dnssecsocket
import "os"
import "bufio"
import "math/rand"
import "net"
import "strconv"
import "strings"
// import log "github.com/sirupsen/logrus"
// import "github.com/wercker/journalhook"
import "go.wit.com/shell"
// will try to get this hosts FQDN
// import "github.com/Showmax/go-fqdn"
import "github.com/miekg/dns"
// import "github.com/davecgh/go-spew/spew"
const MIN = 1
const MAX = 100
func random() int {
return rand.Intn(MAX-MIN) + MIN
}
func GetRemoteAddr(conn net.TCPConn) string {
clientAddr := conn.RemoteAddr().String()
parts := strings.Split(clientAddr, "]")
ipv6 := parts[0]
return ipv6[1:]
}
//
// Handle each connection
// Each client must send it's hostname as the first line
// Then each hostname is verified with DNSSEC
//
func HandleConnection(conn *net.TCPConn) {
// Disable journalhook until it builds on Windows
// journalhook.Enable()
// spew.Dump(conn)
// ipv6client := GetRemoteAddr(c)
ipv6client := conn.RemoteAddr()
log(args.VerboseDnssec, "Serving to %s as the IPv6 client", ipv6client)
// setup this TCP socket as the "standard input"
// newStdin, _ := bufio.NewReader(conn.File())
newStdin, _ := conn.File()
newreader := bufio.NewReader(newStdin)
log(args.VerboseDnssec, "Waiting for the client to tell me its name")
netData, err := newreader.ReadString('\n')
if err != nil {
log(args.VerboseDnssec, err)
return
}
clientHostname := strings.TrimSpace(netData)
log(args.VerboseDnssec, "Recieved client hostname as:", clientHostname)
dnsRR := Dnstrace(clientHostname, "AAAA")
if (dnsRR == nil) {
log(args.VerboseDnssec, "dnsRR IS NIL")
log(args.VerboseDnssec, "dnsRR IS NIL")
log(args.VerboseDnssec, "dnsRR IS NIL")
conn.Close()
return
}
ipaddr := dns.Field(dnsRR[1], 1)
log(args.VerboseDnssec, "Client claims to be: ", ipaddr)
log(args.VerboseDnssec, "Serving to IPv6 client:", ipv6client)
/* TODO: figure out how to fix this check
if (ipaddr != ipv6client) {
log(args.VerboseDnssec)
log(args.VerboseDnssec, "DNSSEC ERROR: client IPv6 does not work")
log(args.VerboseDnssec, "DNSSEC ERROR: client IPv6 does not work")
log(args.VerboseDnssec, "DNSSEC ERROR: client IPv6 does not work")
log(args.VerboseDnssec)
conn.Close()
return
}
*/
f, _ := conn.File()
// shell.SetStdout(f)
// shell.SpewOn() // turn this on if you want to look at the process exit states
// send all log() output to systemd journalctl
// shell.UseJournalctl()
for {
defer shell.SetStdout(os.Stdout)
defer conn.Close()
netData, err := newreader.ReadString('\n')
if err != nil {
log(args.VerboseDnssec, err)
return
}
temp := strings.TrimSpace(string(netData))
if temp == "STOP" {
break
}
log(args.VerboseDnssec, "Recieved: ", temp)
if (temp == "list") {
log(args.VerboseDnssec, "Should run list here")
shell.SetStdout(f)
shell.Run("/root/bin/list.testing.com")
shell.SetStdout(os.Stdout)
}
if (temp == "cpuinfo") {
log(args.VerboseDnssec, "Should cat /proc/cpuinfo")
shell.SetStdout(f)
shell.Run("cat /proc/cpuinfo")
shell.SetStdout(os.Stdout)
}
result := strconv.Itoa(random()) + "\n"
conn.Write([]byte(string(result)))
}
}

View File

@ -1,168 +0,0 @@
package dnssecsocket
// inspired from github.com/rs/dnstrace/main.go
import "fmt"
import "net"
// import "os"
import "strings"
import "time"
import "github.com/miekg/dns"
import "github.com/rs/dnstrace/client"
// import log "github.com/sirupsen/logrus"
// this is cool, but breaks the Windows build
// import "github.com/wercker/journalhook"
// import "github.com/davecgh/go-spew/spew"
const (
cReset = 0
cBold = 1
cRed = 31
cGreen = 32
cYellow = 33
cBlue = 34
cMagenta = 35
cCyan = 36
cGray = 37
cDarkGray = 90
)
func colorize(s interface{}, color int, enabled bool) string {
if !enabled {
return fmt.Sprintf("%v", s)
}
return fmt.Sprintf("\x1b[%dm%v\x1b[0m", color, s)
}
func Dnstrace(hostname string, qtypestr string) []dns.RR {
// color := flag.Bool("color", true, "Enable/disable colors")
color := true
qname := dns.Fqdn(hostname)
// qtype := dns.TypeA
qtype := dns.StringToType[qtypestr]
col := func(s interface{}, c int) string {
return colorize(s, c, color)
}
m := &dns.Msg{}
m.SetQuestion(qname, qtype)
// Set DNSSEC opt to better emulate the default queries from a nameserver.
o := &dns.OPT{
Hdr: dns.RR_Header{
Name: ".",
Rrtype: dns.TypeOPT,
},
}
o.SetDo()
o.SetUDPSize(dns.DefaultMsgSize)
m.Extra = append(m.Extra, o)
c := client.New(1)
c.Client.Timeout = 500 * time.Millisecond
t := client.Tracer{
GotIntermediaryResponse: func(i int, m *dns.Msg, rs client.Responses, rtype client.ResponseType) {
fr := rs.Fastest()
var r *dns.Msg
if fr != nil {
r = fr.Msg
}
qname := m.Question[0].Name
qtype := dns.TypeToString[m.Question[0].Qtype]
if i > 1 {
log(args.VerboseDnssec)
}
log(args.VerboseDnssec, "%d - query %s %s", i, qtype, qname)
if r != nil {
log(args.VerboseDnssec, ": %s", strings.Replace(strings.Replace(r.MsgHdr.String(), ";; ", "", -1), "\n", ", ", -1))
}
log(args.VerboseDnssec)
for _, pr := range rs {
ln := 0
if pr.Msg != nil {
ln = pr.Msg.Len()
}
rtt := float64(pr.RTT) / float64(time.Millisecond)
lrtt := "0ms (from cache)"
if pr.Server.HasGlue {
lrtt = "0ms (from glue)"
} else if pr.Server.LookupRTT > 0 {
lrtt = fmt.Sprintf("%.2fms", float64(pr.Server.LookupRTT)/float64(time.Millisecond))
}
log(args.VerboseDnssec, col(" - %d bytes in %.2fms + %s lookup on %s(%s)", cDarkGray), ln, rtt, lrtt, pr.Server.Name, pr.Addr)
if pr.Err != nil {
err := pr.Err
if oerr, ok := err.(*net.OpError); ok {
err = oerr.Err
}
log(args.VerboseDnssec, ": %v", col(err, cRed))
}
log(args.VerboseDnssec, "\n")
}
switch rtype {
case client.ResponseTypeDelegation:
var label string
for _, rr := range r.Ns {
if ns, ok := rr.(*dns.NS); ok {
label = ns.Header().Name
break
}
}
_, ns := c.DCache.Get(label)
for _, s := range ns {
var glue string
if s.HasGlue {
glue = col("glue: "+strings.Join(s.Addrs, ","), cDarkGray)
} else {
glue = col("no glue", cYellow)
}
log(args.VerboseDnssec, "%s %d NS %s (%s)\n", label, s.TTL, s.Name, glue)
}
case client.ResponseTypeCNAME:
for _, rr := range r.Answer {
log(args.VerboseDnssec, rr)
}
}
},
FollowingCNAME: func(domain, target string) {
log(args.VerboseDnssec, col("\n~ following CNAME %s -> %s\n", cBlue), domain, target)
},
}
r, rtt, err := c.RecursiveQuery(m, t)
if err != nil {
log(args.VerboseDnssec, col("*** error: %v\n", cRed), err)
return nil
}
log(args.VerboseDnssec)
log(args.VerboseDnssec, col(";; Cold best path time: %s\n\n", cGray), rtt)
for i, rr := range r.Answer {
log(args.VerboseDnssec, "r.Answer =", i, rr, args.VerboseDnssec)
}
return r.Answer
// for _, rr := range r.Answer {
// return rr
// }
// return nil
}
func ResolveIPv6hostname(hostname string) *net.TCPAddr {
dnsRR := Dnstrace(hostname, "AAAA")
if (dnsRR == nil) {
return nil
}
aaaa := dns.Field(dnsRR[1], 1)
localTCPAddr, _ := net.ResolveTCPAddr("tcp", aaaa)
return localTCPAddr
}
func UseJournalctl() {
log(args.VerboseDnssec, "journalhook is disabled because it breaks the Windows build right now")
// journalhook.Enable()
}

View File

@ -1,30 +0,0 @@
package dnssecsocket
import (
witlog "go.wit.com/gui/log"
)
// various debugging flags
var logNow bool = true // useful for active development
var logError bool = true
var logWarn bool = false
var logInfo bool = false
var logVerbose bool = false
var SPEW witlog.Spewt
// var log interface{}
func log(a ...any) {
witlog.Where = "wit/gui"
witlog.Log(a...)
}
func sleep(a ...any) {
witlog.Sleep(a...)
}
func exit(a ...any) {
log(logError, "got to log() exit")
witlog.Exit(a...)
}

36
draw.go Normal file
View File

@ -0,0 +1,36 @@
// This creates a simple hello world window
package linuxstatus
import (
"go.wit.com/lib/gadgets"
)
// creates the actual widgets.
// it's assumed you are always passing in a box
func draw(ls *LinuxStatus) {
ls.group = ls.window.Box().NewGroup("What Linux Knows It Is")
ls.grid = ls.group.NewGrid("gridnuts", 2, 2)
ls.hostnameStatus = gadgets.NewOneLiner(ls.grid, "status")
ls.hostname = gadgets.NewOneLiner(ls.grid, "hostname -f")
ls.hostshort = gadgets.NewOneLiner(ls.grid, "hostname -s")
ls.domainname = gadgets.NewOneLiner(ls.grid, "domain name")
ls.resolver = gadgets.NewOneLiner(ls.grid, "nameservers =")
ls.resolver.SetText("TODO")
ls.uid = gadgets.NewOneLiner(ls.grid, "UID =")
ls.IPv4 = gadgets.NewOneLiner(ls.grid, "Current IPv4 =")
ls.IPv6 = gadgets.NewOneLiner(ls.grid, "Current IPv6 =")
ls.workingIPv4 = gadgets.NewOneLiner(ls.grid, "Real IPv4 =")
ls.workingIPv6 = gadgets.NewOneLiner(ls.grid, "Real IPv6 =")
// ls.nics = gadgets.NewOneLiner(ls.grid, "network intefaces =")
ls.grid.NewLabel("interfaces =")
ls.Interfaces = ls.grid.NewCombobox()
ls.speed = gadgets.NewOneLiner(ls.grid, "refresh speed =")
ls.speedActual = gadgets.NewOneLiner(ls.grid, "refresh speed =")
ls.grid.Margin()
ls.grid.Pad()
}

View File

@ -1,32 +0,0 @@
package main
/*
https://pkg.go.dev/github.com/miekg/dns#section-readme
DYNAMIC UPDATES
Dynamic updates reuses the DNS message format, but renames three of the sections. Question is Zone, Answer is Prerequisite, Authority is Update, only the Additional is not renamed. See RFC 2136 for the gory details.
You can set a rather complex set of rules for the existence of absence of certain resource records or names in a zone to specify if resource records should be added or removed. The table from RFC 2136 supplemented with the Go DNS function shows which functions exist to specify the prerequisites.
3.2.4 - Table Of Metavalues Used In Prerequisite Section
CLASS TYPE RDATA Meaning Function
--------------------------------------------------------------
ANY ANY empty Name is in use dns.NameUsed
ANY rrset empty RRset exists (value indep) dns.RRsetUsed
NONE ANY empty Name is not in use dns.NameNotUsed
NONE rrset empty RRset does not exist dns.RRsetNotUsed
zone rrset rr RRset exists (value dep) dns.Used
The prerequisite section can also be left empty. If you have decided on the prerequisites you can tell what RRs should be added or deleted. The next table shows the options you have and what functions to call.
3.4.2.6 - Table Of Metavalues Used In Update Section
CLASS TYPE RDATA Meaning Function
---------------------------------------------------------------
ANY ANY empty Delete all RRsets from name dns.RemoveName
ANY rrset empty Delete an RRset dns.RemoveRRset
NONE rrset rr Delete an RR from RRset dns.Remove
zone rrset rr Add to an RRset dns.Insert
*/

View File

@ -1,71 +0,0 @@
// This is a simple example
package main
import (
"os"
"log"
"bufio"
"strings"
"go.wit.com/control-panel-dns/cloudflare"
)
func saveConfig() {
log.Println("TODO")
}
func readConfig() {
homeDir, err := os.UserHomeDir()
if err != nil {
log.Println("searchPaths() error. exiting here?")
}
filename := homeDir + "/" + configfile
log.Println("filename =", filename)
readFileLineByLine(filename)
// os.Exit(0)
}
// readFileLineByLine opens a file and reads through each line.
func readFileLineByLine(filename string) error {
// Open the file.
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close()
log.Println("readFileLineByLine() =", filename)
// Create a new Scanner for the file.
scanner := bufio.NewScanner(file)
// Read through each line using scanner.
for scanner.Scan() {
var newc *cloudflare.ConfigT
newc = new(cloudflare.ConfigT)
line := scanner.Text()
parts := strings.Fields(line)
if (len(parts) < 4) {
log.Println("readFileLineByLine() SKIP =", parts)
continue
}
newc.Domain = parts[0]
newc.ZoneID = parts[1]
newc.Auth = parts[2]
newc.Email = parts[3]
cloudflare.Config[parts[0]] = newc
log.Println("readFileLineByLine() =", newc.Domain, newc.ZoneID, newc.Auth, newc.Email)
}
// Check for errors during Scan.
if err := scanner.Err(); err != nil {
return err
}
return nil
}

View File

@ -1,79 +0,0 @@
package main
// Watches for changes to a directory. Works cross-platform
import (
"log"
"github.com/fsnotify/fsnotify"
)
// This would be a really dumb way to watch for new network interfaces
// since it then watches a linux only directory /sys/class/net for changes
func watchSysClassNet() {
// Create new watcher.
watcher, err := fsnotify.NewWatcher()
if err != nil {
debug(LogError, "watchSysClassNet() failed:", err)
return
}
defer watcher.Close()
// Start listening for events.
go func() {
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
log.Println("event:", event)
if event.Has(fsnotify.Write) {
log.Println("modified file:", event.Name)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Println("error:", err)
}
}
}()
// Add a path.
err = watcher.Add("/tmp")
if err != nil {
debug(LogError, "watchSysClassNet() watcher.Add() failed:", err)
return
}
// Block main goroutine forever.
<-make(chan struct{})
}
func fsnotifyNetworkInterfaceChanges() error {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return err
}
defer watcher.Close()
// Watch for network interface changes
err = watcher.Add("/sys/class/net")
if err != nil {
return err
}
for {
select {
case event := <-watcher.Events:
log.Println("fsnotifyNetworkInterfaceChanges() event =", event)
if event.Op&fsnotify.Create == fsnotify.Create {
// Do something on network interface creation
}
case err := <-watcher.Errors:
log.Println("fsnotifyNetworkInterfaceChanges() event err =", err)
return err
}
}
}

View File

@ -1,118 +1,195 @@
// inspired from:
// https://github.com/mactsouk/opensource.com.git
// and
// https://coderwall.com/p/wohavg/creating-a-simple-tcp-server-in-go
package main
// figures out if your hostname is valid
// then checks if your DNS is setup correctly
package linuxstatus
import (
"go.wit.com/shell"
"fmt"
"io/ioutil"
"strings"
"go.wit.com/control-panel-dns/cloudflare"
"go.wit.com/control-panel-dns/dnssecsocket"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
// will try to get this hosts FQDN
"github.com/Showmax/go-fqdn"
)
// will try to get this hosts FQDN
import "github.com/Showmax/go-fqdn"
func (ls *LinuxStatus) GetDomainName() string {
if !me.Ready() {
return ""
}
return me.domainname.String()
}
// this is the king of dns libraries
import "github.com/miekg/dns"
func getHostname() {
var err error
var s string = "gui.Label == nil"
s, err = fqdn.FqdnHostname()
if (err != nil) {
debug(LogError, "FQDN hostname error =", err)
func (ls *LinuxStatus) setDomainName() {
if !me.Ready() {
return
}
if (me.fqdn != nil) {
if (me.hostname != s) {
me.fqdn.SetText(s)
me.hostname = s
me.changed = true
}
}
debug(LogNet, "FQDN =", s)
dn := run("domainname")
if (me.domainname.S != dn) {
debug(LogChange, "domainname has changed from", me.domainname.S, "to", dn)
if me.domainname.String() != dn {
log.Log(CHANGE, "domainname has changed from", me.GetDomainName(), "to", dn)
me.domainname.SetText(dn)
me.changed = true
}
}
func (ls *LinuxStatus) GetHostname() string {
if !me.Ready() {
return ""
}
return me.hostname.String()
}
func (ls *LinuxStatus) ValidHostname() bool {
if !me.Ready() {
log.Info("ValidHostname() not ready")
return false
}
if me.hostnameStatus.String() == "WORKING" {
return true
}
return false
}
func (ls *LinuxStatus) setHostname(newname string) {
if !me.Ready() {
return
}
if newname == me.hostname.String() {
return
}
log.Log(CHANGE, "hostname has changed from", me.GetHostname(), "to", newname)
me.hostname.SetText(newname)
me.changed = true
}
func (ls *LinuxStatus) GetHostShort() string {
if !me.Ready() {
return ""
}
return me.hostshort.String()
}
func (ls *LinuxStatus) setHostShort() {
if !me.Ready() {
return
}
hshort := run("hostname -s")
if (me.hostshort.S != hshort) {
debug(LogChange, "hostname -s has changed from", me.hostshort.S, "to", hshort)
if me.hostshort.String() != hshort {
log.Log(CHANGE, "hostname -s has changed from", me.hostshort.String(), "to", hshort)
me.hostshort.SetText(hshort)
me.changed = true
}
}
// getDomainName extracts the domain name from a given hostname
func getDomainName(hostname string) (string, error) {
parts := strings.Split(hostname, ".")
if len(parts) < 3 {
return "", fmt.Errorf("hostname '%s' is too short to extract a domain name", hostname)
}
// Join all parts except the first one, which is assumed to be a subdomain
domain := strings.Join(parts[1:], ".")
return domain, nil
}
func lookupHostname() {
if !me.Ready() {
return
}
var err error
var hostfqdn string = "broken"
hostfqdn, err = fqdn.FqdnHostname()
if err != nil {
log.Error(err, "FQDN hostname error")
return
}
log.Log(NET, "full hostname should be: ", hostfqdn)
me.setDomainName()
me.setHostShort()
// these are authoritative
// if they work wrong, your linux configuration is wrong.
// Do not complain.
// Fix your distro if your box is otherwise not working this way
hshort := me.GetHostShort() // from `hostname -s`
dn := me.GetDomainName() // from `domanname`
hostname := me.GetHostname() // from `hostname -f`
if hostfqdn != hostname {
log.Log(WARN, "hostname", hostname, "does not equal fqdn.FqdnHostname()", hostfqdn)
// TODO: figure out what is wrong
if dn == "(none)" {
realdn, err := getDomainName(hostfqdn)
if err == nil {
log.Log(WARN, "need to run: 'domainname", realdn, "' here")
me.changed = true
me.hostnameStatus.SetText("FIXING")
shell.Run([]string{"domainname", realdn})
return
} else {
log.Log(WARN, "getDomainName() err =", err)
log.Log(WARN, "/etc/hostname is too short. let the user set the name here.")
// me.changed = true
me.hostnameStatus.SetText("INVALID DOMAIN NAME")
// return
}
}
log.Log(WARN, "don't know what to do here with domainname")
log.Log(WARN, "check that /etc/hostname is valid?")
// me.changed = true
me.hostnameStatus.SetText("UNKNOWN")
// return
}
var test string
test = hshort + "." + dn
if (me.hostname != test) {
debug(LogInfo, "me.hostname", me.hostname, "does not equal", test)
if (me.hostnameStatus.S != "BROKEN") {
debug(LogChange, "me.hostname", me.hostname, "does not equal", test)
me.setHostname(test)
if hostname != test {
log.Log(CHANGE, "hostname", hostname, "does not equal", test)
if me.hostnameStatus.String() != "BROKEN" {
log.Log(CHANGE, "hostname", hostname, "does not equal", test)
me.changed = true
me.hostnameStatus.SetText("BROKEN")
}
} else {
if (me.hostnameStatus.S != "VALID") {
debug(LogChange, "me.hostname", me.hostname, "is valid")
me.hostnameStatus.SetText("VALID")
if me.hostnameStatus.String() != "WORKING" {
log.Log(CHANGE, "hostname", hostname, "is valid")
me.hostnameStatus.SetText("WORKING")
me.changed = true
}
// enable the cloudflare button if the provider is cloudflare
if (me.cloudflareB == nil) {
debug(LogChange, "me.cloudflare == nil; me.DnsAPI.S =", me.DnsAPI.S)
if (me.DnsAPI.S == "cloudflare") {
me.cloudflareB = me.mainStatus.NewButton("cloudflare wit.com", func () {
cloudflare.CreateRR(myGui, "wit.com", "3777302ac4a78cd7fa4f6d3f72086d06")
})
}
}
}
}
// returns true if the hostname is good
// check that all the OS settings are correct here
// On Linux, /etc/hosts, /etc/hostname
// and domainname and hostname
func goodHostname(h string) bool {
hostname := shell.Chomp(shell.Cat("/etc/hostname"))
debug(true, "hostname =", hostname)
//
// and domainname and hostname
func goodHostname() bool {
content, err := ioutil.ReadFile("/etc/hostname")
if err != nil {
// this needs to be a fixWindow() error
log.Error(err)
}
hostname := string(content)
log.Log(NOW, "hostname =", hostname)
hs := run("hostname -s")
dn := run("domainname")
debug(true, "hostname short =", hs, "domainname =", dn)
log.Log(NOW, "hostname short =", hs, "domainname =", dn)
tmp := hs + "." + dn
if (hostname == tmp) {
debug(true, "hostname seems to be good", hostname)
if hostname == tmp {
log.Log(NOW, "hostname seems to be good", hostname)
return true
}
return false
}
func digAAAA(s string) []string {
var aaaa []string
// lookup the IP address from DNS
rrset := dnssecsocket.Dnstrace(s, "AAAA")
// debug(true, args.VerboseDNS, SPEW, rrset)
for i, rr := range rrset {
ipaddr := dns.Field(rr, 1)
// how the hell do you detect a RRSIG AAAA record here?
if (ipaddr == "28") {
continue
}
debug(LogNow, "r.Answer =", i, "rr =", rr, "ipaddr =", ipaddr)
aaaa = append(aaaa, ipaddr)
me.ipv6s[ipaddr] = rr
}
debug(true, args.VerboseDNS, "aaaa =", aaaa)
return aaaa
}

99
linuxloop.go Normal file
View File

@ -0,0 +1,99 @@
// GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
// Copyright (c) 2023 WIT.COM, Inc.
// This is a control panel for DNS
// This is the main Linux kernel / OS code
// to check your network settings are correct
// This does (and should do) no network or external checking
// This is just the state of your OS
package linuxstatus
import (
"io/ioutil"
"os"
"os/user"
"sort"
"strconv"
"strings"
"go.wit.com/log"
)
func linuxLoop() {
me.changed = false
// checks for a VALID hostname
lookupHostname()
if me.changed {
log.Log(CHANGE, "lookupHostname() detected a change")
}
// scans the linux network intefaces for your available IPv4 & IPv6 addresses
scanInterfaces()
if me.changed {
log.Log(CHANGE, "scanInterfaces() detected a change")
}
for i, t := range me.ifmap {
log.Log(NET, strconv.Itoa(i)+" iface = "+t.iface.Name)
}
// get all the real A records from all the network interfaces linux can see
a := realA()
sort.Strings(a)
tmp := strings.Join(a, "\n")
if tmp != me.workingIPv4.String() {
log.Log(CHANGE, "realA() your real IPv6 addresses changed")
me.changed = true
me.workingIPv4.SetText(tmp)
}
// get all the real AAAA records from all the network interfaces linux can see
aaaa := realAAAA()
sort.Strings(aaaa)
tmp = strings.Join(aaaa, "\n")
if tmp != me.workingIPv6.String() {
log.Log(CHANGE, "realAAAA() your real IPv6 addresses changed")
me.changed = true
me.workingIPv6.SetText(tmp)
}
user, _ := user.Current()
tmp = user.Username + " (" + strconv.Itoa(os.Getuid()) + ")"
if tmp != me.uid.String() {
log.Log(CHANGE, "os.Getuid =", user.Username, os.Getuid())
me.changed = true
me.uid.SetText(tmp)
}
content, _ := ioutil.ReadFile("/etc/resolv.conf")
var ns []string
for _, line := range strings.Split(string(content), "\n") {
parts := strings.Split(line, " ")
if len(parts) > 1 {
if parts[0] == "nameserver" {
ns = append(ns, parts[1])
}
}
}
sort.Strings(ns)
newNS := strings.Join(ns, "\n")
if newNS != me.resolver.String() {
log.Log(CHANGE, "resolver changed in /etc/resolv.conf to", ns)
me.changed = true
me.resolver.SetText(newNS)
}
/*
processName := getProcessNameByPort(53)
fmt.Println("Process with port 53:", processName)
commPath := filepath.Join("/proc", proc.Name(), "comm")
comm, err := ioutil.ReadFile(commPath)
if err != nil {
return "", err // Error reading the process name
}
return strings.TrimSpace(string(comm)), nil
*/
}

59
log.go
View File

@ -1,59 +0,0 @@
package main
import (
"log"
"reflect"
witlog "go.wit.com/gui/log"
)
var LogPrefix = "ipv6cp" // ipv6 control panel debugging line
// various debugging flags
var DEBUGON bool = true
var LogNow bool = true // useful for active development
var LogError bool = true // probably always leave this one
var LogChange bool = true // turn on /proc debugging output
var LogInfo bool = false // general info
var LogNet bool = false // general network debugging
var LogProc bool = false // turn on /proc debugging output
var LogExec bool = false // turn on os.Exec() debugging
var SPEW witlog.Spewt
// var log interface{}
/*
func log(a ...any) {
witlog.Where = "wit/gui"
witlog.Log(a...)
}
*/
func sleep(a ...any) {
witlog.Sleep(a...)
}
func exit(a ...any) {
debug(LogError, "got to log() exit")
witlog.Exit(a...)
}
func debug(a ...any) {
if (! DEBUGON) {
return
}
if (a == nil) {
return
}
var tbool bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
if (a[0] == false) {
return
}
a[0] = LogPrefix // ipv6 control panel debugging line
}
log.Println(a...)
}

223
net.go
View File

@ -1,95 +1,69 @@
// This creates a simple hello world window
package main
package linuxstatus
import (
import (
// "log"
"net"
"sort"
"strings"
"go.wit.com/log"
)
// this doesn't work
/*
func watchNetworkInterfaces() {
// Get list of network interfaces
interfaces, _ := net.Interfaces()
// Set up a notification channel
notification := make(chan net.Interface)
debug(LogNet, "watchNet()")
// Start goroutine to watch for changes
go func() {
debug(LogNet, "watchNet() func")
for {
debug(LogNet, "forever loop start")
// Check for changes in each interface
for _, i := range interfaces {
debug(LogNet, "something on i =", i)
if status := i.Flags & net.FlagUp; status != 0 {
notification <- i
debug(LogNet, "something on i =", i)
}
}
debug(LogNet, "forever loop end")
}
}()
}
*/
func IsIPv6(address string) bool {
return strings.Count(address, ":") >= 2
}
func (t *IPtype) IsReal() bool {
if (t.ip.IsPrivate() || t.ip.IsLoopback() || t.ip.IsLinkLocalUnicast()) {
debug(LogNet, "\t\tIP is Real = false")
if t.ip.IsPrivate() || t.ip.IsLoopback() || t.ip.IsLinkLocalUnicast() {
log.Log(NET, "\t\tIP is Real = false")
return false
} else {
debug(LogNet, "\t\tIP is Real = true")
log.Log(NET, "\t\tIP is Real = true")
return true
}
}
func IsReal(ip *net.IP) bool {
if (ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast()) {
debug(LogNet, "\t\tIP is Real = false")
if ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast() {
log.Log(NET, "\t\tIP is Real = false")
return false
} else {
debug(LogNet, "\t\tIP is Real = true")
log.Log(NET, "\t\tIP is Real = true")
return true
}
}
func renameInterface(i *net.Interface) {
/*
/sbin/ip link set eth1 down
/sbin/ip link set eth1 name eth123
/sbin/ip link set eth123 up
/sbin/ip link set eth1 down
/sbin/ip link set eth1 name eth123
/sbin/ip link set eth123 up
*/
}
// Will figure out if an interface was just added
func checkInterface(i net.Interface) {
val, ok := me.ifmap[i.Index]
if ! ok {
debug(i.Name, "is a new network interface. The linux kernel index =", i.Index)
if !ok {
log.Log(INFO, i.Name, "is a new network interface. The linux kernel index =", i.Index)
me.ifmap[i.Index] = new(IFtype)
me.ifmap[i.Index].gone = false
me.ifmap[i.Index].iface = &i
me.changed = true
if (me.Interfaces != nil) {
if me.Interfaces != nil {
me.Interfaces.AddText(i.Name)
me.Interfaces.SetText(i.Name)
}
return
}
me.ifmap[i.Index].gone = false
debug(LogNet, "me.ifmap[i] does exist. Need to compare everything.", i.Index, i.Name, val.iface.Index, val.iface.Name)
if (val.iface.Name != i.Name) {
debug(val.iface.Name, "has changed to it's name to", i.Name)
log.Log(NET, "me.ifmap[i] does exist. Need to compare everything.", i.Index, i.Name, val.iface.Index, val.iface.Name)
if val.iface.Name != i.Name {
log.Log(INFO, val.iface.Name, "has changed to it's name to", i.Name)
me.ifmap[i.Index].iface = &i
me.changed = true
if (me.Interfaces != nil) {
if me.Interfaces != nil {
me.Interfaces.AddText(i.Name)
me.Interfaces.SetText(i.Name)
}
@ -97,12 +71,16 @@ func checkInterface(i net.Interface) {
}
}
/*
These are the real IP address you have been
given from DHCP
*/
func realAAAA() []string {
var aaaa []string
for s, t := range me.ipmap {
if (t.IsReal()) {
if (t.ipv6) {
if t.IsReal() {
if t.ipv6 {
aaaa = append(aaaa, s)
}
}
@ -114,8 +92,8 @@ func realA() []string {
var a []string
for s, t := range me.ipmap {
if (t.IsReal()) {
if (t.ipv4) {
if t.IsReal() {
if t.ipv4 {
a = append(a, s)
}
}
@ -123,7 +101,7 @@ func realA() []string {
return a
}
func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
func checkDNSOld() (map[string]*IPtype, map[string]*IPtype) {
var ipv4s map[string]*IPtype
var ipv6s map[string]*IPtype
@ -133,18 +111,18 @@ func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
for s, t := range me.ipmap {
i := t.iface
ipt := "IPv4"
if (t.ipv6) {
if t.ipv6 {
ipt = "IPv6"
}
if (t.IsReal()) {
debug("\tIP is Real ", ipt, i.Index, i.Name, s)
if (t.ipv6) {
if t.IsReal() {
log.Log(INFO, "\tIP is Real ", ipt, i.Index, i.Name, s)
if t.ipv6 {
ipv6s[s] = t
} else {
ipv4s[s] = t
}
} else {
debug("\tIP is not Real", ipt, i.Index, i.Name, s)
log.Log(INFO, "\tIP is not Real", ipt, i.Index, i.Name, s)
}
}
return ipv6s, ipv4s
@ -152,14 +130,14 @@ func checkDNS() (map[string]*IPtype, map[string]*IPtype) {
// Will figure out if an IP address is new
func checkIP(ip *net.IPNet, i net.Interface) bool {
debug(LogNet, "\t\taddr.(type) = *net.IPNet")
debug(LogNet, "\t\taddr.(type) =", ip)
log.Log(NET, "\t\taddr.(type) = *net.IPNet")
log.Log(NET, "\t\taddr.(type) =", ip)
var realip string
realip = ip.IP.String()
val, ok := me.ipmap[realip]
if ok {
debug(LogNet, val.ipnet.IP.String(), "is already a defined IP address")
log.Log(NET, val.ipnet.IP.String(), "is already a defined IP address")
me.ipmap[realip].gone = false
return false
}
@ -171,91 +149,98 @@ func checkIP(ip *net.IPNet, i net.Interface) bool {
me.ipmap[realip].ip = ip.IP
me.ipmap[realip].iface = &i
t := "IPv4"
if (IsIPv6(ip.String())) {
if IsIPv6(ip.String()) {
me.ipmap[realip].ipv6 = true
me.ipmap[realip].ipv4 = false
t = "IPv6"
if (me.IPv6 != nil) {
if me.IPv6 != nil {
me.IPv6.SetText(realip)
}
} else {
me.ipmap[realip].ipv6 = false
me.ipmap[realip].ipv4 = true
if (me.IPv4 != nil) {
if me.IPv4 != nil {
me.IPv4.SetText(realip)
}
}
if (IsReal(&ip.IP)) {
debug("\tIP is Real ", t, i.Index, i.Name, realip)
if IsReal(&ip.IP) {
log.Log(INFO, "\tIP is Real ", t, i.Index, i.Name, realip)
} else {
debug("\tIP is not Real", t, i.Index, i.Name, realip)
log.Log(INFO, "\tIP is not Real", t, i.Index, i.Name, realip)
}
debug(LogNet, "\t\tIP is IsPrivate() =", ip.IP.IsPrivate())
debug(LogNet, "\t\tIP is IsLoopback() =", ip.IP.IsLoopback())
debug(LogNet, "\t\tIP is IsLinkLocalUnicast() =", ip.IP.IsLinkLocalUnicast())
// debug("HERE HERE", "realip =", realip, "me.ip[realip]=", me.ipmap[realip])
log.Log(NET, "\t\tIP is IsPrivate() =", ip.IP.IsPrivate())
log.Log(NET, "\t\tIP is IsLoopback() =", ip.IP.IsLoopback())
log.Log(NET, "\t\tIP is IsLinkLocalUnicast() =", ip.IP.IsLinkLocalUnicast())
// log.Log(INFO, "HERE HERE", "realip =", realip, "me.ip[realip]=", me.ipmap[realip])
return true
}
func scanInterfaces() {
debug(LogNet, "scanInterfaces() START")
log.Log(NET, "scanInterfaces() START")
ifaces, _ := net.Interfaces()
// me.ifnew = ifaces
debug(LogNet, SPEW, ifaces)
log.Log(NET, SPEW, ifaces)
for _, i := range ifaces {
addrs, _ := i.Addrs()
// debug("range ifaces = ", i)
// log.Log(INFO, "range ifaces = ", i)
checkInterface(i)
debug(LogNet, "*net.Interface.Name = ", i.Name, i.Index)
debug(LogNet, SPEW, i)
debug(LogNet, SPEW, addrs)
log.Log(NET, "*net.Interface.Name = ", i.Name, i.Index)
log.Log(NET, SPEW, i)
log.Log(NET, SPEW, addrs)
for _, addr := range addrs {
debug(LogNet, "\taddr =", addr)
debug(LogNet, SPEW, addrs)
log.Log(NET, "\taddr =", addr)
log.Log(NET, SPEW, addrs)
ips, _ := net.LookupIP(addr.String())
debug(LogNet, "\tLookupIP(addr) =", ips)
log.Log(NET, "\tLookupIP(addr) =", ips)
switch v := addr.(type) {
case *net.IPNet:
if checkIP(v, i) {
debug(true, "scanInterfaces() IP is new () i =", v.IP.String())
log.Log(NET, "scanInterfaces() IP is new () i =", v.IP.String())
}
default:
debug(LogNet, "\t\taddr.(type) = NO IDEA WHAT TO DO HERE v =", v)
log.Log(NET, "\t\taddr.(type) = NO IDEA WHAT TO DO HERE v =", v)
}
}
}
if deleteChanges() {
me.changed = true
debug(LogNow, "deleteChanges() detected network changes")
log.Log(NET, "deleteChanges() detected network changes")
}
updateRealAAAA()
debug(LogNet, "scanInterfaces() END")
log.Log(NET, "scanInterfaces() END")
}
// displays the IP address found on your network interfaces
func updateRealAAAA() {
var all4 string
var all6 string
var all4 []string
var all6 []string
for s, t := range me.ipmap {
if (t.ipv4) {
all4 += s + "\n"
debug(LogNet, "IPv4 =", s)
} else if (t.ipv6) {
all6 += s + "\n"
debug(LogNet, "IPv6 =", s)
if t.ipv4 {
all4 = append(all4, s)
log.Log(NET, "IPv4 =", s)
} else if t.ipv6 {
all6 = append(all6, s)
log.Log(NET, "IPv6 =", s)
} else {
debug(LogNet, "???? =", s)
log.Log(NET, "???? =", s)
}
}
all4 = sortLines(all4)
all6 = sortLines(all6)
if (me.IPv4.S != all4) {
debug(LogNow, "IPv4 addresses have changed", all4)
me.IPv4.SetText(all4)
// sort and create text
sort.Strings(all4)
sort.Strings(all6)
s4 := strings.Join(all4, "\n")
s6 := strings.Join(all6, "\n")
if me.IPv4.String() != s4 {
log.Log(CHANGE, "IPv4 addresses have changed", s4)
me.IPv4.SetText(s4)
me.changed = true
}
if (me.IPv6.S != all6) {
debug(LogNow, "IPv6 addresses have changed", all6)
me.IPv6.SetText(all6)
if me.IPv6.String() != s6 {
log.Log(CHANGE, "IPv6 addresses have changed", s6)
me.IPv6.SetText(s6)
me.changed = true
}
}
@ -263,19 +248,19 @@ func updateRealAAAA() {
func deleteChanges() bool {
var changed bool = false
for i, t := range me.ifmap {
if (t.gone) {
debug(LogChange, "DELETE int =", i, "name =", t.name, t.iface)
if t.gone {
log.Log(CHANGE, "DELETE int =", i, "name =", t.name, t.iface)
delete(me.ifmap, i)
changed = true
}
t.gone = true
}
for s, t := range me.ipmap {
if (t.gone) {
debug(LogChange, "DELETE name =", s, "IPv4 =", t.ipv4)
debug(LogChange, "DELETE name =", s, "IPv6 =", t.ipv6)
debug(LogChange, "DELETE name =", s, "iface =", t.iface)
debug(LogChange, "DELETE name =", s, "ip =", t.ip)
if t.gone {
log.Log(CHANGE, "DELETE name =", s, "IPv4 =", t.ipv4)
log.Log(CHANGE, "DELETE name =", s, "IPv6 =", t.ipv6)
log.Log(CHANGE, "DELETE name =", s, "iface =", t.iface)
log.Log(CHANGE, "DELETE name =", s, "ip =", t.ip)
delete(me.ipmap, s)
changed = true
}
@ -284,3 +269,27 @@ func deleteChanges() bool {
return changed
}
func (ls *LinuxStatus) GetIPv6() []string {
if !me.Ready() {
return nil
}
tmp := me.workingIPv6.String()
return strings.Split(tmp, "\n")
}
func (ls *LinuxStatus) GetIPv4() []string {
if !me.Ready() {
return nil
}
tmp := me.workingIPv4.String()
return strings.Split(tmp, "\n")
}
func (ls *LinuxStatus) GetNameservers() []string {
if !me.Ready() {
return nil
}
tmp := me.resolver.String()
return strings.Split(tmp, "\n")
}

29
new.go Normal file
View File

@ -0,0 +1,29 @@
// This creates a simple hello world window
package linuxstatus
import (
"go.wit.com/log"
"go.wit.com/lib/gadgets"
)
func InitLinuxStatus() *LinuxStatus {
if me != nil {
log.Log(WARN, "You have done New() twice. You can only do this once")
return me
}
me = &LinuxStatus{
hidden: true,
ready: false,
}
me.ifmap = make(map[int]*IFtype)
me.ipmap = make(map[string]*IPtype)
log.Log(WARN, "Creating the Window")
me.window = gadgets.RawBasicWindow("OS Hostname Details")
me.window.Make()
draw(me)
me.ready = true
return me
}

View File

@ -1,33 +0,0 @@
// inspired from:
// https://github.com/mactsouk/opensource.com.git
// and
// https://coderwall.com/p/wohavg/creating-a-simple-tcp-server-in-go
package main
import (
"os"
)
// ./go-nsupdate \
// --tsig-algorithm=hmac-sha512 \
// --tsig-secret="OWh5/ZHIyaz7B8J9m9ZDqZ8448Pke0PTpkYbZmFcOf5a6rEzgmcwrG91u1BHi1/4us+mKKEobDPLw1x6sD+ZJw==" \
// -i eno2 farm001.lab.wit.com
func nsupdate() {
var tsigSecret string
debug(true, "nsupdate() START")
cmd := "go-nsupdate --tsig-algorithm=hmac-sha512"
tsigSecret = os.Getenv("TIG_SECRET")
cmd += " --tig-secret=\"" + tsigSecret + "\""
cmd += " -i wlo1 " + me.hostname
debug(true, "nsupdate() RUN:", cmd)
for s, t := range me.ipmap {
if (t.IsReal()) {
if (t.ipv6) {
debug(true, "nsupdate() found real AAAA =", s, "on iface", t.iface.Name)
}
}
}
}

38
proc.go
View File

@ -1,4 +1,4 @@
package main
package linuxstatus
import (
"io/ioutil"
@ -6,9 +6,11 @@ import (
"path/filepath"
"strconv"
"strings"
"go.wit.com/log"
)
func getProcessNameByPort(port int) string {
func GetProcessNameByPort(port int) string {
// Convert port to hex string
portHex := strconv.FormatInt(int64(port), 16)
@ -18,24 +20,24 @@ func getProcessNameByPort(port int) string {
if err != nil {
return ""
}
// debug(LogProc, "searchProcNet() data:", string(data))
// log.Log(PROC, "searchProcNet() data:", string(data))
lines := strings.Split(string(data), "\n")
for _, line := range lines {
fields := strings.Fields(line)
debug(LogProc, "searchProcNet() portHex:", portHex)
if (len(fields) > 9) {
debug(LogProc, "searchProcNet() fields[9]", fields[9])
log.Log(PROC, "searchProcNet() portHex:", portHex)
if len(fields) > 9 {
log.Log(PROC, "searchProcNet() fields[9]", fields[9])
}
debug(LogProc, "searchProcNet() lines:", line)
log.Log(PROC, "searchProcNet() lines:", line)
if len(fields) > 1 {
parts := strings.Split(fields[1], ":")
if len(parts) > 1 {
// Convert the hexadecimal string to an integer
value, _ := strconv.ParseInt(parts[1], 16, 64)
debug(LogProc, "searchProcNet() value, port =", value, port, "parts[1] =", parts[1])
if (port == int(value)) {
debug(LogProc, "searchProcNet() THIS IS THE LINE:", fields)
log.Log(PROC, "searchProcNet() value, port =", value, port, "parts[1] =", parts[1])
if port == int(value) {
log.Log(PROC, "searchProcNet() THIS IS THE LINE:", fields)
return fields[9]
}
}
@ -50,7 +52,7 @@ func getProcessNameByPort(port int) string {
if inode == "" {
inode = searchProcNet("/proc/net/udp")
}
debug(LogProc, "searchProcNet() inode =", inode)
log.Log(PROC, "searchProcNet() inode =", inode)
// Search for process with the inode
procs, _ := ioutil.ReadDir("/proc")
@ -68,25 +70,25 @@ func getProcessNameByPort(port int) string {
for _, fd := range fds {
fdLink, _ := os.Readlink(filepath.Join(fdPath, fd.Name()))
var s string
s = "socket:["+inode+"]"
s = "socket:[" + inode + "]"
if strings.Contains(fdLink, "socket:[") {
debug(LogProc, "searchProcNet() fdLink has socket:", fdLink)
debug(LogProc, "searchProcNet() proc.Name() =", proc.Name(), "s =", s)
log.Log(PROC, "searchProcNet() fdLink has socket:", fdLink)
log.Log(PROC, "searchProcNet() proc.Name() =", proc.Name(), "s =", s)
}
if strings.Contains(fdLink, "socket:[35452]") {
debug(LogProc, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
log.Log(PROC, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
return proc.Name()
}
if strings.Contains(fdLink, "socket:[35450]") {
debug(LogProc, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
log.Log(PROC, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
return proc.Name()
}
if strings.Contains(fdLink, "socket:[35440]") {
debug(LogProc, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
log.Log(PROC, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
return proc.Name()
}
if strings.Contains(fdLink, "socket:[21303]") {
debug(LogProc, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
log.Log(PROC, "searchProcNet() found proc.Name() =", proc.Name(), fdLink)
// return proc.Name()
}
if strings.Contains(fdLink, "socket:["+inode+"]") {

View File

@ -1,22 +0,0 @@
all:
protoc --version
make dnsmessage.pb.go
clean:
rm -f *.pb.go
dnsmessage.pb.go: dnsmessage.proto
protoc --go_out=. dnsmessage.proto
compile:
protoc --go_out=. *.proto
deps:
apt install golang-goprotobuf-dev
apt install protobuf-compiler
push:
git pull
git add --all
git commit -a -s
git push

View File

@ -1,749 +0,0 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: dnsmessage.proto
package dnsmessage
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type PBDNSMessage_Type int32
const (
PBDNSMessage_DNSQueryType PBDNSMessage_Type = 1
PBDNSMessage_DNSResponseType PBDNSMessage_Type = 2
PBDNSMessage_DNSOutgoingQueryType PBDNSMessage_Type = 3
PBDNSMessage_DNSIncomingResponseType PBDNSMessage_Type = 4
)
var PBDNSMessage_Type_name = map[int32]string{
1: "DNSQueryType",
2: "DNSResponseType",
3: "DNSOutgoingQueryType",
4: "DNSIncomingResponseType",
}
var PBDNSMessage_Type_value = map[string]int32{
"DNSQueryType": 1,
"DNSResponseType": 2,
"DNSOutgoingQueryType": 3,
"DNSIncomingResponseType": 4,
}
func (x PBDNSMessage_Type) Enum() *PBDNSMessage_Type {
p := new(PBDNSMessage_Type)
*p = x
return p
}
func (x PBDNSMessage_Type) String() string {
return proto.EnumName(PBDNSMessage_Type_name, int32(x))
}
func (x *PBDNSMessage_Type) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(PBDNSMessage_Type_value, data, "PBDNSMessage_Type")
if err != nil {
return err
}
*x = PBDNSMessage_Type(value)
return nil
}
func (PBDNSMessage_Type) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 0}
}
type PBDNSMessage_SocketFamily int32
const (
PBDNSMessage_INET PBDNSMessage_SocketFamily = 1
PBDNSMessage_INET6 PBDNSMessage_SocketFamily = 2
)
var PBDNSMessage_SocketFamily_name = map[int32]string{
1: "INET",
2: "INET6",
}
var PBDNSMessage_SocketFamily_value = map[string]int32{
"INET": 1,
"INET6": 2,
}
func (x PBDNSMessage_SocketFamily) Enum() *PBDNSMessage_SocketFamily {
p := new(PBDNSMessage_SocketFamily)
*p = x
return p
}
func (x PBDNSMessage_SocketFamily) String() string {
return proto.EnumName(PBDNSMessage_SocketFamily_name, int32(x))
}
func (x *PBDNSMessage_SocketFamily) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(PBDNSMessage_SocketFamily_value, data, "PBDNSMessage_SocketFamily")
if err != nil {
return err
}
*x = PBDNSMessage_SocketFamily(value)
return nil
}
func (PBDNSMessage_SocketFamily) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 1}
}
type PBDNSMessage_SocketProtocol int32
const (
PBDNSMessage_UDP PBDNSMessage_SocketProtocol = 1
PBDNSMessage_TCP PBDNSMessage_SocketProtocol = 2
)
var PBDNSMessage_SocketProtocol_name = map[int32]string{
1: "UDP",
2: "TCP",
}
var PBDNSMessage_SocketProtocol_value = map[string]int32{
"UDP": 1,
"TCP": 2,
}
func (x PBDNSMessage_SocketProtocol) Enum() *PBDNSMessage_SocketProtocol {
p := new(PBDNSMessage_SocketProtocol)
*p = x
return p
}
func (x PBDNSMessage_SocketProtocol) String() string {
return proto.EnumName(PBDNSMessage_SocketProtocol_name, int32(x))
}
func (x *PBDNSMessage_SocketProtocol) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(PBDNSMessage_SocketProtocol_value, data, "PBDNSMessage_SocketProtocol")
if err != nil {
return err
}
*x = PBDNSMessage_SocketProtocol(value)
return nil
}
func (PBDNSMessage_SocketProtocol) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 2}
}
type PBDNSMessage_PolicyType int32
const (
PBDNSMessage_UNKNOWN PBDNSMessage_PolicyType = 1
PBDNSMessage_QNAME PBDNSMessage_PolicyType = 2
PBDNSMessage_CLIENTIP PBDNSMessage_PolicyType = 3
PBDNSMessage_RESPONSEIP PBDNSMessage_PolicyType = 4
PBDNSMessage_NSDNAME PBDNSMessage_PolicyType = 5
PBDNSMessage_NSIP PBDNSMessage_PolicyType = 6
)
var PBDNSMessage_PolicyType_name = map[int32]string{
1: "UNKNOWN",
2: "QNAME",
3: "CLIENTIP",
4: "RESPONSEIP",
5: "NSDNAME",
6: "NSIP",
}
var PBDNSMessage_PolicyType_value = map[string]int32{
"UNKNOWN": 1,
"QNAME": 2,
"CLIENTIP": 3,
"RESPONSEIP": 4,
"NSDNAME": 5,
"NSIP": 6,
}
func (x PBDNSMessage_PolicyType) Enum() *PBDNSMessage_PolicyType {
p := new(PBDNSMessage_PolicyType)
*p = x
return p
}
func (x PBDNSMessage_PolicyType) String() string {
return proto.EnumName(PBDNSMessage_PolicyType_name, int32(x))
}
func (x *PBDNSMessage_PolicyType) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(PBDNSMessage_PolicyType_value, data, "PBDNSMessage_PolicyType")
if err != nil {
return err
}
*x = PBDNSMessage_PolicyType(value)
return nil
}
func (PBDNSMessage_PolicyType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 3}
}
type PBDNSMessage struct {
Type *PBDNSMessage_Type `protobuf:"varint,1,req,name=type,enum=PBDNSMessage_Type" json:"type,omitempty"`
MessageId []byte `protobuf:"bytes,2,opt,name=messageId" json:"messageId,omitempty"`
ServerIdentity []byte `protobuf:"bytes,3,opt,name=serverIdentity" json:"serverIdentity,omitempty"`
SocketFamily *PBDNSMessage_SocketFamily `protobuf:"varint,4,opt,name=socketFamily,enum=PBDNSMessage_SocketFamily" json:"socketFamily,omitempty"`
SocketProtocol *PBDNSMessage_SocketProtocol `protobuf:"varint,5,opt,name=socketProtocol,enum=PBDNSMessage_SocketProtocol" json:"socketProtocol,omitempty"`
From []byte `protobuf:"bytes,6,opt,name=from" json:"from,omitempty"`
To []byte `protobuf:"bytes,7,opt,name=to" json:"to,omitempty"`
InBytes *uint64 `protobuf:"varint,8,opt,name=inBytes" json:"inBytes,omitempty"`
TimeSec *uint32 `protobuf:"varint,9,opt,name=timeSec" json:"timeSec,omitempty"`
TimeUsec *uint32 `protobuf:"varint,10,opt,name=timeUsec" json:"timeUsec,omitempty"`
Id *uint32 `protobuf:"varint,11,opt,name=id" json:"id,omitempty"`
Question *PBDNSMessage_DNSQuestion `protobuf:"bytes,12,opt,name=question" json:"question,omitempty"`
Response *PBDNSMessage_DNSResponse `protobuf:"bytes,13,opt,name=response" json:"response,omitempty"`
OriginalRequestorSubnet []byte `protobuf:"bytes,14,opt,name=originalRequestorSubnet" json:"originalRequestorSubnet,omitempty"`
RequestorId *string `protobuf:"bytes,15,opt,name=requestorId" json:"requestorId,omitempty"`
InitialRequestId []byte `protobuf:"bytes,16,opt,name=initialRequestId" json:"initialRequestId,omitempty"`
DeviceId []byte `protobuf:"bytes,17,opt,name=deviceId" json:"deviceId,omitempty"`
NewlyObservedDomain *bool `protobuf:"varint,18,opt,name=newlyObservedDomain" json:"newlyObservedDomain,omitempty"`
DeviceName *string `protobuf:"bytes,19,opt,name=deviceName" json:"deviceName,omitempty"`
FromPort *uint32 `protobuf:"varint,20,opt,name=fromPort" json:"fromPort,omitempty"`
ToPort *uint32 `protobuf:"varint,21,opt,name=toPort" json:"toPort,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PBDNSMessage) Reset() { *m = PBDNSMessage{} }
func (m *PBDNSMessage) String() string { return proto.CompactTextString(m) }
func (*PBDNSMessage) ProtoMessage() {}
func (*PBDNSMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0}
}
func (m *PBDNSMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PBDNSMessage.Unmarshal(m, b)
}
func (m *PBDNSMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PBDNSMessage.Marshal(b, m, deterministic)
}
func (m *PBDNSMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_PBDNSMessage.Merge(m, src)
}
func (m *PBDNSMessage) XXX_Size() int {
return xxx_messageInfo_PBDNSMessage.Size(m)
}
func (m *PBDNSMessage) XXX_DiscardUnknown() {
xxx_messageInfo_PBDNSMessage.DiscardUnknown(m)
}
var xxx_messageInfo_PBDNSMessage proto.InternalMessageInfo
func (m *PBDNSMessage) GetType() PBDNSMessage_Type {
if m != nil && m.Type != nil {
return *m.Type
}
return PBDNSMessage_DNSQueryType
}
func (m *PBDNSMessage) GetMessageId() []byte {
if m != nil {
return m.MessageId
}
return nil
}
func (m *PBDNSMessage) GetServerIdentity() []byte {
if m != nil {
return m.ServerIdentity
}
return nil
}
func (m *PBDNSMessage) GetSocketFamily() PBDNSMessage_SocketFamily {
if m != nil && m.SocketFamily != nil {
return *m.SocketFamily
}
return PBDNSMessage_INET
}
func (m *PBDNSMessage) GetSocketProtocol() PBDNSMessage_SocketProtocol {
if m != nil && m.SocketProtocol != nil {
return *m.SocketProtocol
}
return PBDNSMessage_UDP
}
func (m *PBDNSMessage) GetFrom() []byte {
if m != nil {
return m.From
}
return nil
}
func (m *PBDNSMessage) GetTo() []byte {
if m != nil {
return m.To
}
return nil
}
func (m *PBDNSMessage) GetInBytes() uint64 {
if m != nil && m.InBytes != nil {
return *m.InBytes
}
return 0
}
func (m *PBDNSMessage) GetTimeSec() uint32 {
if m != nil && m.TimeSec != nil {
return *m.TimeSec
}
return 0
}
func (m *PBDNSMessage) GetTimeUsec() uint32 {
if m != nil && m.TimeUsec != nil {
return *m.TimeUsec
}
return 0
}
func (m *PBDNSMessage) GetId() uint32 {
if m != nil && m.Id != nil {
return *m.Id
}
return 0
}
func (m *PBDNSMessage) GetQuestion() *PBDNSMessage_DNSQuestion {
if m != nil {
return m.Question
}
return nil
}
func (m *PBDNSMessage) GetResponse() *PBDNSMessage_DNSResponse {
if m != nil {
return m.Response
}
return nil
}
func (m *PBDNSMessage) GetOriginalRequestorSubnet() []byte {
if m != nil {
return m.OriginalRequestorSubnet
}
return nil
}
func (m *PBDNSMessage) GetRequestorId() string {
if m != nil && m.RequestorId != nil {
return *m.RequestorId
}
return ""
}
func (m *PBDNSMessage) GetInitialRequestId() []byte {
if m != nil {
return m.InitialRequestId
}
return nil
}
func (m *PBDNSMessage) GetDeviceId() []byte {
if m != nil {
return m.DeviceId
}
return nil
}
func (m *PBDNSMessage) GetNewlyObservedDomain() bool {
if m != nil && m.NewlyObservedDomain != nil {
return *m.NewlyObservedDomain
}
return false
}
func (m *PBDNSMessage) GetDeviceName() string {
if m != nil && m.DeviceName != nil {
return *m.DeviceName
}
return ""
}
func (m *PBDNSMessage) GetFromPort() uint32 {
if m != nil && m.FromPort != nil {
return *m.FromPort
}
return 0
}
func (m *PBDNSMessage) GetToPort() uint32 {
if m != nil && m.ToPort != nil {
return *m.ToPort
}
return 0
}
type PBDNSMessage_DNSQuestion struct {
QName *string `protobuf:"bytes,1,opt,name=qName" json:"qName,omitempty"`
QType *uint32 `protobuf:"varint,2,opt,name=qType" json:"qType,omitempty"`
QClass *uint32 `protobuf:"varint,3,opt,name=qClass" json:"qClass,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PBDNSMessage_DNSQuestion) Reset() { *m = PBDNSMessage_DNSQuestion{} }
func (m *PBDNSMessage_DNSQuestion) String() string { return proto.CompactTextString(m) }
func (*PBDNSMessage_DNSQuestion) ProtoMessage() {}
func (*PBDNSMessage_DNSQuestion) Descriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 0}
}
func (m *PBDNSMessage_DNSQuestion) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PBDNSMessage_DNSQuestion.Unmarshal(m, b)
}
func (m *PBDNSMessage_DNSQuestion) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PBDNSMessage_DNSQuestion.Marshal(b, m, deterministic)
}
func (m *PBDNSMessage_DNSQuestion) XXX_Merge(src proto.Message) {
xxx_messageInfo_PBDNSMessage_DNSQuestion.Merge(m, src)
}
func (m *PBDNSMessage_DNSQuestion) XXX_Size() int {
return xxx_messageInfo_PBDNSMessage_DNSQuestion.Size(m)
}
func (m *PBDNSMessage_DNSQuestion) XXX_DiscardUnknown() {
xxx_messageInfo_PBDNSMessage_DNSQuestion.DiscardUnknown(m)
}
var xxx_messageInfo_PBDNSMessage_DNSQuestion proto.InternalMessageInfo
func (m *PBDNSMessage_DNSQuestion) GetQName() string {
if m != nil && m.QName != nil {
return *m.QName
}
return ""
}
func (m *PBDNSMessage_DNSQuestion) GetQType() uint32 {
if m != nil && m.QType != nil {
return *m.QType
}
return 0
}
func (m *PBDNSMessage_DNSQuestion) GetQClass() uint32 {
if m != nil && m.QClass != nil {
return *m.QClass
}
return 0
}
type PBDNSMessage_DNSResponse struct {
Rcode *uint32 `protobuf:"varint,1,opt,name=rcode" json:"rcode,omitempty"`
Rrs []*PBDNSMessage_DNSResponse_DNSRR `protobuf:"bytes,2,rep,name=rrs" json:"rrs,omitempty"`
AppliedPolicy *string `protobuf:"bytes,3,opt,name=appliedPolicy" json:"appliedPolicy,omitempty"`
Tags []string `protobuf:"bytes,4,rep,name=tags" json:"tags,omitempty"`
QueryTimeSec *uint32 `protobuf:"varint,5,opt,name=queryTimeSec" json:"queryTimeSec,omitempty"`
QueryTimeUsec *uint32 `protobuf:"varint,6,opt,name=queryTimeUsec" json:"queryTimeUsec,omitempty"`
AppliedPolicyType *PBDNSMessage_PolicyType `protobuf:"varint,7,opt,name=appliedPolicyType,enum=PBDNSMessage_PolicyType" json:"appliedPolicyType,omitempty"`
AppliedPolicyTrigger *string `protobuf:"bytes,8,opt,name=appliedPolicyTrigger" json:"appliedPolicyTrigger,omitempty"`
AppliedPolicyHit *string `protobuf:"bytes,9,opt,name=appliedPolicyHit" json:"appliedPolicyHit,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PBDNSMessage_DNSResponse) Reset() { *m = PBDNSMessage_DNSResponse{} }
func (m *PBDNSMessage_DNSResponse) String() string { return proto.CompactTextString(m) }
func (*PBDNSMessage_DNSResponse) ProtoMessage() {}
func (*PBDNSMessage_DNSResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 1}
}
func (m *PBDNSMessage_DNSResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PBDNSMessage_DNSResponse.Unmarshal(m, b)
}
func (m *PBDNSMessage_DNSResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PBDNSMessage_DNSResponse.Marshal(b, m, deterministic)
}
func (m *PBDNSMessage_DNSResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_PBDNSMessage_DNSResponse.Merge(m, src)
}
func (m *PBDNSMessage_DNSResponse) XXX_Size() int {
return xxx_messageInfo_PBDNSMessage_DNSResponse.Size(m)
}
func (m *PBDNSMessage_DNSResponse) XXX_DiscardUnknown() {
xxx_messageInfo_PBDNSMessage_DNSResponse.DiscardUnknown(m)
}
var xxx_messageInfo_PBDNSMessage_DNSResponse proto.InternalMessageInfo
func (m *PBDNSMessage_DNSResponse) GetRcode() uint32 {
if m != nil && m.Rcode != nil {
return *m.Rcode
}
return 0
}
func (m *PBDNSMessage_DNSResponse) GetRrs() []*PBDNSMessage_DNSResponse_DNSRR {
if m != nil {
return m.Rrs
}
return nil
}
func (m *PBDNSMessage_DNSResponse) GetAppliedPolicy() string {
if m != nil && m.AppliedPolicy != nil {
return *m.AppliedPolicy
}
return ""
}
func (m *PBDNSMessage_DNSResponse) GetTags() []string {
if m != nil {
return m.Tags
}
return nil
}
func (m *PBDNSMessage_DNSResponse) GetQueryTimeSec() uint32 {
if m != nil && m.QueryTimeSec != nil {
return *m.QueryTimeSec
}
return 0
}
func (m *PBDNSMessage_DNSResponse) GetQueryTimeUsec() uint32 {
if m != nil && m.QueryTimeUsec != nil {
return *m.QueryTimeUsec
}
return 0
}
func (m *PBDNSMessage_DNSResponse) GetAppliedPolicyType() PBDNSMessage_PolicyType {
if m != nil && m.AppliedPolicyType != nil {
return *m.AppliedPolicyType
}
return PBDNSMessage_UNKNOWN
}
func (m *PBDNSMessage_DNSResponse) GetAppliedPolicyTrigger() string {
if m != nil && m.AppliedPolicyTrigger != nil {
return *m.AppliedPolicyTrigger
}
return ""
}
func (m *PBDNSMessage_DNSResponse) GetAppliedPolicyHit() string {
if m != nil && m.AppliedPolicyHit != nil {
return *m.AppliedPolicyHit
}
return ""
}
// See exportTypes in https://docs.powerdns.com/recursor/lua-config/protobuf.html#protobufServer
// for the list of supported resource record types.
type PBDNSMessage_DNSResponse_DNSRR struct {
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Type *uint32 `protobuf:"varint,2,opt,name=type" json:"type,omitempty"`
Class *uint32 `protobuf:"varint,3,opt,name=class" json:"class,omitempty"`
Ttl *uint32 `protobuf:"varint,4,opt,name=ttl" json:"ttl,omitempty"`
Rdata []byte `protobuf:"bytes,5,opt,name=rdata" json:"rdata,omitempty"`
Udr *bool `protobuf:"varint,6,opt,name=udr" json:"udr,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PBDNSMessage_DNSResponse_DNSRR) Reset() { *m = PBDNSMessage_DNSResponse_DNSRR{} }
func (m *PBDNSMessage_DNSResponse_DNSRR) String() string { return proto.CompactTextString(m) }
func (*PBDNSMessage_DNSResponse_DNSRR) ProtoMessage() {}
func (*PBDNSMessage_DNSResponse_DNSRR) Descriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{0, 1, 0}
}
func (m *PBDNSMessage_DNSResponse_DNSRR) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PBDNSMessage_DNSResponse_DNSRR.Unmarshal(m, b)
}
func (m *PBDNSMessage_DNSResponse_DNSRR) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PBDNSMessage_DNSResponse_DNSRR.Marshal(b, m, deterministic)
}
func (m *PBDNSMessage_DNSResponse_DNSRR) XXX_Merge(src proto.Message) {
xxx_messageInfo_PBDNSMessage_DNSResponse_DNSRR.Merge(m, src)
}
func (m *PBDNSMessage_DNSResponse_DNSRR) XXX_Size() int {
return xxx_messageInfo_PBDNSMessage_DNSResponse_DNSRR.Size(m)
}
func (m *PBDNSMessage_DNSResponse_DNSRR) XXX_DiscardUnknown() {
xxx_messageInfo_PBDNSMessage_DNSResponse_DNSRR.DiscardUnknown(m)
}
var xxx_messageInfo_PBDNSMessage_DNSResponse_DNSRR proto.InternalMessageInfo
func (m *PBDNSMessage_DNSResponse_DNSRR) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *PBDNSMessage_DNSResponse_DNSRR) GetType() uint32 {
if m != nil && m.Type != nil {
return *m.Type
}
return 0
}
func (m *PBDNSMessage_DNSResponse_DNSRR) GetClass() uint32 {
if m != nil && m.Class != nil {
return *m.Class
}
return 0
}
func (m *PBDNSMessage_DNSResponse_DNSRR) GetTtl() uint32 {
if m != nil && m.Ttl != nil {
return *m.Ttl
}
return 0
}
func (m *PBDNSMessage_DNSResponse_DNSRR) GetRdata() []byte {
if m != nil {
return m.Rdata
}
return nil
}
func (m *PBDNSMessage_DNSResponse_DNSRR) GetUdr() bool {
if m != nil && m.Udr != nil {
return *m.Udr
}
return false
}
type PBDNSMessageList struct {
Msg []*PBDNSMessage `protobuf:"bytes,1,rep,name=msg" json:"msg,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *PBDNSMessageList) Reset() { *m = PBDNSMessageList{} }
func (m *PBDNSMessageList) String() string { return proto.CompactTextString(m) }
func (*PBDNSMessageList) ProtoMessage() {}
func (*PBDNSMessageList) Descriptor() ([]byte, []int) {
return fileDescriptor_c3136ceafbfed9e7, []int{1}
}
func (m *PBDNSMessageList) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_PBDNSMessageList.Unmarshal(m, b)
}
func (m *PBDNSMessageList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_PBDNSMessageList.Marshal(b, m, deterministic)
}
func (m *PBDNSMessageList) XXX_Merge(src proto.Message) {
xxx_messageInfo_PBDNSMessageList.Merge(m, src)
}
func (m *PBDNSMessageList) XXX_Size() int {
return xxx_messageInfo_PBDNSMessageList.Size(m)
}
func (m *PBDNSMessageList) XXX_DiscardUnknown() {
xxx_messageInfo_PBDNSMessageList.DiscardUnknown(m)
}
var xxx_messageInfo_PBDNSMessageList proto.InternalMessageInfo
func (m *PBDNSMessageList) GetMsg() []*PBDNSMessage {
if m != nil {
return m.Msg
}
return nil
}
func init() {
proto.RegisterEnum("PBDNSMessage_Type", PBDNSMessage_Type_name, PBDNSMessage_Type_value)
proto.RegisterEnum("PBDNSMessage_SocketFamily", PBDNSMessage_SocketFamily_name, PBDNSMessage_SocketFamily_value)
proto.RegisterEnum("PBDNSMessage_SocketProtocol", PBDNSMessage_SocketProtocol_name, PBDNSMessage_SocketProtocol_value)
proto.RegisterEnum("PBDNSMessage_PolicyType", PBDNSMessage_PolicyType_name, PBDNSMessage_PolicyType_value)
proto.RegisterType((*PBDNSMessage)(nil), "PBDNSMessage")
proto.RegisterType((*PBDNSMessage_DNSQuestion)(nil), "PBDNSMessage.DNSQuestion")
proto.RegisterType((*PBDNSMessage_DNSResponse)(nil), "PBDNSMessage.DNSResponse")
proto.RegisterType((*PBDNSMessage_DNSResponse_DNSRR)(nil), "PBDNSMessage.DNSResponse.DNSRR")
proto.RegisterType((*PBDNSMessageList)(nil), "PBDNSMessageList")
}
func init() {
proto.RegisterFile("dnsmessage.proto", fileDescriptor_c3136ceafbfed9e7)
}
var fileDescriptor_c3136ceafbfed9e7 = []byte{
// 836 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x54, 0xdd, 0x8f, 0xdb, 0xc4,
0x17, 0x95, 0x3f, 0xb2, 0x49, 0x6e, 0xec, 0xd4, 0x9d, 0xcd, 0xef, 0xd7, 0x21, 0x54, 0xd4, 0x0a,
0xa8, 0xb2, 0x78, 0x58, 0x41, 0x10, 0x88, 0x27, 0x24, 0xba, 0x49, 0x85, 0x45, 0xeb, 0xf5, 0x8e,
0xb3, 0x42, 0x3c, 0xba, 0xf6, 0x60, 0x8d, 0x48, 0x3c, 0x59, 0x7b, 0x52, 0x94, 0x27, 0x84, 0xf8,
0xc7, 0xd1, 0x5c, 0xe7, 0xc3, 0xee, 0xee, 0xbe, 0xdd, 0x73, 0xee, 0xb9, 0xc7, 0x9e, 0x7b, 0xef,
0x0c, 0x78, 0x79, 0x59, 0x6f, 0x78, 0x5d, 0xa7, 0x05, 0xbf, 0xda, 0x56, 0x52, 0xc9, 0xd9, 0x3f,
0x2e, 0x38, 0xf1, 0x9b, 0x45, 0x94, 0xbc, 0x6f, 0x68, 0xf2, 0x1a, 0x6c, 0xb5, 0xdf, 0x72, 0x6a,
0xf8, 0x66, 0x30, 0x9e, 0x93, 0xab, 0x76, 0xf2, 0x6a, 0xb5, 0xdf, 0x72, 0x86, 0x79, 0xf2, 0x12,
0x86, 0x07, 0xa7, 0x30, 0xa7, 0xa6, 0x6f, 0x04, 0x0e, 0x3b, 0x13, 0xe4, 0x35, 0x8c, 0x6b, 0x5e,
0x7d, 0xe4, 0x55, 0x98, 0xf3, 0x52, 0x09, 0xb5, 0xa7, 0x16, 0x4a, 0x3e, 0x61, 0xc9, 0x4f, 0xe0,
0xd4, 0x32, 0xfb, 0x93, 0xab, 0xb7, 0xe9, 0x46, 0xac, 0xf7, 0xd4, 0xf6, 0x8d, 0x60, 0x3c, 0x9f,
0x76, 0xbf, 0x9a, 0xb4, 0x14, 0xac, 0xa3, 0x27, 0x0b, 0x18, 0x37, 0x38, 0xd6, 0xa7, 0xc9, 0xe4,
0x9a, 0xf6, 0xd0, 0xe1, 0xe5, 0x63, 0x0e, 0x47, 0x0d, 0xfb, 0xa4, 0x86, 0x10, 0xb0, 0xff, 0xa8,
0xe4, 0x86, 0x5e, 0xe0, 0x3f, 0x62, 0x4c, 0xc6, 0x60, 0x2a, 0x49, 0xfb, 0xc8, 0x98, 0x4a, 0x12,
0x0a, 0x7d, 0x51, 0xbe, 0xd9, 0x2b, 0x5e, 0xd3, 0x81, 0x6f, 0x04, 0x36, 0x3b, 0x42, 0x9d, 0x51,
0x62, 0xc3, 0x13, 0x9e, 0xd1, 0xa1, 0x6f, 0x04, 0x2e, 0x3b, 0x42, 0x32, 0x85, 0x81, 0x0e, 0xef,
0x6a, 0x9e, 0x51, 0xc0, 0xd4, 0x09, 0x6b, 0x7f, 0x91, 0xd3, 0x11, 0xb2, 0xa6, 0xc8, 0xc9, 0xf7,
0x30, 0xb8, 0xdf, 0xf1, 0x5a, 0x09, 0x59, 0x52, 0xc7, 0x37, 0x82, 0xd1, 0xfc, 0xb3, 0xee, 0x19,
0x16, 0x51, 0x72, 0x7b, 0x10, 0xb0, 0x93, 0x54, 0x97, 0x55, 0xbc, 0xde, 0xca, 0xb2, 0xe6, 0xd4,
0x7d, 0xa2, 0x8c, 0x1d, 0x04, 0xec, 0x24, 0x25, 0x3f, 0xc2, 0x0b, 0x59, 0x89, 0x42, 0x94, 0xe9,
0x9a, 0x71, 0x34, 0x93, 0x55, 0xb2, 0xfb, 0x50, 0x72, 0x45, 0xc7, 0x78, 0xe4, 0xa7, 0xd2, 0xc4,
0x87, 0x51, 0x75, 0xa4, 0xc2, 0x9c, 0x3e, 0xf3, 0x8d, 0x60, 0xc8, 0xda, 0x14, 0xf9, 0x1a, 0x3c,
0x51, 0x0a, 0x25, 0x4e, 0xb5, 0x61, 0x4e, 0x3d, 0x34, 0x7d, 0xc0, 0xeb, 0x0e, 0xe5, 0xfc, 0xa3,
0xc8, 0xf4, 0x12, 0x3d, 0x47, 0xcd, 0x09, 0x93, 0x6f, 0xe0, 0xb2, 0xe4, 0x7f, 0xad, 0xf7, 0x37,
0x1f, 0x70, 0x69, 0xf2, 0x85, 0xdc, 0xa4, 0xa2, 0xa4, 0xc4, 0x37, 0x82, 0x01, 0x7b, 0x2c, 0x45,
0xbe, 0x00, 0x68, 0xaa, 0xa3, 0x74, 0xc3, 0xe9, 0x25, 0xfe, 0x5a, 0x8b, 0xd1, 0x5f, 0xd3, 0xb3,
0x8d, 0x65, 0xa5, 0xe8, 0xa4, 0x99, 0xc7, 0x11, 0x93, 0xff, 0xc3, 0x85, 0x92, 0x98, 0xf9, 0x1f,
0x66, 0x0e, 0x68, 0x7a, 0x0b, 0xa3, 0x56, 0xe7, 0xc9, 0x04, 0x7a, 0xf7, 0xe8, 0x6e, 0xa0, 0x7b,
0x03, 0x90, 0xd5, 0x77, 0x03, 0x2f, 0x82, 0xcb, 0x1a, 0xa0, 0x2d, 0xef, 0xaf, 0xd7, 0x69, 0x5d,
0xe3, 0xf2, 0xbb, 0xec, 0x80, 0xa6, 0xff, 0xda, 0xe8, 0x79, 0x1c, 0x8b, 0xae, 0xae, 0x32, 0x99,
0x37, 0x9e, 0x2e, 0x6b, 0x00, 0xf9, 0x16, 0xac, 0xaa, 0xaa, 0xa9, 0xe9, 0x5b, 0xc1, 0x68, 0xfe,
0xea, 0xc9, 0xa1, 0x62, 0xcc, 0x98, 0xd6, 0x92, 0xaf, 0xc0, 0x4d, 0xb7, 0xdb, 0xb5, 0xe0, 0x79,
0x2c, 0xd7, 0x22, 0x6b, 0x2e, 0xdd, 0x90, 0x75, 0x49, 0xbd, 0xed, 0x2a, 0x2d, 0x6a, 0x6a, 0xfb,
0x56, 0x30, 0x64, 0x18, 0x93, 0x19, 0x38, 0xf7, 0x3b, 0x5e, 0xed, 0x57, 0x87, 0x45, 0xee, 0xe1,
0x9f, 0x74, 0x38, 0xed, 0x7e, 0xc2, 0xb8, 0xd2, 0x17, 0x28, 0xea, 0x92, 0xe4, 0x2d, 0x3c, 0xef,
0x7c, 0x0e, 0xdb, 0xd2, 0xc7, 0x4b, 0x49, 0xbb, 0x87, 0x38, 0xe7, 0xd9, 0xc3, 0x12, 0x32, 0x87,
0x49, 0x97, 0xac, 0x44, 0x51, 0xf0, 0x0a, 0x2f, 0xdf, 0x90, 0x3d, 0x9a, 0xd3, 0x9b, 0xd7, 0xe1,
0x7f, 0x11, 0x0a, 0xaf, 0xe4, 0x90, 0x3d, 0xe0, 0xa7, 0x7f, 0x43, 0x0f, 0x3b, 0xa7, 0xdb, 0x51,
0x9e, 0x07, 0x8a, 0x31, 0xb6, 0xe8, 0x3c, 0xce, 0xe6, 0xc1, 0x9b, 0x40, 0x2f, 0x6b, 0x0d, 0xb3,
0x01, 0xc4, 0x03, 0x4b, 0xa9, 0x35, 0xbe, 0x5b, 0x2e, 0xd3, 0x21, 0x4e, 0x33, 0x4f, 0x55, 0x8a,
0x3d, 0x74, 0x58, 0x03, 0xb4, 0x6e, 0x97, 0x57, 0xd8, 0xb2, 0x01, 0xd3, 0xe1, 0x2c, 0x07, 0x1b,
0x0f, 0xea, 0x81, 0xd3, 0x2c, 0x58, 0x85, 0x07, 0xf7, 0x0c, 0x72, 0x09, 0xcf, 0x5a, 0x03, 0x46,
0xd2, 0x24, 0x14, 0x26, 0x8b, 0x28, 0xb9, 0xd9, 0xa9, 0x42, 0x8a, 0xb2, 0x38, 0xcb, 0x2d, 0xf2,
0x39, 0xbc, 0x58, 0x44, 0x49, 0x58, 0x66, 0x72, 0x23, 0xca, 0xa2, 0x53, 0x66, 0xcf, 0xbe, 0x04,
0xa7, 0xfd, 0x7c, 0x92, 0x01, 0xd8, 0x61, 0xb4, 0x5c, 0x79, 0x06, 0x19, 0x42, 0x4f, 0x47, 0x3f,
0x78, 0xe6, 0x6c, 0x06, 0xe3, 0xee, 0x0b, 0x49, 0xfa, 0x60, 0xdd, 0x2d, 0x62, 0xcf, 0xd0, 0xc1,
0xea, 0x3a, 0xf6, 0xcc, 0xd9, 0xef, 0x00, 0xad, 0xe9, 0x8c, 0xa0, 0x7f, 0x17, 0xfd, 0x1a, 0xdd,
0xfc, 0x16, 0x35, 0x4e, 0xb7, 0xd1, 0xcf, 0xef, 0x97, 0x9e, 0x49, 0x1c, 0x18, 0x5c, 0xbf, 0x0b,
0x97, 0xd1, 0x2a, 0x8c, 0x3d, 0x8b, 0x8c, 0x01, 0xd8, 0x32, 0x89, 0x6f, 0xa2, 0x64, 0x19, 0xc6,
0x9e, 0xad, 0xab, 0xa2, 0x64, 0x81, 0xd2, 0x9e, 0xfe, 0x93, 0x28, 0x09, 0x63, 0xef, 0x62, 0xf6,
0x1d, 0x78, 0xed, 0xc5, 0x78, 0x27, 0x6a, 0x45, 0x5e, 0x81, 0xb5, 0xa9, 0x0b, 0x6a, 0xe0, 0xf6,
0xbb, 0x9d, 0xc5, 0x61, 0x3a, 0xf3, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3d, 0x56, 0xce, 0x98,
0xcb, 0x06, 0x00, 0x00,
}

View File

@ -1,105 +0,0 @@
/*
* This file describes the message format used by the protobuf logging feature in PowerDNS and dnsdist.
*
* MIT License
*
* Copyright (c) 2016-now PowerDNS.COM B.V. and its contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
syntax = "proto2";
message PBDNSMessage {
enum Type {
DNSQueryType = 1; // Query received by the service
DNSResponseType = 2; // Response returned by the service
DNSOutgoingQueryType = 3; // Query sent out by the service to a remote server
DNSIncomingResponseType = 4; // Response returned by the remote server
}
enum SocketFamily {
INET = 1; // IPv4 (RFC 791)
INET6 = 2; // IPv6 (RFC 2460)
}
enum SocketProtocol {
UDP = 1; // User Datagram Protocol (RFC 768)
TCP = 2; // Transmission Control Protocol (RFC 793)
}
enum PolicyType {
UNKNOWN = 1; // No RPZ policy applied, or unknown type
QNAME = 2; // Policy matched on the QName
CLIENTIP = 3; // Policy matched on the client IP
RESPONSEIP = 4; // Policy matched on one of the IPs contained in the answer
NSDNAME = 5; // Policy matched on the name of one nameserver involved
NSIP = 6; // Policy matched on the IP of one nameserver involved
}
required Type type = 1; // Type of event
optional bytes messageId = 2; // UUID, shared by the query and the response
optional bytes serverIdentity = 3; // ID of the server emitting the protobuf message
optional SocketFamily socketFamily = 4;
optional SocketProtocol socketProtocol = 5;
optional bytes from = 6; // DNS requestor (client) as 4 (IPv4) or 16 (IPv6) raw bytes in network byte order
optional bytes to = 7; // DNS responder (server) as 4 (IPv4) or 16 (IPv6) raw bytes in network byte order
optional uint64 inBytes = 8; // Size of the query or response on the wire
optional uint32 timeSec = 9; // Time of message reception (seconds since epoch)
optional uint32 timeUsec = 10; // Time of message reception (additional micro-seconds)
optional uint32 id = 11; // ID of the query/response as found in the DNS header
message DNSQuestion {
optional string qName = 1; // Fully qualified DNS name (with trailing dot)
optional uint32 qType = 2; // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
optional uint32 qClass = 3; // Typically 1 (IN), see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
}
optional DNSQuestion question = 12; // DNS query received from client
message DNSResponse {
// See exportTypes in https://docs.powerdns.com/recursor/lua-config/protobuf.html#protobufServer
// for the list of supported resource record types.
message DNSRR {
optional string name = 1; // Fully qualified DNS name (with trailing dot)
optional uint32 type = 2; // https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
optional uint32 class = 3; // Typically 1 (IN), see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
optional uint32 ttl = 4; // TTL in seconds
optional bytes rdata = 5; // raw address bytes in network byte order for A & AAAA; text representation for others, with fully qualified (trailing dot) domain names
optional bool udr = 6; // True if this is the first time this RR has been seen for this question
}
optional uint32 rcode = 1; // DNS Response code, or 65536 for a network error including a timeout
repeated DNSRR rrs = 2; // DNS resource records in response
optional string appliedPolicy = 3; // Filtering policy (RPZ or Lua) applied
repeated string tags = 4; // Additional tags applied
optional uint32 queryTimeSec = 5; // Time of the corresponding query reception (seconds since epoch)
optional uint32 queryTimeUsec = 6; // Time of the corresponding query reception (additional micro-seconds)
optional PolicyType appliedPolicyType = 7; // Type of the filtering policy (RPZ or Lua) applied
optional string appliedPolicyTrigger = 8; // The RPZ trigger
optional string appliedPolicyHit = 9; // The value (qname or IP) that caused the hit
}
optional DNSResponse response = 13;
optional bytes originalRequestorSubnet = 14; // EDNS Client Subnet value (4 or 16 raw bytes in network byte order)
optional string requestorId = 15; // Username of the requestor
optional bytes initialRequestId = 16; // UUID of the incoming query that initiated this outgoing query or incoming response
optional bytes deviceId = 17; // Device ID of the requestor (could be mac address IP address or e.g. IMEI, format implementation dependent)
optional bool newlyObservedDomain = 18; // True if the domain has not been seen before
optional string deviceName = 19; // Device name of the requestor
optional uint32 fromPort = 20; // Source port of the DNS query (client)
optional uint32 toPort = 21; // Destination port of the DNS query (server)
}
message PBDNSMessageList {
repeated PBDNSMessage msg = 1;
}

View File

@ -1,262 +0,0 @@
// dnstap: flexible, structured event replication format for DNS software
//
// This file contains the protobuf schemas for the "dnstap" structured event
// replication format for DNS software.
// Written in 2013-2014 by Farsight Security, Inc.
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this file to the public
// domain worldwide. This file is distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along
// with this file. If not, see:
//
// <http://creativecommons.org/publicdomain/zero/1.0/>.
package dnstap;
// "Dnstap": this is the top-level dnstap type, which is a "union" type that
// contains other kinds of dnstap payloads, although currently only one type
// of dnstap payload is defined.
// See: https://developers.google.com/protocol-buffers/docs/techniques#union
message Dnstap {
// DNS server identity.
// If enabled, this is the identity string of the DNS server which generated
// this message. Typically this would be the same string as returned by an
// "NSID" (RFC 5001) query.
optional bytes identity = 1;
// DNS server version.
// If enabled, this is the version string of the DNS server which generated
// this message. Typically this would be the same string as returned by a
// "version.bind" query.
optional bytes version = 2;
// Extra data for this payload.
// This field can be used for adding an arbitrary byte-string annotation to
// the payload. No encoding or interpretation is applied or enforced.
optional bytes extra = 3;
// Identifies which field below is filled in.
enum Type {
MESSAGE = 1;
}
required Type type = 15;
// One of the following will be filled in.
optional Message message = 14;
}
// SocketFamily: the network protocol family of a socket. This specifies how
// to interpret "network address" fields.
enum SocketFamily {
INET = 1; // IPv4 (RFC 791)
INET6 = 2; // IPv6 (RFC 2460)
}
// SocketProtocol: the transport protocol of a socket. This specifies how to
// interpret "transport port" fields.
enum SocketProtocol {
UDP = 1; // User Datagram Protocol (RFC 768)
TCP = 2; // Transmission Control Protocol (RFC 793)
}
// Message: a wire-format (RFC 1035 section 4) DNS message and associated
// metadata. Applications generating "Message" payloads should follow
// certain requirements based on the MessageType, see below.
message Message {
// There are eight types of "Message" defined that correspond to the
// four arrows in the following diagram, slightly modified from RFC 1035
// section 2:
// +---------+ +----------+ +--------+
// | | query | | query | |
// | Stub |-SQ--------CQ->| Recursive|-RQ----AQ->| Auth. |
// | Resolver| | Server | | Name |
// | |<-SR--------CR-| |<-RR----AR-| Server |
// +---------+ response | | response | |
// +----------+ +--------+
// Each arrow has two Type values each, one for each "end" of each arrow,
// because these are considered to be distinct events. Each end of each
// arrow on the diagram above has been marked with a two-letter Type
// mnemonic. Clockwise from upper left, these mnemonic values are:
//
// SQ: STUB_QUERY
// CQ: CLIENT_QUERY
// RQ: RESOLVER_QUERY
// AQ: AUTH_QUERY
// AR: AUTH_RESPONSE
// RR: RESOLVER_RESPONSE
// CR: CLIENT_RESPONSE
// SR: STUB_RESPONSE
// Two additional types of "Message" have been defined for the
// "forwarding" case where an upstream DNS server is responsible for
// further recursion. These are not shown on the diagram above, but have
// the following mnemonic values:
// FQ: FORWARDER_QUERY
// FR: FORWARDER_RESPONSE
// The "Message" Type values are defined below.
enum Type {
// AUTH_QUERY is a DNS query message received from a resolver by an
// authoritative name server, from the perspective of the authorative
// name server.
AUTH_QUERY = 1;
// AUTH_RESPONSE is a DNS response message sent from an authoritative
// name server to a resolver, from the perspective of the authoritative
// name server.
AUTH_RESPONSE = 2;
// RESOLVER_QUERY is a DNS query message sent from a resolver to an
// authoritative name server, from the perspective of the resolver.
// Resolvers typically clear the RD (recursion desired) bit when
// sending queries.
RESOLVER_QUERY = 3;
// RESOLVER_RESPONSE is a DNS response message received from an
// authoritative name server by a resolver, from the perspective of
// the resolver.
RESOLVER_RESPONSE = 4;
// CLIENT_QUERY is a DNS query message sent from a client to a DNS
// server which is expected to perform further recursion, from the
// perspective of the DNS server. The client may be a stub resolver or
// forwarder or some other type of software which typically sets the RD
// (recursion desired) bit when querying the DNS server. The DNS server
// may be a simple forwarding proxy or it may be a full recursive
// resolver.
CLIENT_QUERY = 5;
// CLIENT_RESPONSE is a DNS response message sent from a DNS server to
// a client, from the perspective of the DNS server. The DNS server
// typically sets the RA (recursion available) bit when responding.
CLIENT_RESPONSE = 6;
// FORWARDER_QUERY is a DNS query message sent from a downstream DNS
// server to an upstream DNS server which is expected to perform
// further recursion, from the perspective of the downstream DNS
// server.
FORWARDER_QUERY = 7;
// FORWARDER_RESPONSE is a DNS response message sent from an upstream
// DNS server performing recursion to a downstream DNS server, from the
// perspective of the downstream DNS server.
FORWARDER_RESPONSE = 8;
// STUB_QUERY is a DNS query message sent from a stub resolver to a DNS
// server, from the perspective of the stub resolver.
STUB_QUERY = 9;
// STUB_RESPONSE is a DNS response message sent from a DNS server to a
// stub resolver, from the perspective of the stub resolver.
STUB_RESPONSE = 10;
}
// One of the Type values described above.
required Type type = 1;
// One of the SocketFamily values described above.
optional SocketFamily socket_family = 2;
// One of the SocketProtocol values described above.
optional SocketProtocol socket_protocol = 3;
// The network address of the message initiator.
// For SocketFamily INET, this field is 4 octets (IPv4 address).
// For SocketFamily INET6, this field is 16 octets (IPv6 address).
optional bytes query_address = 4;
// The network address of the message responder.
// For SocketFamily INET, this field is 4 octets (IPv4 address).
// For SocketFamily INET6, this field is 16 octets (IPv6 address).
optional bytes response_address = 5;
// The transport port of the message initiator.
// This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
optional uint32 query_port = 6;
// The transport port of the message responder.
// This is a 16-bit UDP or TCP port number, depending on SocketProtocol.
optional uint32 response_port = 7;
// The time at which the DNS query message was sent or received, depending
// on whether this is an AUTH_QUERY, RESOLVER_QUERY, or CLIENT_QUERY.
// This is the number of seconds since the UNIX epoch.
optional uint64 query_time_sec = 8;
// The time at which the DNS query message was sent or received.
// This is the seconds fraction, expressed as a count of nanoseconds.
optional fixed32 query_time_nsec = 9;
// The initiator's original wire-format DNS query message, verbatim.
optional bytes query_message = 10;
// The "zone" or "bailiwick" pertaining to the DNS query message.
// This is a wire-format DNS domain name.
optional bytes query_zone = 11;
// The time at which the DNS response message was sent or received,
// depending on whether this is an AUTH_RESPONSE, RESOLVER_RESPONSE, or
// CLIENT_RESPONSE.
// This is the number of seconds since the UNIX epoch.
optional uint64 response_time_sec = 12;
// The time at which the DNS response message was sent or received.
// This is the seconds fraction, expressed as a count of nanoseconds.
optional fixed32 response_time_nsec = 13;
// The responder's original wire-format DNS response message, verbatim.
optional bytes response_message = 14;
}
// All fields except for 'type' in the Message schema are optional.
// It is recommended that at least the following fields be filled in for
// particular types of Messages.
// AUTH_QUERY:
// socket_family, socket_protocol
// query_address, query_port
// query_message
// query_time_sec, query_time_nsec
// AUTH_RESPONSE:
// socket_family, socket_protocol
// query_address, query_port
// query_time_sec, query_time_nsec
// response_message
// response_time_sec, response_time_nsec
// RESOLVER_QUERY:
// socket_family, socket_protocol
// query_name, query_type, query_class
// query_message
// query_time_sec, query_time_nsec
// query_zone
// response_address, response_port
// RESOLVER_RESPONSE:
// socket_family, socket_protocol
// query_name, query_type, query_class
// query_time_sec, query_time_nsec
// query_zone
// response_address, response_port
// response_message
// response_time_sec, response_time_nsec
// CLIENT_QUERY:
// socket_family, socket_protocol
// query_message
// query_time_sec, query_time_nsec
// CLIENT_RESPONSE:
// socket_family, socket_protocol
// query_time_sec, query_time_nsec
// response_message
// response_time_sec, response_time_nsec

View File

@ -1,26 +0,0 @@
package main
import (
"log"
"github.com/jsimonetti/rtnetlink"
)
// List all interfaces
func Example_listLink() {
// Dial a connection to the rtnetlink socket
conn, err := rtnetlink.Dial(nil)
if err != nil {
debug(LogError, "Example_listLink() failed", err)
return
}
defer conn.Close()
// Request a list of interfaces
msg, err := conn.Link.List()
if err != nil {
log.Println(err)
}
log.Println("%#v", msg)
log.Println(SPEW, msg)
}

61
structs.go Normal file
View File

@ -0,0 +1,61 @@
/*
figures out if your hostname is valid
then checks if your DNS is setup correctly
*/
package linuxstatus
import (
"net"
"go.wit.com/gui"
"go.wit.com/lib/gadgets"
)
var me *LinuxStatus
type LinuxStatus struct {
ready bool
hidden bool
changed bool
parent *gui.Node
ifmap map[int]*IFtype // the current interfaces
ipmap map[string]*IPtype // the current ip addresses
window *gadgets.BasicWindow
group *gui.Node
grid *gui.Node
hostnameStatus *gadgets.OneLiner
hostname *gadgets.OneLiner
hostshort *gadgets.OneLiner
domainname *gadgets.OneLiner
resolver *gadgets.OneLiner
uid *gadgets.OneLiner
IPv4 *gadgets.OneLiner
IPv6 *gadgets.OneLiner
workingIPv4 *gadgets.OneLiner
workingIPv6 *gadgets.OneLiner
Interfaces *gui.Node
speed *gadgets.OneLiner
speedActual *gadgets.OneLiner
}
type IPtype struct {
gone bool // used to track if the ip exists
ipv6 bool // the future
ipv4 bool // the past
LinkLocal bool
iface *net.Interface
ip net.IP
ipnet *net.IPNet
}
type IFtype struct {
gone bool // used to track if the interface exists
name string // just a shortcut to the name. maybe this is dumb
// up bool // could be used to track ifup/ifdown
iface *net.Interface
}

38
timer.go Normal file
View File

@ -0,0 +1,38 @@
package linuxstatus
import (
"sort"
"strings"
"time"
)
// timeFunction takes a function as an argument and returns the execution time.
func timeFunction(f func()) time.Duration {
startTime := time.Now() // Record the start time
f() // Execute the function
return time.Since(startTime) // Calculate the elapsed time
}
// sortLines takes a string, splits it on newlines, sorts the lines,
// and rejoins them with newlines.
func sortLines(input string) string {
lines := strings.Split(input, "\n")
// Trim leading and trailing whitespace from each line
for i, line := range lines {
lines[i] = strings.TrimSpace(line)
}
sort.Strings(lines)
tmp := strings.Join(lines, "\n")
tmp = strings.TrimLeft(tmp, "\n")
tmp = strings.TrimRight(tmp, "\n")
return tmp
}
func (ls *LinuxStatus) SetSpeedActual(s string) {
if !ls.Ready() {
return
}
ls.speedActual.SetText(s)
}

44
unix.go
View File

@ -2,18 +2,17 @@
// https://wiki.archlinux.org/title/Dynamic_DNS
package main
package linuxstatus
import (
"log"
"os"
"os/exec"
"net"
import (
"bytes"
"fmt"
"net"
"os"
"os/exec"
"strings"
"go.wit.com/shell"
"go.wit.com/log"
)
func CheckSuperuser() bool {
@ -28,14 +27,14 @@ func Escalate() {
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
debug(LogError, "exit in Escalate()")
exit(err)
log.Error(err, "exit in Escalate()")
log.Exit(err)
}
}
}
// You need permission to do a zone transfer. Otherwise:
// dig +noall +answer +multiline lab.wit.com any
// dig +noall +answer +multiline lab.wit.com any
// dig +all +multiline fire.lab.wit.com # gives the zonefile header (ttl vals)
func DumpPublicDNSZone(zone string) {
entries, err := net.LookupHost(zone)
@ -48,24 +47,24 @@ func DumpPublicDNSZone(zone string) {
}
func dumpIPs(host string) {
ips, err := net.LookupIP(host)
if err != nil {
debug(LogError, "dumpIPs() failed:", err)
}
for _, ip := range ips {
log.Println(host, ip)
}
ips, err := net.LookupIP(host)
if err != nil {
log.Error(err, "dumpIPs() failed")
}
for _, ip := range ips {
log.Println(host, ip)
}
}
/*
check if ddclient is installed, working, and/or configured
https://github.com/ddclient/ddclient
check if ddclient is installed, working, and/or configured
https://github.com/ddclient/ddclient
*/
func ddclient() {
}
/*
check if ddupdate is installed, working, and/or configured
check if ddupdate is installed, working, and/or configured
*/
func ddupdate() {
}
@ -89,9 +88,10 @@ func run(s string) string {
return ""
}
tmp := shell.Chomp(out.String())
// Trim leading and trailing whitespace from each line
tmp := strings.TrimSpace(out.String())
// Output the results
debug(LogExec, "Command Output:", tmp)
log.Verbose("Command Output:", tmp)
return tmp
}

43
update.go Normal file
View File

@ -0,0 +1,43 @@
package linuxstatus
import (
"errors"
"fmt"
"time"
"go.wit.com/log"
)
func (ls *LinuxStatus) Update() {
if ls == nil {
return
}
if !ls.Ready() {
log.Log(WARN, "can't update yet. ready is false")
log.Error(errors.New("Update() is not ready yet"))
return
}
log.Log(INFO, "Update() START")
duration := timeFunction(func() {
linuxLoop()
})
ls.setSpeed(duration)
log.Log(INFO, "Update() END")
}
func (ls *LinuxStatus) setSpeed(duration time.Duration) {
s := fmt.Sprint(duration)
if ls.speedActual == nil {
log.Log(WARN, "can't actually warn")
return
}
ls.speedActual.SetText(s)
if duration > 500*time.Millisecond {
ls.speed.SetText("SLOW")
} else if duration > 100*time.Millisecond {
ls.speed.SetText("OK")
} else {
ls.speed.SetText("FAST")
}
}