Python socket.IP_MULTICAST_LOOP Examples

The following are 30 code examples of socket.IP_MULTICAST_LOOP(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module socket , or try the search function .
Example #1
Source File: multicast_checks.py    From rift-python with Apache License 2.0 7 votes vote down vote up
def _create_ipv4_sockets(loopback_enabled):
    # Open a multicast send socket, with IP_MULTICAST_LOOP enabled or disabled as requested.
    mcast_address = "224.0.1.195"
    port = 49501
    group = (mcast_address, port)
    txsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    txsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    if loopback_enabled:
        txsock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
    else:
        txsock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
    txsock.connect(group)
    # Open a multicast receive socket and join the group
    rxsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    req = struct.pack("=4sl", socket.inet_aton(mcast_address), socket.INADDR_ANY)
    rxsock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, req)
    rxsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    rxsock.bind(group)
    return (txsock, rxsock) 
Example #2
Source File: multicast_checks.py    From rift-python with Apache License 2.0 6 votes vote down vote up
def _create_ipv6_sockets(loopback_enabled):
    # Open a multicast send socket, with IP_MULTICAST_LOOP enabled or disabled as requested.
    intf_name = find_ethernet_interface()
    intf_index = socket.if_nametoindex(intf_name)
    mcast_address = "ff02::abcd:99"
    port = 30000
    group = (mcast_address, port)
    txsock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    txsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    txsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, intf_index)
    if loopback_enabled:
        txsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)
    else:
        txsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 0)
    txsock.connect(group)
    # Open a multicast receive socket and join the group
    rxsock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    req = struct.pack("=16si", socket.inet_pton(socket.AF_INET6, mcast_address), intf_index)
    if platform.system() == "Darwin":
        rxsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, req)
    else:
        rxsock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_ADD_MEMBERSHIP, req)
    rxsock.bind(("::", port))
    return (txsock, rxsock) 
Example #3
Source File: minusconf.py    From scoop with GNU Lesser General Public License v3.0 6 votes vote down vote up
def _init_advertiser(self):
        sock = _find_sock()
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, struct.pack('@I', 1))
        sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, struct.pack('@I', 1))
        if sock.family == socket.AF_INET6:
            sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, struct.pack('@I', 1))
        sock.bind(('', self.port))

        addrs = _resolve_addrs(self.addresses, None, self.ignore_unavailable, (sock.family,))

        for fam,to,orig_fam,orig_addr in addrs:
            try:
                _multicast_join_group(sock, orig_fam, orig_addr)
            except socket.error:
                if not self.ignore_unavailable:
                    raise

        self._sock = sock 
