1 #!/usr/bin/env python 2 # 3 # Send/receive UDP multicast packets. 4 # Requires that your OS kernel supports IP multicast. 5 # 6 # Usage: 7 # mcast -s (sender, IPv4) 8 # mcast -s -6 (sender, IPv6) 9 # mcast (receivers, IPv4) 10 # mcast -6 (receivers, IPv6) 11 12 MYPORT = 8123 13 MYGROUP_4 = '225.0.0.250' 14 MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' 15 MYTTL = 1 # Increase to reach other networks 16 17 import time 18 import struct 19 import socket 20 import sys 21 22 def main(): 23 group = MYGROUP_6 if "-6" in sys.argv[1:] else MYGROUP_4 24 25 if "-s" in sys.argv[1:]: 26 sender(group) 27 else: 28 receiver(group) 29 30 31 def sender(group): 32 addrinfo = socket.getaddrinfo(group, None)[0] 33 34 s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) 35 36 # Set Time-to-live (optional) 37 ttl_bin = struct.pack('@i', MYTTL) 38 if addrinfo[0] == socket.AF_INET: # IPv4 39 s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) 40 else: 41 s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) 42 43 while True: 44 data = repr(time.time()) 45 s.sendto(data + '\0', (addrinfo[4][0], MYPORT)) 46 time.sleep(1) 47 48 49 def receiver(group): 50 # Look up multicast group address in name server and find out IP version 51 addrinfo = socket.getaddrinfo(group, None)[0] 52 53 # Create a socket 54 s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) 55 56 # Allow multiple copies of this program on one machine 57 # (not strictly needed) 58 s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 59 60 # Bind it to the port 61 s.bind(('', MYPORT)) 62 63 group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) 64 # Join group 65 if addrinfo[0] == socket.AF_INET: # IPv4 66 mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) 67 s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 68 else: 69 mreq = group_bin + struct.pack('@I', 0) 70 s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, mreq) 71 72 # Loop, printing any data we receive 73 while True: 74 data, sender = s.recvfrom(1500) 75 while data[-1:] == '\0': data = data[:-1] # Strip trailing \0's 76 print (str(sender) + ' ' + repr(data)) 77 78 79 if __name__ == '__main__': 80 main() 81