Created
January 23, 2019 22:16
-
-
Save cjhanks/14bdc11fc4c0fec5d38ef67140c77048 to your computer and use it in GitHub Desktop.
This file contains 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 = 5 # 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