func leaveIPv4Group(fd int, ifi *net.Interface, grp net.IP) error { mreq := syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}} if err := setSyscallIPMreq(&mreq, ifi); err != nil { return err } return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd, ianaProtocolIP, syscall.IP_DROP_MEMBERSHIP, &mreq)) }
// ListenMulticastIPv4 creates a net.IPConn to receive multicast messages for the given group // address. laddr specifies which network interface to use when joining the group. func ListenMulticastIPv4(gaddr, laddr net.IP) (*net.IPConn, error) { gaddr = gaddr.To4() laddr = laddr.To4() c, err := net.ListenIP("ip4:112", &net.IPAddr{IP: gaddr}) if err != nil { return nil, err } f, err := c.File() if err != nil { return nil, err } defer f.Close() mreq := &syscall.IPMreq{ Multiaddr: [4]byte{gaddr[0], gaddr[1], gaddr[2], gaddr[3]}, Interface: [4]byte{laddr[0], laddr[1], laddr[2], laddr[3]}, } err = syscall.SetsockoptIPMreq(int(f.Fd()), syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq) if err != nil { return nil, err } return c, nil }
func joinIPv4Group(fd int, ifi *net.Interface, grp net.IP) error { mreq := syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}} if err := setSysIPMreqInterface(&mreq, ifi); err != nil { return err } return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd, ianaProtocolIP, sysSockoptJoinGroup, &mreq)) }
func leaveIPv4Group(fd *netFD, ifi *Interface, ip IP) error { mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}} if err := setIPv4MreqToInterface(mreq, ifi); err != nil { return err } fd.incref() defer fd.decref() return os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)) }
func leaveIPv4GroupUDP(c *UDPConn, ifi *Interface, ip IP) error { mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}} if err := setIPv4InterfaceToJoin(mreq, ifi); err != nil { return &OpError{"leaveipv4group", "udp", &IPAddr{ip}, err} } if err := os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(c.fd.sysfd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)); err != nil { return &OpError{"leaveipv4group", "udp", &IPAddr{ip}, err} } return nil }
func leaveIPv4Group(fd int, ifi *net.Interface, grp net.IP) error { mreq := &syscall.IPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}} if err := setSyscallIPMreq(mreq, ifi); err != nil { return err } err := syscall.SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq) if err != nil { return os.NewSyscallError("setsockopt", err) } return nil }
func joinIPv4Group(fd *netFD, ifi *Interface, ip IP) error { mreq := &syscall.IPMreq{Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}} if err := setIPv4MreqToInterface(mreq, ifi); err != nil { return err } if err := fd.incref(false); err != nil { return err } defer fd.decref() err := syscall.SetsockoptIPMreq(fd.sysfd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq) if err != nil { return os.NewSyscallError("setsockopt", err) } return nil }
// LeaveGroup exits the IPv4 multicast group named by addr. func (c *UDPConn) LeaveGroup(addr IP) os.Error { if !c.ok() { return os.EINVAL } ip := addr.To4() if ip == nil { return &OpError{"leavegroup", "udp", &IPAddr{ip}, errInvalidMulticast} } mreq := &syscall.IPMreq{ Multiaddr: [4]byte{ip[0], ip[1], ip[2], ip[3]}, } err := os.NewSyscallError("setsockopt", syscall.SetsockoptIPMreq(c.fd.sysfd, syscall.IPPROTO_IP, syscall.IP_DROP_MEMBERSHIP, mreq)) if err != nil { return &OpError{"leavegroup", "udp", &IPAddr{ip}, err} } return nil }
func (s *Ssdp) createSocket() error { // create the socket var err error s.socket.socket, err = syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, syscall.IPPROTO_UDP) if err != nil { return err } // make sure we can reuse it / share it if err := syscall.SetsockoptInt(s.socket.socket, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); err != nil { syscall.Closesocket(s.socket.socket) s.socket.socket = 0 return err } // going to broadcast if err := syscall.SetsockoptInt(s.socket.socket, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1); err != nil { syscall.Closesocket(s.socket.socket) s.socket.socket = 0 return err } // bind it to the ssdp port lsa := &syscall.SockaddrInet4{Port: 1900, Addr: [4]byte{0, 0, 0, 0}} err = syscall.Bind(s.socket.socket, lsa) if err != nil { syscall.Closesocket(s.socket.socket) s.socket.socket = 0 return err } iter, err := net.Interfaces() if err != nil { syscall.Closesocket(s.socket.socket) s.socket.socket = 0 return err } wasFound := false for i := range iter { if iter[i].Flags&net.FlagMulticast == 0 { continue } addrs, err := iter[i].Addrs() if err != nil { continue } for k := range addrs { as4 := addrs[k].(*net.IPAddr).IP.To4() // join the multicast group mreq := &syscall.IPMreq{Multiaddr: [4]byte{239, 255, 255, 250}, Interface: [4]byte{as4[0], as4[1], as4[2], as4[3]}} if err := syscall.SetsockoptIPMreq(s.socket.socket, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq); err != nil { syscall.Closesocket(s.socket.socket) s.socket.socket = 0 return err } wasFound = true } } // if we couldn't join a group, fall back to just 0.0.0.0 if !wasFound { mreq := &syscall.IPMreq{Multiaddr: [4]byte{239, 255, 255, 250}, Interface: [4]byte{0, 0, 0, 0}} if err := syscall.SetsockoptIPMreq(s.socket.socket, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq); err != nil { syscall.Closesocket(s.socket.socket) s.socket.socket = 0 return err } } s.socket.readBytes = make([]byte, 2048) return nil }