Example #4
Source File: wsdd.py    From wsdd with MIT License 6 votes vote down vote up
def init_v4(self):
        idx = socket.if_nametoindex(self.interface.name)
        self.multicast_address = (WSD_MCAST_GRP_V4, WSD_UDP_PORT)

        # v4: member_request (ip_mreqn) = { multicast_addr, intf_addr, idx }
        mreq = (
            socket.inet_pton(self.family, WSD_MCAST_GRP_V4) +
            socket.inet_pton(self.family, self.address) +
            struct.pack('@I', idx))
        self.recv_socket.setsockopt(
            socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)

        try:
            self.recv_socket.bind((WSD_MCAST_GRP_V4, WSD_UDP_PORT))
        except OSError:
            self.recv_socket.bind(('', WSD_UDP_PORT))

        self.send_socket.setsockopt(
            socket.IPPROTO_IP, socket.IP_MULTICAST_IF, mreq)
        self.send_socket.setsockopt(
            socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
        self.send_socket.setsockopt(
            socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, args.hoplimit)

        self.listen_address = (self.address, WSD_HTTP_PORT) 
Example #5
Source File: packetizer.py    From WaveSync with MIT License 5 votes vote down vote up
def create_socket(self, channels, ttl, multicast_loop, broadcast, source_address=None):
        "Create a UDP multicast socket"
        self.sock = socket.socket(socket.AF_INET,
                                  socket.SOCK_DGRAM,
                                  socket.IPPROTO_UDP)
        self.sock.setsockopt(socket.IPPROTO_IP,
                             socket.IP_MULTICAST_TTL,
                             ttl)

        for address, port in channels:
            if source_address and ipaddress.IPv4Address(address).is_multicast:
                try:
                    self.sock.setsockopt(socket.SOL_IP,
                                         socket.IP_MULTICAST_IF,
                                         socket.inet_aton(source_address))
                    print("added membership, interface source address: %s, group: %s" % (source_address, address))
                    self.sock.setsockopt(socket.SOL_IP,
                                         socket.IP_ADD_MEMBERSHIP,
                                         socket.inet_aton(address) + socket.inet_aton(source_address))
                except:
                    print("failed to add membership, interface source address: %s, group: %s. This is ok for unicast." % (source_address, address))

        if multicast_loop is True:
            self.sock.setsockopt(socket.IPPROTO_IP,
                                 socket.IP_MULTICAST_LOOP, 1)

        if broadcast is True:
            self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

        self.destinations = [
            (address, port)
            for address, port in channels
        ]

        IP_PMTUDISC_DO = 2
        IP_MTU_DISCOVER = 10

        # Set DF flag on IP packet (Don't Fragment) - fragmenting would be bad idea
        # it's way better to chunk the packets right.
        self.sock.setsockopt(socket.IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DO) 
Example #6
Source File: multicast_checks.py    From rift-python with Apache License 2.0 5 votes vote down vote up
def _loopback_needed(ipv6):
    # If we receive a single copy when loopback is disabled, then we need to disable loopback
    if _copies_received(ipv6, False) == 1:
        return False
    # We receive zero copies with loopback disabled. Make sure we do receive a single copy with
    # loopback enabled.
    copies = _copies_received(ipv6, True)
    if copies == 1:
        return True
    elif copies == 0:
        assert False, "We don't receive multicast packet with or without IP_MULTICAST_LOOP"
    else:
        assert False, "Unexpected IP_MULTICAST_LOOP behavior"
    return False  # To make Pylint happy 
Example #7
Source File: zeroconf.py    From RepetierIntegration with GNU Affero General Public License v3.0 5 votes vote down vote up
def new_socket():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
    # multicast UDP sockets (p 731, "TCP/IP Illustrated,
    # Volume 2"), but some BSD-derived systems require
    # SO_REUSEPORT to be specified explicity.  Also, not all
    # versions of Python have SO_REUSEPORT available.
    # Catch OSError and socket.error for kernel versions <3.9 because lacking
    # SO_REUSEPORT support.
    try:
        reuseport = socket.SO_REUSEPORT
    except AttributeError:
        pass
    else:
        try:
            s.setsockopt(socket.SOL_SOCKET, reuseport, 1)
        except (OSError, socket.error) as err:
            # OSError on python 3, socket.error on python 2
            if not err.errno == errno.ENOPROTOOPT:
                raise

    # OpenBSD needs the ttl and loop values for the IP_MULTICAST_TTL and
    # IP_MULTICAST_LOOP socket options as an unsigned char.
    ttl = struct.pack(b'B', 255)
    s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
    loop = struct.pack(b'B', 1)
    s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop)

    s.bind(('', _MDNS_PORT))
    return s 
Example #8
Source File: zeroconf.py    From jarvis with GNU General Public License v2.0 5 votes vote down vote up
def new_socket():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
    # multicast UDP sockets (p 731, "TCP/IP Illustrated,
    # Volume 2"), but some BSD-derived systems require
    # SO_REUSEPORT to be specified explicity.  Also, not all
    # versions of Python have SO_REUSEPORT available.
    # Catch OSError and socket.error for kernel versions <3.9 because lacking
    # SO_REUSEPORT support.
    try:
        reuseport = socket.SO_REUSEPORT
    except AttributeError:
        pass
    else:
        try:
            s.setsockopt(socket.SOL_SOCKET, reuseport, 1)
        except (OSError, socket.error) as err:
            # OSError on python 3, socket.error on python 2
            if not err.errno == errno.ENOPROTOOPT:
                raise

    # OpenBSD needs the ttl and loop values for the IP_MULTICAST_TTL and
    # IP_MULTICAST_LOOP socket options as an unsigned char.
    ttl = struct.pack(b'B', 255)
    s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
    loop = struct.pack(b'B', 1)
    s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop)

    s.bind(('', _MDNS_PORT))
    return s 
