Skip to content

Instantly share code, notes, and snippets.

@tonusoo
Last active May 8, 2023 19:23
Show Gist options
  • Save tonusoo/17e6ff0472b032ddcf50a2a69dfd4a4a to your computer and use it in GitHub Desktop.
Save tonusoo/17e6ff0472b032ddcf50a2a69dfd4a4a to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
#
# Shows the delay between IGMPv2 "General Membership Query" and specific IGMPv2 "Membership Report".
# Example output:
#
# 22:01:01.561632 - 0.000 - IGMPv2 General Membership Query: 192.168.0.1 > 224.0.0.1: Max Resp Time: 10.00 s
# 22:01:02.124777 - 0.563 - IGMPv2 Membership Report: 192.168.0.100 > 239.3.5.3: Group Address: 239.3.5.3
#
# 22:01:13.337657 - 0.000 - IGMPv2 General Membership Query: 192.168.0.1 > 224.0.0.1: Max Resp Time: 10.00 s
# 22:01:19.994571 - 6.657 - IGMPv2 General Membership Query: 192.168.0.1 > 224.0.0.1: Max Resp Time: 10.00 s
# 22:01:22.094582 - 8.757 - IGMPv2 Membership Report: 192.168.0.100 > 239.3.5.3: Group Address: 239.3.5.3
#
import time
from datetime import datetime
from scapy.all import sniff, IP
from scapy.contrib.igmp import IGMP
query_received = None
def handler(pkt):
global query_received
#print(pkt.show())
if pkt[IGMP].type == 17 and pkt[IP].dst == "224.0.0.1":
if query_received is None:
query_received = time.time()
delta = 0.000
else:
delta = time.time() - query_received
print(f"{datetime.now().strftime('%H:%M:%S.%f')} - {delta:.3f} - "
"IGMPv2 General Membership Query: "
f"{pkt[IP].src} > {pkt[IP].dst}: Max Resp Time: "
f"{pkt[IGMP].mrcode/10:.2f} s")
elif pkt[IGMP].type == 22 and pkt[IGMP].gaddr == "239.3.5.1":
print(f"{datetime.now().strftime('%H:%M:%S.%f')} - NA - "
"IGMPv2 Membership Report: "
f"{pkt[IP].src} > {pkt[IP].dst}: Group Address: "
f"{pkt[IGMP].gaddr}")
elif pkt[IGMP].type == 22 and pkt[IGMP].gaddr == "239.3.5.3":
if query_received is not None:
print(f"{datetime.now().strftime('%H:%M:%S.%f')} - "
f"{time.time() - query_received:.3f} - "
"IGMPv2 Membership Report: "
f"{pkt[IP].src} > {pkt[IP].dst}: Group Address: "
f"{pkt[IGMP].gaddr}\n")
query_received = None
# ens3 is LAN-facing interface.
sniff(iface="ens3", filter="igmp", prn=handler, store=0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment