]>
Commit | Line | Data |
---|---|---|
86439e8d DS |
1 | #!/usr/bin/env python |
2 | # | |
3 | # mcast-tx.py | |
4 | # | |
5 | # Copyright (c) 2018 Cumulus Networks, Inc. | |
6 | # | |
7 | # Permission to use, copy, modify, and/or distribute this software | |
8 | # for any purpose with or without fee is hereby granted, provided | |
9 | # that the above copyright notice and this permission notice appear | |
10 | # in all copies. | |
11 | # | |
12 | # THE SOFTWARE IS PROVIDED "AS IS" AND Cumulus Networks DISCLAIMS ALL WARRANTIES | |
13 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
14 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR | |
15 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY | |
16 | # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
17 | # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS | |
18 | # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
19 | # OF THIS SOFTWARE. | |
20 | # | |
21 | ||
22 | import argparse | |
23 | import logging | |
24 | import socket | |
25 | import struct | |
26 | import time | |
27 | ||
28 | ||
787e7624 | 29 | logging.basicConfig( |
30 | level=logging.DEBUG, format="%(asctime)s %(levelname)5s: %(message)s" | |
31 | ) | |
86439e8d DS |
32 | |
33 | # Color the errors and warnings in red | |
787e7624 | 34 | logging.addLevelName( |
35 | logging.ERROR, "\033[91m %s\033[0m" % logging.getLevelName(logging.ERROR) | |
36 | ) | |
37 | logging.addLevelName( | |
38 | logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING) | |
39 | ) | |
86439e8d DS |
40 | log = logging.getLogger(__name__) |
41 | ||
787e7624 | 42 | parser = argparse.ArgumentParser( |
43 | description="Multicast packet generator", version="1.0.0" | |
44 | ) | |
45 | parser.add_argument("group", help="Multicast IP") | |
46 | parser.add_argument("ifname", help="Interface name") | |
47 | parser.add_argument("--port", type=int, help="UDP port number", default=1000) | |
48 | parser.add_argument("--ttl", type=int, help="time-to-live", default=20) | |
49 | parser.add_argument("--count", type=int, help="Packets to send", default=1) | |
50 | parser.add_argument("--interval", type=int, help="ms between packets", default=100) | |
86439e8d DS |
51 | args = parser.parse_args() |
52 | ||
53 | # Create the datagram socket | |
54 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
55 | ||
56 | # IN.SO_BINDTODEVICE is not defined in some releases of python but it is 25 | |
57 | # https://github.com/sivel/bonding/issues/10 | |
58 | # | |
59 | # Bind our socket to ifname | |
787e7624 | 60 | sock.setsockopt( |
61 | socket.SOL_SOCKET, 25, struct.pack("%ds" % len(args.ifname), args.ifname) | |
62 | ) | |
86439e8d DS |
63 | |
64 | # We need to make sure our sendto() finishes before we close the socket | |
65 | sock.setblocking(1) | |
66 | ||
67 | # Set the time-to-live | |
787e7624 | 68 | sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, struct.pack("b", args.ttl)) |
86439e8d DS |
69 | |
70 | ms = args.interval / 1000.0 | |
71 | ||
72 | # Send data to the multicast group | |
73 | for x in xrange(args.count): | |
787e7624 | 74 | log.info( |
75 | "TX multicast UDP packet to %s:%d on %s" % (args.group, args.port, args.ifname) | |
76 | ) | |
77 | sent = sock.sendto("foobar %d" % x, (args.group, args.port)) | |
86439e8d DS |
78 | |
79 | if args.count > 1 and ms: | |
80 | time.sleep(ms) | |
81 | ||
82 | sock.close() |