Example #9
Source File: udp.py    From BitTorrent with GNU General Public License v3.0 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, mode) 
Example #10
Source File: udp.py    From BitTorrent with GNU General Public License v3.0 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP) 
Example #11
Source File: udp.py    From python-for-android with Apache License 2.0 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, mode) 
Example #12
Source File: udp.py    From python-for-android with Apache License 2.0 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP) 
Example #13
Source File: udp.py    From python-for-android with Apache License 2.0 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP,
                               mode) 
Example #14
Source File: udp.py    From python-for-android with Apache License 2.0 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP,
                                      socket.IP_MULTICAST_LOOP) 
Example #15
Source File: ssdp.py    From script.tubecast with MIT License 5 votes vote down vote up
def set_loopback_mode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP,
                               mode) 
Example #16
Source File: connection_manager.py    From jellyfin-kodi with GNU General Public License v3.0 5 votes vote down vote up
def _server_discovery(self):
        MULTI_GROUP = ("<broadcast>", 7359)
        MESSAGE = b"who is JellyfinServer?"

        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(1.0)  # This controls the socket.timeout exception

        sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
        sock.setsockopt(socket.IPPROTO_IP, socket.SO_REUSEADDR, 1)

        LOG.debug("MultiGroup      : %s", str(MULTI_GROUP))
        LOG.debug("Sending UDP Data: %s", MESSAGE)

        servers = []

        try:
            sock.sendto(MESSAGE, MULTI_GROUP)
        except Exception as error:
            LOG.exception(traceback.format_exc())
            LOG.exception(error)
            return servers

        while True:
            try:
                data, addr = sock.recvfrom(1024)  # buffer size
                servers.append(json.loads(data))

            except socket.timeout:
                LOG.info("Found Servers: %s", servers)
                return servers

            except Exception as e:
                LOG.error(traceback.format_exc())
                LOG.exception("Error trying to find servers: %s", e)
                return servers 
Example #17
Source File: udp_client.py    From xknx with MIT License 5 votes vote down vote up
def create_multicast_sock(own_ip, remote_addr, bind_to_multicast_addr):
        """Create UDP multicast socket."""
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.setblocking(False)

        sock.setsockopt(
            socket.SOL_IP,
            socket.IP_MULTICAST_IF,
            socket.inet_aton(own_ip))
        sock.setsockopt(
            socket.SOL_IP,
            socket.IP_ADD_MEMBERSHIP,
            socket.inet_aton(remote_addr[0]) +
            socket.inet_aton(own_ip))
        sock.setsockopt(
            socket.IPPROTO_IP,
            socket.IP_MULTICAST_TTL, 2)
        sock.setsockopt(
            socket.IPPROTO_IP,
            socket.IP_MULTICAST_IF,
            socket.inet_aton(own_ip))

        # I have no idea why we have to use different bind calls here
        # - bind() with multicast addr does not work with gateway search requests
        #   on some machines. It only works if called with own ip. It also doesn't
        #   work on Mac OS.
        # - bind() with own_ip does not work with ROUTING_INDICATIONS on Gira
        #   knx router - for an unknown reason.
        if bind_to_multicast_addr:
            if platform == "win32":
                sock.bind(('', remote_addr[1]))
            else:
                sock.bind((remote_addr[0], remote_addr[1]))
        else:
            sock.bind((own_ip, 0))
        sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 0)
        return sock 
Example #18
Source File: udp.py    From learn_python3_spider with MIT License 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, mode) 
Example #19
Source File: udp.py    From learn_python3_spider with MIT License 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP) 
Example #20
Source File: udp.py    From learn_python3_spider with MIT License 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP,
                               mode) 
Example #21
Source File: udp.py    From learn_python3_spider with MIT License 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP,
                                      socket.IP_MULTICAST_LOOP) 
