def inject_packet(self, iface, dst_mac): ether_part = Ether(src='00:00:00:00:00:00', dst=dst_mac) ip_part = IP(ttl=1, src='0.0.0.0', dst='224.0.0.1') igmp_part = IGMP(type=0x11) igmp_part.mrtime = (self.max_resp_time / 100) & 0xff igmp_part.igmpize(ether=ether_part, ip=ip_part) # Make this IGMP query packet as an unicast packet ether_part.dst = dst_mac sendp(ether_part / ip_part / igmp_part, iface=iface, verbose=False)
def calc_IPv4_overhead(IP_prot, src_IP, dst_IP, src_port, dst_port, TOS_val, TCP_flags, dTime): # Init packet p = IP() # ICMP Protocol if IP_prot == 1: # * This will only work with University of Oregon ICMP Netflow * # Discard for other netflows, or derive type and code another way temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ ICMP(type=type, code=code) # IGMP Protocol if IP_prot == 2: # * This will only work with University of Oregon IGMP Netflow * # Discard for other netflows, or derive type and code another way temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ IGMP(type=type, mrcode=code) # TCP Protocol elif IP_prot == 6: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ TCP(sport=src_port, dport=dst_port, flags=TCP_flags, window=dTime) # UDP Protocol elif IP_prot == 17: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ UDP(sport=src_port, dport=dst_port) # GRE (Generic Routing Encapsulation) Protocol elif IP_prot == 47: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ GRE() # ESP (Encapsulating Security Payload) Protocol elif IP_prot == 50: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ ESP() # Rare packets else: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) return p
def gen_IPv4(src_IP, dst_IP, src_port, dst_port, IP_prot, TOS_val, TCP_flags, packets, bytes, dTime): # Init packet p = IP() overhead = calc_IPv4_overhead(IP_prot, src_IP, dst_IP, src_port, dst_port, TOS_val, TCP_flags, dTime) # This creates a tiny degree of error bytes_left = bytes - len(overhead) * packets packet_size = int(bytes_left / packets) # Create a fake payload that justifies byte count of packets to correct amount payload = bytearray(random.getrandbits(8) for _ in xrange(packet_size)) if IP_prot == 1: temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ ICMP(type=type, code=code, length=packet_size) / Raw(payload) elif IP_prot == 2: temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ IGMP(type=type, mrcode=code) / Raw(payload) elif IP_prot == 6: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ TCP(sport=src_port, dport=dst_port, flags=TCP_flags) / Raw(payload) elif IP_prot == 17: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ UDP(sport=src_port, dport=dst_port, len=packet_size) / Raw(payload) elif IP_prot == 47: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ GRE() / Raw(payload) elif IP_prot == 50: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ ESP(data=payload) else: p = IP(src=src_IP, dst=dst_IP, proto=IP_prot, tos=TOS_val) / \ Raw(payload) return p
def sub(m_addr): addr = socket.gethostbyname(Network.get_default_gateway_linux()) mc_addr = socket.gethostbyname(m_addr) iface = Network.get_if() pkt = Ether(src=get_if_hwaddr(iface), dst='00:00:00:00:01:01') pkt = pkt / IP(dst=addr) / IGMP(type=0x17, gaddr=mc_addr) sendp(pkt, iface=iface, verbose=False) Log.info("Unsubscribed to", str(mc_addr))
def run(self): """Sends IGMP general query packets using the multicast address 224.0.0.1. Received replies are processed by a SniffThread. """ # create IGMP general query packet ether_part = Ether(src=self.mac) ip_part = IP(ttl=self._TTL, src=self.ip, dst=self._IGMP_MULTICAST) igmp_part = IGMP(type=self._IGMP_GENERAL_QUERY) # Called to explicitely fixup associated IP and Ethernet headers igmp_part.igmpize(ether=ether_part, ip=ip_part) while True: sendp(ether_part / ip_part / igmp_part) time.sleep(self._SLEEP)
def main(): addr = socket.gethostbyname(get_default_gateway_linux()) mc_addr = socket.gethostbyname(sys.argv[2]) iface = get_if() if sys.argv[1] == "subscribe": igmp_type = 0x16 else: igmp_type = 0x17 #print "sending on interface %s to %s" % (iface, str(addr)) pkt = Ether(src=get_if_hwaddr(iface), dst='00:00:00:00:01:01') pkt = pkt / IP(dst=addr) / IGMP(type=igmp_type, gaddr=mc_addr) sendp(pkt, iface=iface, verbose=False) if igmp_type == 0x16: print "Subscribed to " + str(mc_addr) if igmp_type == 0x17: print "Unsubscribed from " + str(mc_addr)
def test_non_routable_igmp_pkts(do_test, ptfadapter, duthost, setup, fanouthost, tx_dut_ports, pkt_fields, igmp_version, msg_type, ports_info): """ @summary: Create an IGMP non-routable packets. """ # IGMP Types: # 0x11 = Membership Query # 0x12 = Version 1 Membership Report # 0x16 = Version 2 Membership Report # 0x17 = Leave Group # IP destination address according to the RFC 2236: # Message Type Destination Group # ------------ ----------------- # General Query ALL-SYSTEMS (224.0.0.1) # Group-Specific Query The group being queried # Membership Report The group being reported # Leave Message ALL-ROUTERS (224.0.0.2) # TODO: fix this workaround as of now current PTF and Scapy versions do not support creation of IGMP packets # Temporaly created hex of IGMP packet layer by using scapy version 2.4.3. # Example how to get HEX of specific IGMP packets: # v3_membership_query = IGMPv3(type=0x11, mrcode=0, chksum=None)/scapy.contrib.igmpv3.IGMPv3mq(gaddr="224.0.0.1", # srcaddrs=["172.16.11.1", "10.0.0.59"], qrv=1, qqic=125, numsrc=2) # gr_obj = scapy.contrib.igmpv3.IGMPv3gr(rtype=1, auxdlen=0, maddr="224.2.2.4", numsrc=2, srcaddrs=["172.16.11.1", # "10.0.0.59"]).build() # v3_membership_report = IGMPv3(type=0x22, mrcode=0, chksum=None)/scapy.contrib.igmpv3.IGMPv3mr(res2=0x00, numgrp=1, # records=[gr_obj]).build() # The rest packets are build like "simple_igmp_packet" function from PTF testutils.py # FIXME: Need some sort of configuration for EOS and SONiC fanout hosts to # not drop IGMP packets before they reach the DUT if not fanouthost: pytest.skip("Test case requires explicit fanout support") from scapy.contrib.igmp import IGMP Ether = testutils.scapy.Ether IP = testutils.scapy.IP if "vlan" in tx_dut_ports[ports_info["dut_iface"]].lower( ) and msg_type == "membership_report": pytest.skip("Test case is not supported on VLAN interface") igmp_proto = 0x02 multicast_group_addr = "224.1.1.1" ethernet_dst = "01:00:5e:01:01:01" ip_dst = { "general_query": "224.0.0.1", "membership_report": multicast_group_addr } igmp_types = { "v1": { "general_query": IGMP(type=0x11, gaddr="224.0.0.1"), "membership_report": IGMP(type=0x12, gaddr=multicast_group_addr) }, "v2": { "membership_report": IGMP(type=0x16, gaddr=multicast_group_addr), "leave_group": IGMP(type=0x17, gaddr=multicast_group_addr) }, "v3": { "general_query": "\x11\x00L2\xe0\x00\x00\x01\x01}\x00\x02\xac\x10\x0b\x01\n\x00\x00;", "membership_report": "\"\x009\xa9\x00\x00\x00\x01\x01\x00\x00\x02\xe0\x02\x02\x04\xac\x10\x0b\x01\n\x00\x00;" } } if igmp_version == "v3": pkt = testutils.simple_ip_packet(eth_dst=ethernet_dst, eth_src=ports_info["src_mac"], ip_src=pkt_fields["ipv4_src"], ip_dst=ip_dst[msg_type], ip_ttl=1, ip_proto=igmp_proto) del pkt["Raw"] pkt = pkt / igmp_types[igmp_version][msg_type] else: eth_layer = Ether(src=ports_info["src_mac"], dst=ethernet_dst) ip_layer = IP(src=pkt_fields["ipv4_src"], ) igmp_layer = igmp_types[igmp_version][msg_type] assert igmp_layer.igmpize(ip=ip_layer, ether=eth_layer), "Can't create IGMP packet" pkt = eth_layer / ip_layer / igmp_layer log_pkt_params(ports_info["dut_iface"], ethernet_dst, ports_info["src_mac"], pkt.getlayer("IP").dst, pkt_fields["ipv4_src"]) do_test("L3", pkt, ptfadapter, duthost, ports_info, setup["dut_to_ptf_port_map"].values(), tx_dut_ports)
def calc_IPv6_overhead(IP_prot, src_IP, dst_IP, src_port, dst_port, TCP_flags, dTime): # Init packet p = IPv6() # ICMP Protocol if IP_prot == 1: # * This will only work with University of Oregon ICMP Netflow * # Discard for other netflows, or derive type and code another way temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ ICMP(type=type, code=code) # IGMP Protocol if IP_prot == 2: # * This will only work with University of Oregon IGMP Netflow * # Discard for other netflows, or derive type and code another way temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ IGMP(type=type, mrcode=code) # TCP Protocol elif IP_prot == 6: p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ TCP(sport=src_port, dport=dst_port, flags=TCP_flags, window=dTime) # UDP Protocol elif IP_prot == 17: p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ UDP(sport=src_port, dport=dst_port) # GRE (Generic Routing Encapsulation) Protocol elif IP_prot == 47: p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ GRE() # ESP (Encapsulating Security Payload) Protocol elif IP_prot == 50: p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ ESP() # ICMP Protocol for IPv6 elif IP_prot == 58: # * This will only work with University of Oregon IPv6 ICMP Netflow * # Discard for other netflows, derive type and code another way, or disregard type & code attributes temp = dst_port.split('.') type, code = int(temp[0]), int(temp[1]) p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ ICMP(type=type, code=code) # OSPF Protocol (Assuming OSPF Hello Packet) elif IP_prot == 89: p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) / \ OSPF_Hello(hellointerval=dTime) # Rare packets else: p = IPv6(src=src_IP, dst=dst_IP, nh=IP_prot) return p
""" from scapy.utils import rdpcap from scapy.contrib.igmp import IGMP eth = Ether(dst='01:00:5e:00:00:fb', type=0x800) ipoption = IPOption_Router_Alert(copy_flag=1, optclass='control', option='router_alert', length=4, alert='router_shall_examine_packet') number_of_packets = 10000 for p in range(number_of_packets): hi = p // 256 lo = p - 256 * hi gaddr = "224.224." + str(hi) + "." + str(lo) ip = IP(version=4, proto=2, ttl=1, src='10.255.0.1', dst=gaddr, options=[ipoption]) igmp = IGMP(type=0x16, mrcode=0, gaddr=gaddr) pkt = eth / ip / igmp pkt[IGMP].igmpize() sendp(pkt, iface='ens33') # interface on which the packets are sent out
# https://github.com/levigross/Scapy/blob/master/scapy/contrib/igmp.py # The function adjusts the IP header based on conformance rules # and the group address encoded in the IGMP message. # The rules are: # 1. Send General Group Query to 224.0.0.1 (all systems) # 2. Send Leave Group to 224.0.0.2 (all routers) # 3a.Otherwise send the packet to the group address # 3b.Send reports/joins to the group address #!/usr/bin/env python from scapy.all import * from scapy.contrib.igmp import IGMP eth = Ether() # Send General Group Query to 224.0.0.1 (all systems) iph = IP(src='192.168.1.1', dst='224.0.0.1', proto=2) igmp = IGMP(type=0x11, gaddr='0.0.0.0', mrtime=20) igmp.igmpize(iph,eth) sendp(eth/iph/igmp, iface="eth1", count=1) # Send Leave Group to 224.0.0.2 (all routers) iph = IP(src='192.168.1.42', dst='224.0.0.2', proto=2) igmp = IGMP(type=0x17, gaddr='239.0.0.58', mrtime=20) igmp.igmpize(iph,eth) sendp(eth/iph/igmp, iface="eth1", count=1) # Send reports/joins to the group address iph = IP(src='192.168.1.42', dst='239.0.0.59', proto=2) igmp = IGMP(type=0x16, gaddr='239.0.0.59', mrtime=20) igmp.igmpize(iph,eth) sendp(eth/iph/igmp, iface="eth1", count=1)
ipSet = [] with open(fileLocation) as f: lines = f.readlines() for line in lines: ipSet.append(line.strip('\n')) return ipSet testIpArr = readIpSetFromFile('ipSetV2.txt') while True: for i in range(len(testIpArr)): ip = testIpArr[i] ipIpy = IPy.IP(ip) ipYan = ipIpy.strBin()[-23:] ipYan = '0000000100000000010111100' + ipYan mac = hex(int(ipYan, 2))[2:] if (len(hex(int(ipYan, 2))[2:]) < 12): for j in range(12 - len(hex(int(ipYan, 2))[2:])): mac = '0' + mac mulMac = mac[0:2] + ':' + mac[2:4] + ':' + mac[4:6] + ':' + mac[6:8] + ':' + mac[8:10] + ':' + mac[10:12] print ip print mulMac p_join = Ether(dst=mulMac, src='a0:8c:fd:9e:2d:f1') / IP(src='10.0.0.123', dst=ip, ttl=1) /IGMP(type=0x16,gaddr=ip,mrcode=0x00) sendp(p_join,iface=interface) print '----------------' time.sleep(5)