func (s *Server) sendRA(src net.Addr) { var srcIP net.IP var ipAddr net.Addr iface, err := net.InterfaceByName("tap" + s.name) if err != nil { return } addrs, err := iface.Addrs() if err != nil { l.Info("can't get addresses from " + iface.Name + " " + err.Error()) return } for _, addr := range addrs { ip, _, err := net.ParseCIDR(addr.String()) if err != nil { l.Info(err.Error()) continue } if ip.To4() == nil && strings.HasPrefix(addr.String(), "fe80") { srcIP = ip if src == nil { ipAddr = net.Addr(&net.IPAddr{IP: net.IPv6linklocalallnodes, Zone: "tap" + s.name}) } else { ipAddr = src } break } } if ipAddr == nil || srcIP == nil { l.Info(fmt.Sprintf("ipv6 add missing for tap %s %s", s.name, srcIP)) return } res, err := s.ServeICMPv6(srcIP, &ICMPv6{Type: uint8(ipv6.ICMPTypeRouterSolicitation)}) if err != nil { l.Info(err.Error()) return } for _, msg := range res { buf := make([]byte, msg.Len()) buf, err = msg.Marshal() if err != nil { l.Info(fmt.Sprintf("%s err %s", s.name, err.Error())) continue } wcm := ipv6.ControlMessage{HopLimit: 255} wcm.Dst = net.IPv6linklocalallnodes wcm.IfIndex = iface.Index if _, err = s.ipv6conn.WriteTo(buf, &wcm, ipAddr); err != nil { l.Info(fmt.Sprintf("%s err %s", s.name, err.Error())) continue } } }