LINUX.ORG.RU

Имитация IGMPv3 трафика с помощью Scapy

 , , ,


0

1

Добрый день, пытаюсь понять как правильно имитировать трафик, что бы на маршрутизаторах появились записи о группах мультикаста. Схема проста, есть две убунты и два роутера между ними: U-R-R-U На них настроен PIM примерно так:

ip pim interface eth1 
ip pim interface eth2 
ip pim rp 50.50.50.1 group-prefix 230.0.0.30/32
ip pim rp 20.20.20.1 group-prefix 230.0.0.20/32
ip pim on

На убунтах слева направо я пытаюсь передавать пакеты IGMP сборку которых с горем пополам нашёл в интернетах: 1pc:

scapy
from scapy.all import * 
class IGMP3(Packet): 
  name = "IGMP3" 
  fields_desc = [ ByteField("type", 0x11), 
      ByteField("mrtime", 20), 
     XShortField("chksum", None), 
      IPField("gaddr", "230.0.0.30"), 
      IntField("others", 0x0)] 
  def post_build(self, p, pay): 
   p += pay 
   if self.chksum is None: 
    ck = checksum(p) 
    p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:] 
   return p

bind_layers(IP, IGMP3, frag=0, proto=2) 
p = IP(dst="224.0.0.22")/IGMP3() 
send(p, iface="eth1", loop=1,inter=0.01, count=100)
2pc:
from scapy.all import * 
class IGMP3(Packet): 
  name = "IGMP3" 
  fields_desc = [ ByteField("type", 0x22), 
      ByteField("mrtime", 20), 
     XShortField("chksum", None), 
      IPField("gaddr", "230.0.0.30"), 
      IntField("others", 0x0)] 
  def post_build(self, p, pay): 
   p += pay 
   if self.chksum is None: 
    ck = checksum(p) 
    p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:] 
   return p

bind_layers(IP, IGMP3, frag=0, proto=2) 
p = IP(dst="224.0.0.22")/IGMP3() 
send(p)

К сожалению ничего не выходит, если кто-то разбирается как это должно работать буду благодарен.

Вот так вот.

scapy
from scapy.packet import *
from scapy.all import *

conf.route.add(net="0.0.0.0/0",gw="30.30.30.1")

class IGMPv3gr(Packet):
  name = "IGMPv3gr"
  igmpv3grtypes = { 1 : "Mode Is Include",
                    2 : "Mode Is Exclude",
                    3 : "Change To Include Mode",
                    4 : "Change To Exclude Mode",
                    5 : "Allow New Sources",
                    6 : "Block Old Sources"}
  fields_desc = [ ByteEnumField("rtype", 1, igmpv3grtypes),
                  ByteField("auxdlen",0),
                  FieldLenField("numsrc", None, "srcaddrs"),
                  IPField("maddr", "0.0.0.0"),
                  FieldListField("srcaddrs", [], IPField("sa", "0.0.0.0"), "numsrc") ]
  def mysummary(self):
    return self.sprintf("IGMPv3 Group Record %IGMPv3gr.type% %IGMPv3gr.maddr%")
  def default_payload_class(self, payload):
    return conf.padding_layer


class IGMPv3mr(Packet):
    name = "IGMPv3mr"
    fields_desc = [XShortField("res2", 0),
                   FieldLenField("numgrp", None, count_of="records"),
                   PacketListField("records", [], IGMPv3gr, count_from=lambda x: x.numgrp)]




class IGMPv3(Packet): 
  name = "IGMPv3"
  igmpv3types = {0x11: "Membership Query",
                 0x22: "Version 3 Membership Report",
                 0x30: "Multicast Router Advertisement",
                 0x31: "Multicast Router Solicitation",
                 0x32: "Multicast Router Termination"}
  
  fields_desc = [ ByteEnumField("type", 0x22, igmpv3types),
                  ByteField("mrcode", 20),
                  XShortField("chksum", None)] 
  
  def post_build(self, p, pay):
    p += pay
    if self.type in [0, 0x31, 0x32, 0x22]:   # for these, field is reserved (0)
      p = p[:1]+chr(0)+p[2:]
    if self.chksum is None:
      ck = checksum(p)
      p = p[:2]+chr(ck>>8)+chr(ck&0xff)+p[4:]
    return p


bind_layers(IGMPv3, IGMPv3mr, type=0x22, mrcode=0x0) 
p = IP(frag=0, proto=2, ttl=1, tos=0xc0, dst='224.0.0.22', flags="DF")/IGMPv3()/IGMPv3mr(numgrp=1)/IGMPv3gr(maddr="232.0.0.20", srcaddrs="20.20.20.2", numsrc=1)
send(p, iface="eth1", loop=1,inter=0.1, count=100)
scapy
packet = Ether(dst='ff:ff:ff:ff:ff:ff')/IP(dst="232.0.0.20",src="50.50.50.2",len=1316,ttl=12,flags=2)/UDP(sport=55380,dport=10000)/"Hello!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
sendp(packet,iface="${ethertype1}${ethNum1}.101",loop=1,inter=0.1, count=2000)
exit()
freemadman ()