python 套接字编程:制作 pim-join-prune 数据包

python socket programming: Crafting pim-join-prune packet

大家下午好,

我的编码技能还达不到自己进行套接字编程所需的水平,我想知道这里是否有人可以帮助我解决我需要的问题 - 这很简单:

我想将“虚拟”PIM 加入数据包发送到相邻设备,而无需真正维护任何 PIM 邻接/(你好)。理想情况下,我想 end-up 有一个接受几个参数的函数:

def send_dummy_join(group, rp, source_ip):
  // send 1 join every time this function is called

理想情况下,我需要 运行 使用 python3 而不是使用外部模块(例如 scapy)

另一个我遇到但不太明白如何解决的问题是制作一个源地址不属于系统上任何网络接口的数据包。我知道 scapy 可以做到这一点我只是不太了解如何自己制作它。

在此先感谢您的帮助。非常感谢!

一些外部信息。

PIM headers

http://www.networksorcery.com/enp/protocol/pim.htm

PIM.c实施

https://github.com/troglobit/pimd/blob/master/src/pim.c

我很可能(虽然完全正确 ;-))因以下代码段而被公开私刑,但作为一名网络工程师,另一名网络工程师请查看下面的代码。

还有几点要记住 - 您需要先 "establish adjacency"(交换一些 hello 数据包),否则您的 PIM 加入将被上游路由器忽略(因此添加了虚拟 hello 函数)。

此外,发送 PIM 加入时 "Upstream Neighbour IP" 也是必需的。

import socket
from struct import pack, iter_unpack
from functools import reduce    

def checksum(data):
    sum = reduce(lambda x, y: x + y, iter_unpack("!H",data))
    s = reduce(lambda x, y: x + y, sum)

    while (s >> 16):
        s = (s & 0xFFFF) + (s >> 16)
    s = ~s & 0xffff

    return s

def send_dummy_hello():
    PIM_GROUP = '224.0.0.13'

    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_PIM)
    my_packet=pack('!BBH3H4H4H4H', 32, 0, 24707, 1, 2, 105, 20, 4, 16121,
        16078, 19, 4, 0, 1, 21, 4, 256, 0)

    sock.sendto(my_packet, (PIM_GROUP,0))

def send_dummy_join(group, rp_addr, neighbor_ip):
    PIM_GROUP = '224.0.0.13'

    sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_PIM)

    pim_ver    = 35
    pim_res    = 0
    pktchksum  = 0
    pim_opts   = 256
    neighbor   = socket.inet_aton(neighbor_ip)
    ngroups    = 1
    holdtime   = 210
    subnet     = socket.inet_aton('1.0.0.32')
    group_a    = socket.inet_aton(group)
    num_joins  = 1
    num_prunes = 0
    rrp_subnet = socket.inet_aton('1.0.7.32')
    rp_address = socket.inet_aton(rp_addr)

    my_packet = pack('!BB2H4sHH4s4sHH4s4s', pim_ver, pim_res, pktchksum, pim_opts,
        neighbor, ngroups, holdtime, subnet, group_a, num_joins, num_prunes, 
        rrp_subnet, rp_address)

    pktchksum = checksum(my_packet)
    my_packet = pack('!BB2H4sHH4s4sHH4s4s', pim_ver, pim_res, pktchksum, pim_opts,
        neighbor, ngroups, holdtime, subnet, group_a, num_joins, num_prunes, 
        rrp_subnet, rp_address)

    sock.sendto(my_packet, (PIM_GROUP,0))
    print (f'PIM Join sent to {neighbor_ip} for {group} & RP {rp_addr}')

>>>send_dummy_hello() 
>>>send_dummy_join('239.10.20.30','192.168.0.1','10.0.0.102')


我用 EVE-NG 测试了它,它(神奇地!)起作用了 :-)

编辑:

现在编辑代码以支持 header 校验和计算。我想现在已经完成了! :-)