python программирование сокетов: создание пакета pim-join-prune - PullRequest
1 голос
/ 18 января 2020

Добрый день всем,

мои навыки кодирования не совсем на уровне, необходимом для самостоятельного программирования сокетов, и мне было интересно, может ли кто-нибудь здесь помочь мне с тем, что мне нужно - что довольно просто:

  • создание собственного пакета соединения PIM (многоадресная передача).

Я хочу отправить «фиктивные» пакеты присоединения PIM к соседнему устройству, не беспокоясь о поддержании любых смежностей PIM / (привет). В идеале я хочу закончить с функцией, которая принимает несколько аргументов:

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

В идеале мне нужно, чтобы она работала с использованием python3 без использования внешних модулей (например, scapy)

Другой Проблема, с которой я столкнулся и не совсем понимаю, как ее решить - это создание пакета с адресом источника, который не принадлежит ни одному сетевому интерфейсу в системе. Я знаю, что СКАПИ может сделать это, но я не совсем понимаю, как это сделать самому.

Заранее спасибо за вашу помощь. Очень ценится!

Некоторая внешняя информация.

Заголовки PIM

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

PIM. c реализация

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

1 Ответ

0 голосов
/ 19 января 2020

Я, скорее всего, ( вполне справедливо, хотя; -) ) публично линчуется для следующего фрагмента кода, но как один сетевой инженер для другого, ознакомьтесь с кодом ниже.

Еще несколько битов, которые нужно иметь в виду - сначала нужно "установить sh смежность" ( обменяться некоторыми приветственными пакетами ), иначе соединения PIM будут игнорироваться вышестоящим маршрутизатором ( следовательно добавлена ​​фиктивная функция приветствия).

Кроме того, «IP-адрес соседнего узла» также необходим при отправке соединений PIM.

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, и это (волшебно!) Сработало :-)

РЕДАКТИРОВАТЬ :

Код теперь отредактировано для поддержки вычисления контрольной суммы заголовка. Я думаю, что это теперь завершено! :-)

...