Created
November 8, 2017 08:55
-
-
Save ZoomQuiet/84f99c8caec66065ed699bf478fc1389 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
# Send/receive UDP multicast packets. | |
# Requires that your OS kernel supports IP multicast. | |
# | |
# Usage: | |
# mcast -s (sender, IPv4) | |
# mcast -s -6 (sender, IPv6) | |
# mcast (receivers, IPv4) | |
# mcast -6 (receivers, IPv6) | |
MYPORT = 8123 | |
MYGROUP_4 = '225.0.0.250' | |
MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' | |
MYTTL = 1 # Increase to reach other networks | |
import time | |
import struct | |
import socket | |
import sys | |
def main(): | |
group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 | |
if "-s" in sys.argv[1:]: | |
sender(group) | |
else: | |
receiver(group) | |
def sender(group): | |
addrinfo = socket.getaddrinfo(group, None)[0] | |
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) | |
# Set Time-to-live (optional) | |
ttl_bin = struct.pack('@i', MYTTL) | |
if addrinfo[0] == socket.AF_INET: # IPv4 | |
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) | |
else: | |
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) | |
while True: | |
data = repr(time.time()) | |
s.sendto(data + '\0', (addrinfo[4][0], MYPORT)) | |
time.sleep(1) | |
def receiver(group): | |
# Look up multicast group address in name server and find out IP version | |
addrinfo = socket.getaddrinfo(group, None)[0] | |
# Create a socket | |
s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) | |
# Allow multiple copies of this program on one machine | |
# (not strictly needed) | |
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
# Bind it to the port | |
s.bind(('', MYPORT)) | |
group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) | |
# Join group | |
if addrinfo[0] == socket.AF_INET: # IPv4 | |
mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) | |
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) | |
else: | |
mreq = group_bin + struct.pack('@I', 0) | |
s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) | |
# Loop, printing any data we receive | |
while True: | |
data, sender = s.recvfrom(1500) | |
while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's | |
print (str(sender) + ' ' + repr(data)) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment