@@ -86,7 +86,7 @@ func WalkIP(cidr string) chan string {
8686// PingLan tries to send a tiny UDP packet to all LAN hosts
8787func (a * disc ) PingLan () {
8888 var (
89- isV4 bool
89+ isV6 bool
9090 b [16 ]byte
9191 )
9292
@@ -99,12 +99,8 @@ func (a *disc) PingLan() {
9999 // ip network(s) that assigned to interface(s)
100100 for _ , addr := range addrs {
101101 if strings .IndexAny (addr .String (), "::" ) != - 1 {
102- isV4 = false
102+ isV6 = true
103103 } else {
104- isV4 = true
105- }
106-
107- if isV4 {
108104 fd , err := syscall .Socket (syscall .AF_INET , syscall .SOCK_RAW , syscall .IPPROTO_ICMP )
109105 if err != nil {
110106 println (err .Error ())
@@ -125,36 +121,41 @@ func (a *disc) PingLan() {
125121 },
126122 }).Marshal (nil )
127123 if err := syscall .Sendto (fd , m , 0 , & addr ); err != nil {
128- println (err .Error ())
124+ if b [3 ] != 0 && b [3 ] != 255 {
125+ println (err .Error ())
126+ }
129127 }
130128 }
131129 syscall .Close (fd )
132- } else {
133- fd , err := syscall .Socket (syscall .AF_INET6 , syscall .SOCK_RAW , syscall .IPPROTO_ICMPV6 )
134- if err != nil {
135- println (err .Error ())
136- return
137- }
138- syscall .SetsockoptInt (fd , syscall .IPPROTO_IPV6 , syscall .IPV6_UNICAST_HOPS , 1 )
139- copy (b [:], net .ParseIP (fmt .Sprintf ("ff02::1" )).To16 ())
140- addr := syscall.SockaddrInet6 {
141- Port : 33434 ,
142- ZoneId : uint32 (i .Index ),
143- Addr : b ,
144- }
145- m , _ := (& icmp.Message {
146- Type : ipv6 .ICMPTypeEchoRequest , Code : 0 ,
147- Body : & icmp.Echo {
148- ID : 2016 , Seq : 1 ,
149- Data : make ([]byte , 52 - 48 ),
150- },
151- }).Marshal (nil )
152- if err := syscall .Sendto (fd , m , 0 , & addr ); err != nil {
153- println (err .Error ())
154- }
155- syscall .Close (fd )
156130 }
157131 }
132+ // sending a solicited-node multicast/icmp if there is IPv6 address
133+ if isV6 {
134+ fd , err := syscall .Socket (syscall .AF_INET6 , syscall .SOCK_RAW , syscall .IPPROTO_ICMPV6 )
135+ if err != nil {
136+ println (err .Error ())
137+ return
138+ }
139+ syscall .SetsockoptInt (fd , syscall .IPPROTO_IPV6 , syscall .IPV6_UNICAST_HOPS , 1 )
140+ copy (b [:], net .ParseIP (fmt .Sprintf ("ff02::1" )).To16 ())
141+ addr := syscall.SockaddrInet6 {
142+ Port : 33434 ,
143+ ZoneId : uint32 (i .Index ),
144+ Addr : b ,
145+ }
146+ m , _ := (& icmp.Message {
147+ Type : ipv6 .ICMPTypeEchoRequest , Code : 0 ,
148+ Body : & icmp.Echo {
149+ ID : 2016 , Seq : 1 ,
150+ Data : make ([]byte , 52 - 48 ),
151+ },
152+ }).Marshal (nil )
153+ if err := syscall .Sendto (fd , m , 0 , & addr ); err != nil {
154+ println (err .Error ())
155+ }
156+ isV6 = false
157+ syscall .Close (fd )
158+ }
158159 }
159160}
160161func nextIP (ip net.IP ) {
0 commit comments