├── .gitignore ├── README.md └── mctest.py /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Multicast Test Tool in Python2/3 2 | 3 | ``` 4 | $ ./mctest.py 5 | usage: mctest.py [-h] [-send string] [-receive] 6 | [-group Multicast Group default: 232.8.8.8] [-port UDP Port] 7 | [-ttl int] [-v] 8 | 9 | Multicast Send/Receive Test Tool 10 | 11 | optional arguments: 12 | -h, --help show this help message and exit 13 | -send string Send a Message 14 | -receive Receive Messages from Group 15 | -group Multicast Group (default: 232.8.8.8) 16 | -port UDP Port UDP Port to receive on (default 1900) 17 | -ttl int Multicast TTL (default 10) 18 | -v Verbose Output 19 | ``` 20 | 21 | ## Receive Example (uPNP Traffic) 22 | ``` 23 | $ ./mctest.py -rec -group 239.255.255.250 -port 1900 24 | Listing on 239.255.255.250 port 1900 25 | Received on 239.255.255.250 from 10.26.73.211 from port 1900: NOTIFY * HTTP/1.1 26 | HOST: 239.255.255.250:1900 27 | CACHE-CONTROL: max-age=60 28 | LOCATION: http://10.26.73.211:6432/description.xml 29 | NT: upnp:rootdevice 30 | NTS: ssdp:alive 31 | SERVER: lwIP/1.3.2 32 | USN: uuid:upnp_MDL-S2E-c0a26d004ba8::upnp:rootdevice 33 | ``` 34 | 35 | ## Send Example with Receive 36 | ``` 37 | ./mctest.py -send 'test from imac' 38 | Sending to 232.8.8.8 (TTL 10): test from imac: 2017-07-17 11:23:29 39 | Sending to 232.8.8.8 (TTL 10): test from imac: 2017-07-17 11:23:30 40 | Sending to 232.8.8.8 (TTL 10): test from imac: 2017-07-17 11:23:31 41 | ``` 42 | 43 | ### Receiver 44 | ``` 45 | ./mctest.py -rec 46 | Listing on 232.8.8.8 port 1900 47 | Received on 232.8.8.8 from 128.23.200.25 from port 51596: test from imac: 2017-07-17 11:23:29 48 | Received on 232.8.8.8 from 128.23.200.25 from port 51596: test from imac: 2017-07-17 11:23:30 49 | Received on 232.8.8.8 from 128.23.200.25 from port 51596: test from imac: 2017-07-17 11:23:31 50 | ``` 51 | -------------------------------------------------------------------------------- /mctest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import time 3 | from datetime import datetime 4 | import socket 5 | import sys 6 | import struct 7 | import argparse 8 | import logging 9 | import pickle 10 | 11 | logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', \ 12 | level=logging.WARNING) 13 | 14 | logger = logging.getLogger('mctest') 15 | 16 | group = '232.8.8.8' 17 | mport = 1900 18 | mttl = 10 19 | message = 'multicast test tool' 20 | 21 | parser = argparse.ArgumentParser() 22 | parser = argparse.ArgumentParser(description='Multicast Send/Receive Test Tool') 23 | parser.add_argument("-send", metavar="string", help="Send a Message", 24 | type=str) 25 | parser.add_argument("-receive", help="Receive Messages from Group", 26 | action="store_true") 27 | parser.add_argument("-group", metavar="Multicast Group (default: 232.8.8.8)", type=str) 28 | parser.add_argument("-port", metavar="UDP Port", help="UDP Port to receive on (default 1900)") 29 | parser.add_argument('-ttl', metavar='int', help="Multicast TTL (default 10)", type=int) 30 | parser.add_argument("-v", help="Verbose Output", action="store_true") 31 | args = parser.parse_args() 32 | 33 | def receiver(mgroup): 34 | 'Receive on a multicast group' 35 | 36 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 37 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 38 | 39 | # Windows workaround 40 | try: 41 | sock.bind((mgroup, mport)) 42 | except socket.error: 43 | sock.bind(('', mport)) 44 | 45 | mreq = struct.pack("4sl", socket.inet_aton(group), socket.INADDR_ANY) 46 | 47 | sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 48 | 49 | print('Listing on ' + mgroup + ' port ' + str(mport)) 50 | 51 | while True: 52 | (data, address) = sock.recvfrom(12000) 53 | 54 | # Try to unpickle log record from a DatagramHandler 55 | try: 56 | lrtxt = pickle.loads(data[4:]) 57 | lr = logging.makeLogRecord(lrtxt) 58 | logger.handle(lr) 59 | 60 | # Print message normally 61 | except Exception as e: 62 | print('Exeception', str(e)) 63 | print('Received on ' + mgroup + ' from ' + address[0] + \ 64 | ' from port ' + str(address[1]) + ': ' + data) 65 | 66 | 67 | def sender(mgroup): 68 | 'Send to a multicast group' 69 | 70 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 71 | ttl_bin = struct.pack('@i', mttl) 72 | sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl_bin) 73 | while 1: 74 | time_now = datetime.now().strftime("%Y-%m-%d %H:%M:%S") 75 | mcast_msg = message + ': ' + time_now 76 | print('Sending to ' + mgroup + ' (TTL ' + str(mttl) + '): ' + mcast_msg) 77 | sock.sendto(mcast_msg, (mgroup, mport)) 78 | time.sleep(1) 79 | 80 | if args.group: 81 | group = args.group 82 | if args.ttl: 83 | mttl = int(args.ttl) 84 | if args.port: 85 | mport = args.port 86 | 87 | if args.send: 88 | message = args.send 89 | sender(group) 90 | elif args.receive: 91 | receiver(group) 92 | else: 93 | parser.print_help() 94 | --------------------------------------------------------------------------------