kvm/network.go

131 lines
2.4 KiB
Go

package kvm
import (
"fmt"
"github.com/pion/mdns/v2"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"net"
"time"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netlink/nl"
)
var networkState struct {
Up bool
IPv4 string
IPv6 string
MAC string
}
type LocalIpInfo struct {
IPv4 string
IPv6 string
MAC string
}
func checkNetworkState() {
iface, err := netlink.LinkByName("eth0")
if err != nil {
fmt.Printf("failed to get eth0 interface: %v\n", err)
return
}
newState := struct {
Up bool
IPv4 string
IPv6 string
MAC string
}{
Up: iface.Attrs().OperState == netlink.OperUp,
MAC: iface.Attrs().HardwareAddr.String(),
}
addrs, err := netlink.AddrList(iface, nl.FAMILY_ALL)
if err != nil {
fmt.Printf("failed to get addresses for eth0: %v\n", err)
}
for _, addr := range addrs {
if addr.IP.To4() != nil {
newState.IPv4 = addr.IP.String()
} else if addr.IP.To16() != nil && newState.IPv6 == "" {
newState.IPv6 = addr.IP.String()
}
}
if newState != networkState {
networkState = newState
fmt.Println("network state changed")
requestDisplayUpdate()
}
}
func startMDNS() error {
addr4, err := net.ResolveUDPAddr("udp4", mdns.DefaultAddressIPv4)
if err != nil {
return err
}
addr6, err := net.ResolveUDPAddr("udp6", mdns.DefaultAddressIPv6)
if err != nil {
return err
}
l4, err := net.ListenUDP("udp4", addr4)
if err != nil {
return err
}
l6, err := net.ListenUDP("udp6", addr6)
if err != nil {
return err
}
_, err = mdns.Server(ipv4.NewPacketConn(l4), ipv6.NewPacketConn(l6), &mdns.Config{
LocalNames: []string{"jetkvm.local"}, //TODO: make it configurable
})
if err != nil {
return err
}
//defer server.Close()
return nil
}
func init() {
updates := make(chan netlink.LinkUpdate)
done := make(chan struct{})
if err := netlink.LinkSubscribe(updates, done); err != nil {
fmt.Println("failed to subscribe to link updates: %v", err)
return
}
go func() {
waitCtrlClientConnected()
checkNetworkState()
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for {
select {
case update := <-updates:
if update.Link.Attrs().Name == "eth0" {
fmt.Printf("link update: %+v\n", update)
checkNetworkState()
}
case <-ticker.C:
checkNetworkState()
case <-done:
return
}
}
}()
fmt.Println("Starting mDNS server")
err := startMDNS()
if err != nil {
fmt.Println("failed to run mDNS: %v", err)
}
}