diff options
Diffstat (limited to 'tests/topotests/pim_basic/mcast-rx.py')
-rwxr-xr-x | tests/topotests/pim_basic/mcast-rx.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/tests/topotests/pim_basic/mcast-rx.py b/tests/topotests/pim_basic/mcast-rx.py new file mode 100755 index 0000000..d05ed1a --- /dev/null +++ b/tests/topotests/pim_basic/mcast-rx.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: ISC +# +# mcast-rx.py +# +# Copyright (c) 2018 Cumulus Networks, Inc. +# +""" +Subscribe to a multicast group so that the kernel sends an IGMP JOIN +for the multicast group we subscribed to. +""" + +import argparse +import logging +import re +import os +import socket +import subprocess +import struct +import sys +import time + + +def ifname_to_ifindex(ifname): + output = subprocess.check_output( + "ip link show %s" % ifname, shell=True, universal_newlines=True + ) + first_line = output.split("\n")[0] + re_index = re.search("^(\d+):", first_line) + + if re_index: + return int(re_index.group(1)) + + log.error("Could not parse the ifindex for %s out of\n%s" % (ifname, first_line)) + return None + + +# Thou shalt be root +if os.geteuid() != 0: + sys.stderr.write("ERROR: You must have root privileges\n") + sys.exit(1) + + +logging.basicConfig( + level=logging.DEBUG, format="%(asctime)s %(levelname)5s: %(message)s" +) + +# Color the errors and warnings in red +logging.addLevelName( + logging.ERROR, "\033[91m %s\033[0m" % logging.getLevelName(logging.ERROR) +) +logging.addLevelName( + logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING) +) +log = logging.getLogger(__name__) + +parser = argparse.ArgumentParser(description="Multicast RX utility") + +parser.add_argument("group", help="Multicast IP") +parser.add_argument("ifname", help="Interface name") +parser.add_argument("--port", help="UDP port", default=1000) +parser.add_argument("--sleep", help="Time to sleep before we stop waiting", default=5) +args = parser.parse_args() + +# Create the datagram socket +sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) +sock.bind((args.group, args.port)) + +newpid = os.fork() + +if newpid == 0: + ifindex = ifname_to_ifindex(args.ifname) + mreq = struct.pack( + "=4sLL", socket.inet_aton(args.group), socket.INADDR_ANY, ifindex + ) + sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) + time.sleep(float(args.sleep)) + sock.close() |