| 
									
										
										
										
											2010-03-11 22:53:45 +00:00
										 |  |  | #!/usr/bin/env python3 | 
					
						
							| 
									
										
										
										
											2010-12-30 22:11:50 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 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) | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											1992-09-08 21:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | MYPORT = 8123 | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  | MYGROUP_4 = '225.0.0.250' | 
					
						
							|  |  |  | MYGROUP_6 = 'ff15:7079:7468:6f6e:6465:6d6f:6d63:6173' | 
					
						
							|  |  |  | MYTTL = 1 # Increase to reach other networks | 
					
						
							| 
									
										
										
										
											1992-09-08 21:19:55 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | import time | 
					
						
							|  |  |  | import struct | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  | import socket | 
					
						
							|  |  |  | import sys | 
					
						
							| 
									
										
										
										
											1992-09-08 21:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-11-16 16:54:45 +00:00
										 |  |  | def main(): | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |     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): | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     addrinfo = socket.getaddrinfo(group, None)[0] | 
					
						
							| 
									
										
										
										
											1992-11-16 16:54:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) | 
					
						
							| 
									
										
										
										
											1992-09-08 21:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |     # Set Time-to-live (optional) | 
					
						
							|  |  |  |     ttl_bin = struct.pack('@i', MYTTL) | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     if addrinfo[0] == socket.AF_INET: # IPv4 | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |         s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     else: | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |         s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_HOPS, ttl_bin) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     while True: | 
					
						
							|  |  |  |         data = repr(time.time()).encode('utf-8') + b'\0' | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |         s.sendto(data, (addrinfo[4][0], MYPORT)) | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |         time.sleep(1) | 
					
						
							| 
									
										
										
										
											1992-09-08 21:19:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-10-25 19:20:47 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  | def receiver(group): | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     # Look up multicast group address in name server and find out IP version | 
					
						
							|  |  |  |     addrinfo = socket.getaddrinfo(group, None)[0] | 
					
						
							| 
									
										
										
										
											1992-11-16 16:54:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     # Create a socket | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     s = socket.socket(addrinfo[0], socket.SOCK_DGRAM) | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     # Allow multiple copies of this program on one machine | 
					
						
							|  |  |  |     # (not strictly needed) | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |     s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 05:56:09 +00:00
										 |  |  |     # Bind it to the port | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |     s.bind(('', MYPORT)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |     # Join group | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |     if addrinfo[0] == socket.AF_INET: # IPv4 | 
					
						
							|  |  |  |         mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |         s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) | 
					
						
							|  |  |  |     else: | 
					
						
							| 
									
										
										
										
											2009-06-23 22:01:54 +00:00
										 |  |  |         mreq = group_bin + struct.pack('@I', 0) | 
					
						
							| 
									
										
										
										
											2009-05-03 19:09:56 +00:00
										 |  |  |         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() |