Example #22
Source File: udp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, mode) 
Example #23
Source File: udp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP) 
Example #24
Source File: udp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def setLoopbackMode(self, mode):
        mode = struct.pack("b", operator.truth(mode))
        self.socket.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP,
                               mode) 
Example #25
Source File: udp.py    From Safejumper-for-Desktop with GNU General Public License v2.0 5 votes vote down vote up
def getLoopbackMode(self):
        return self.socket.getsockopt(socket.IPPROTO_IP,
                                      socket.IP_MULTICAST_LOOP) 
Example #26
Source File: mihome.py    From goodbye-mihome with BSD 2-Clause "Simplified" License 5 votes vote down vote up
def receiver(service='mihome'):
    from plugins import gateway

    assert service in MULTICAST, 'No such service'
    store = get_store()
    address, port = MULTICAST.get(service)
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.bind(("0.0.0.0", port))
 
    mreq = struct.pack("=4sl", socket.inet_aton(address), socket.INADDR_ANY)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 32)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, SOCKET_BUFSIZE)
    sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
    sock.settimeout(20)  # 2x of heartbeat period

    current = {}

    while True:
        try:
            data, _ = sock.recvfrom(SOCKET_BUFSIZE)  # buffer size is 1024 bytes
        except socket.timeout:
            continue
        print(datetime.now().isoformat(), data)
        if service == 'mihome':
            message = json.loads(data.decode())
            data = json.loads(message['data'])
            if message.get('model') in ('sensor_ht', 'weather.v1') and not sensor_ht.process(conn, cursor, current, message, data):
                continue
            elif message.get('model') == 'magnet':
                magnet.process(store, message, data)
            elif message.get('model') == 'gateway':
                gateway.process(store, message, data)
            current = {}
        elif service == 'yeelight':
            yeelight.process(data.decode()) 
Example #27
Source File: connection_manager.py    From plugin.video.emby with GNU General Public License v3.0 5 votes vote down vote up
def _server_discovery(self):
        
        MULTI_GROUP = ("<broadcast>", 7359)
        MESSAGE = "who is EmbyServer?"
        sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        sock.settimeout(1.0) # This controls the socket.timeout exception
        sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 20)
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
        sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1)
        sock.setsockopt(socket.IPPROTO_IP, socket.SO_REUSEADDR, 1)
        
        LOG.debug("MultiGroup      : %s", str(MULTI_GROUP))
        LOG.debug("Sending UDP Data: %s", MESSAGE)
        servers = []

        try:
            sock.sendto(MESSAGE, MULTI_GROUP)
        except Exception as error:
            LOG.error(error)

            return servers

        while True:
            try:
                data, addr = sock.recvfrom(1024) # buffer size
                servers.append(json.loads(data))
            
            except socket.timeout:
                LOG.info("Found Servers: %s", servers)

                return servers
            
            except Exception as e:
                LOG.error("Error trying to find servers: %s", e)

                return servers 
Example #28
Source File: interface.py    From rift-python with Apache License 2.0 5 votes vote down vote up
def create_socket_ipv4_tx_mcast(self, multicast_address, port, loopback):
        try:
            sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
        except IOError as err:
            self.warning("Could not create IPv4 UDP socket: %s", err)
            return None
        self.enable_addr_and_port_reuse(sock)
        if self._ipv4_address is not None:
            try:
                sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_IF,
                                socket.inet_aton(self._ipv4_address))
            except IOError as err:
                self.warning("Could not set IPv6 multicast interface address %s: %s",
                             self._ipv4_address, err)
                return None
        try:
            loop_value = 1 if loopback else 0
            sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop_value)
        except IOError as err:
            self.warning("Could not set IPv4 multicast loopback value %d: %s", loop_value, err)
            return None
        try:
            sock.connect((multicast_address, port))
        except IOError as err:
            self.warning("Could not connect UDP socket to address %s port %d: %s",
                         multicast_address, port, err)
            return None
        return sock 
