diff --git a/cmd/diagd/diagd.go b/cmd/diagd/diagd.go index 6c1e129..d14f412 100644 --- a/cmd/diagd/diagd.go +++ b/cmd/diagd/diagd.go @@ -94,14 +94,12 @@ func logic() error { m := diag.NewMonitor(diag.Link(uplink). Then(diag.DHCPv4(). Then(diag.Ping4Gateway(). - Then(diag.Ping4("google.ch"). - Then(diag.TCP4("www.google.ch:80"))))). + Then(diag.TCP4("www.google.ch:80")))). Then(diag.DHCPv6(). - Then(diag.Ping6("lan0", "google.ch"))). + Then(diag.TCP6("lan0", "www.google.ch:80"))). Then(diag.RouterAdvertisments(uplink). Then(diag.Ping6Gateway(). - Then(diag.Ping6(uplink, "google.ch"). - Then(diag.TCP6("www.google.ch:80"))))). + Then(diag.TCP6(uplink, "www.google.ch:80")))). Then(diag.Ping6("", ip6allrouters+"%"+uplink))) var mu sync.Mutex http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { diff --git a/internal/diag/tcp.go b/internal/diag/tcp.go index bad741e..8bd8f55 100644 --- a/internal/diag/tcp.go +++ b/internal/diag/tcp.go @@ -53,6 +53,7 @@ func TCP4(addr string) Node { type tcp6 struct { children []Node + ifname string addr string } @@ -70,7 +71,39 @@ func (d *tcp6) Children() []Node { } func (d *tcp6) Evaluate() (string, error) { - conn, err := net.Dial("tcp6", d.addr) + var dialer net.Dialer + + if d.ifname != "" { + iface, err := net.InterfaceByName(d.ifname) + if err != nil { + return "", err + } + addrs, err := iface.Addrs() + if err != nil { + return "", err + } + for _, addr := range addrs { + ipnet, ok := addr.(*net.IPNet) + if !ok { + continue + } + + if ipnet.IP.To4() != nil { + continue // skip IPv4 addresses + } + + if !global.Contains(ipnet.IP) { + continue // skip local IPv6 addresses + } + + dialer.LocalAddr = &net.TCPAddr{ + IP: ipnet.IP, + } + break + } + } + + conn, err := dialer.Dial("tcp6", d.addr) if err != nil { return "", err } @@ -80,6 +113,9 @@ func (d *tcp6) Evaluate() (string, error) { // TCP6 returns a Node which succeeds when the specified address accepts a TCPv6 // connection. -func TCP6(addr string) Node { - return &tcp6{addr: addr} +func TCP6(ifname, addr string) Node { + return &tcp6{ + ifname: ifname, + addr: addr, + } }