Example #29
Source File: zeroconf.py    From HomePWN with GNU General Public License v3.0 4 votes vote down vote up
def new_socket(interface_number=None, interface_name=None):
    """
    Create a new socket for a given interface_number. 
    interface_name and interface_number have to be for the same interface 

    """
    #Default is IPv4
    address_family = socket.AF_INET

    intf = None #The interface used to transmit data

    if interface_number is None: 
        #No ipv6 interface given. Stay in ipv4 
        intf = socket.gethostbyname(socket.gethostname())
    else: #IPv6 
        intf = int(interface_number)
        address_family = socket.AF_INET6

    #Create socket 
    s = socket.socket(address_family, socket.SOCK_DGRAM)

    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
    # multicast UDP sockets (p 731, "TCP/IP Illustrated,
    # Volume 2"), but some BSD-derived systems require
    # SO_REUSEPORT to be specified explicity.  Also, not all
    # versions of Python have SO_REUSEPORT available.
    # Catch OSError and socket.error for kernel versions <3.9 because lacking
    # SO_REUSEPORT support.
    try:
        reuseport = socket.SO_REUSEPORT
    except AttributeError:
        pass
    else:
        try:
            s.setsockopt(socket.SOL_SOCKET, reuseport, 1)
        except (OSError, socket.error) as err:
            # OSError on python 3, socket.error on python 2
            if not err.errno == errno.ENOPROTOOPT:
                raise


    # OpenBSD needs the ttl and loop values for the IP_MULTICAST_TTL and
    # IP_MULTICAST_LOOP socket options as an unsigned char.
    if address_family is socket.AF_INET: 
        ttl = struct.pack(b'B', 255)
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
        loop = struct.pack(b'B', 1)
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop)
    
    else: #IPv6
        s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 255)
        s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)

    if interface_name is "awdl0" and platform.system() == 'Darwin':
        s.setsockopt(socket.SOL_SOCKET, 0x1104, 1)

    #Bind the Socket
    s.bind(('', _MDNS_PORT))
    return s 
Example #30
Source File: zeroconf.py    From apple_bleee with GNU General Public License v3.0 4 votes vote down vote up
def new_socket(interface_number=None, interface_name=None):
    """
    Create a new socket for a given interface_number. 
    interface_name and interface_number have to be for the same interface 

    """
    #Default is IPv4
    address_family = socket.AF_INET

    intf = None #The interface used to transmit data

    if interface_number is None: 
        #No ipv6 interface given. Stay in ipv4 
        intf = socket.gethostbyname(socket.gethostname())
    else: #IPv6 
        intf = int(interface_number)
        address_family = socket.AF_INET6

    #Create socket 
    s = socket.socket(address_family, socket.SOCK_DGRAM)

    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # SO_REUSEADDR should be equivalent to SO_REUSEPORT for
    # multicast UDP sockets (p 731, "TCP/IP Illustrated,
    # Volume 2"), but some BSD-derived systems require
    # SO_REUSEPORT to be specified explicity.  Also, not all
    # versions of Python have SO_REUSEPORT available.
    # Catch OSError and socket.error for kernel versions <3.9 because lacking
    # SO_REUSEPORT support.
    try:
        reuseport = socket.SO_REUSEPORT
    except AttributeError:
        pass
    else:
        try:
            s.setsockopt(socket.SOL_SOCKET, reuseport, 1)
        except (OSError, socket.error) as err:
            # OSError on python 3, socket.error on python 2
            if not err.errno == errno.ENOPROTOOPT:
                raise


    # OpenBSD needs the ttl and loop values for the IP_MULTICAST_TTL and
    # IP_MULTICAST_LOOP socket options as an unsigned char.
    if address_family is socket.AF_INET: 
        ttl = struct.pack(b'B', 255)
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
        loop = struct.pack(b'B', 1)
        s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, loop)
    
    else: #IPv6
        s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, 255)
        s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_LOOP, 1)

    if interface_name is "awdl0" and platform.system() == 'Darwin':
        s.setsockopt(socket.SOL_SOCKET, 0x1104, 1)

    #Bind the Socket
    s.bind(('', _MDNS_PORT))
    return s