Commit 8eca3c59 authored by Pedro Oliveira's avatar Pedro Oliveira

Use pimdm package (to avoid collision of modules/classes from 3rd parties)

parent a3fd05f5
name: Upload Python Package
on:
release:
types: [created]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v1
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build and publish
env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
python setup.py sdist bdist_wheel
twine upload dist/*
#!/usr/bin/env python #!/usr/bin/env python3
from Daemon.Daemon import Daemon from pimdm import Run
import Main
import _pickle as pickle
import socket
import sys
import os
import argparse
import traceback
if __name__ == '__main__':
def client_socket(data_to_send): Run.main()
# Create a UDS socket \ No newline at end of file
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = '/tmp/pim_uds_socket'
#print('connecting to %s' % server_address)
try:
sock.connect(server_address)
sock.sendall(pickle.dumps(data_to_send))
data_rcv = sock.recv(1024 * 256)
if data_rcv:
print(pickle.loads(data_rcv))
except socket.error:
pass
finally:
#print('closing socket')
sock.close()
class MyDaemon(Daemon):
def run(self):
Main.main()
server_address = '/tmp/pim_uds_socket'
# Make sure the socket does not already exist
try:
os.unlink(server_address)
except OSError:
if os.path.exists(server_address):
raise
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Bind the socket to the port
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
while True:
try:
connection, client_address = sock.accept()
data = connection.recv(256 * 1024)
print(sys.stderr, 'sending data back to the client')
print(pickle.loads(data))
args = pickle.loads(data)
if 'list_interfaces' in args and args.list_interfaces:
connection.sendall(pickle.dumps(Main.list_enabled_interfaces()))
elif 'list_neighbors' in args and args.list_neighbors:
connection.sendall(pickle.dumps(Main.list_neighbors()))
elif 'list_state' in args and args.list_state:
connection.sendall(pickle.dumps(Main.list_state()))
elif 'add_interface' in args and args.add_interface:
Main.add_pim_interface(args.add_interface[0], False)
connection.shutdown(socket.SHUT_RDWR)
elif 'add_interface_sr' in args and args.add_interface_sr:
Main.add_pim_interface(args.add_interface_sr[0], True)
connection.shutdown(socket.SHUT_RDWR)
elif 'add_interface_igmp' in args and args.add_interface_igmp:
Main.add_igmp_interface(args.add_interface_igmp[0])
connection.shutdown(socket.SHUT_RDWR)
elif 'remove_interface' in args and args.remove_interface:
Main.remove_interface(args.remove_interface[0], pim=True)
connection.shutdown(socket.SHUT_RDWR)
elif 'remove_interface_igmp' in args and args.remove_interface_igmp:
Main.remove_interface(args.remove_interface_igmp[0], igmp=True)
connection.shutdown(socket.SHUT_RDWR)
elif 'stop' in args and args.stop:
Main.stop()
connection.shutdown(socket.SHUT_RDWR)
elif 'test' in args and args.test:
Main.test(args.test[0], args.test[1])
connection.shutdown(socket.SHUT_RDWR)
except Exception:
connection.shutdown(socket.SHUT_RDWR)
traceback.print_exc()
finally:
# Clean up the connection
connection.close()
def main():
"""
Entry point for PIM-DM
"""
parser = argparse.ArgumentParser(description='PIM-DM protocol')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-start", "--start", action="store_true", default=False, help="Start PIM")
group.add_argument("-stop", "--stop", action="store_true", default=False, help="Stop PIM")
group.add_argument("-restart", "--restart", action="store_true", default=False, help="Restart PIM")
group.add_argument("-li", "--list_interfaces", action="store_true", default=False, help="List All PIM Interfaces")
group.add_argument("-ln", "--list_neighbors", action="store_true", default=False, help="List All PIM Neighbors")
group.add_argument("-ls", "--list_state", action="store_true", default=False, help="List state of IGMP")
group.add_argument("-mr", "--multicast_routes", action="store_true", default=False, help="List Multicast Routing table")
group.add_argument("-ai", "--add_interface", nargs=1, metavar='INTERFACE_NAME', help="Add PIM interface")
group.add_argument("-aisr", "--add_interface_sr", nargs=1, metavar='INTERFACE_NAME', help="Add PIM interface with State Refresh enabled")
group.add_argument("-aiigmp", "--add_interface_igmp", nargs=1, metavar='INTERFACE_NAME', help="Add IGMP interface")
group.add_argument("-ri", "--remove_interface", nargs=1, metavar='INTERFACE_NAME', help="Remove PIM interface")
group.add_argument("-riigmp", "--remove_interface_igmp", nargs=1, metavar='INTERFACE_NAME', help="Remove IGMP interface")
group.add_argument("-v", "--verbose", action="store_true", default=False, help="Verbose (print all debug messages)")
group.add_argument("-t", "--test", nargs=2, metavar=('ROUTER_NAME', 'SERVER_LOG_IP'), help="Tester... send log information to SERVER_LOG_IP. Set the router name to ROUTER_NAME")
args = parser.parse_args()
#print(parser.parse_args())
daemon = MyDaemon('/tmp/Daemon-pim.pid')
if args.start:
print("start")
daemon.start()
sys.exit(0)
elif args.stop:
client_socket(args)
daemon.stop()
sys.exit(0)
elif args.restart:
daemon.restart()
sys.exit(0)
elif args.verbose:
os.system("tail -f stdout")
sys.exit(0)
elif args.multicast_routes:
os.system("ip mroute show")
sys.exit(0)
elif not daemon.is_running():
print("PIM is not running")
parser.print_usage()
sys.exit(0)
client_socket(args)
if __name__ == "__main__":
main()
...@@ -22,9 +22,10 @@ class Daemon: ...@@ -22,9 +22,10 @@ class Daemon:
sys.exit(1) sys.exit(1)
# decouple from parent environment # decouple from parent environment
#os.chdir('/') os.makedirs('/var/log/pimdm/')
#os.setsid() os.chdir('/var/log/pimdm/')
#os.umask(0) os.setsid()
os.umask(0)
# do second fork # do second fork
try: try:
......
import socket import socket
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import threading import threading
import random
import netifaces
from Packet.ReceivedPacket import ReceivedPacket
import Main
import traceback import traceback
from RWLock.RWLock import RWLockWrite
class Interface(metaclass=ABCMeta): class Interface(metaclass=ABCMeta):
......
...@@ -3,9 +3,9 @@ import struct ...@@ -3,9 +3,9 @@ import struct
from ipaddress import IPv4Address from ipaddress import IPv4Address
from ctypes import create_string_buffer, addressof from ctypes import create_string_buffer, addressof
import netifaces import netifaces
from Packet.ReceivedPacket import ReceivedPacket from pimdm.Interface import Interface
from Interface import Interface from pimdm.Packet.ReceivedPacket import ReceivedPacket
from utils import Version_1_Membership_Report, Version_2_Membership_Report, Leave_Group, Membership_Query from pimdm.igmp.igmp_globals import Version_1_Membership_Report, Version_2_Membership_Report, Leave_Group, Membership_Query
if not hasattr(socket, 'SO_BINDTODEVICE'): if not hasattr(socket, 'SO_BINDTODEVICE'):
socket.SO_BINDTODEVICE = 25 socket.SO_BINDTODEVICE = 25
...@@ -44,7 +44,7 @@ class InterfaceIGMP(Interface): ...@@ -44,7 +44,7 @@ class InterfaceIGMP(Interface):
rcv_s.bind((interface_name, 0x0800)) rcv_s.bind((interface_name, 0x0800))
super().__init__(interface_name=interface_name, recv_socket=rcv_s, send_socket=snd_s, vif_index=vif_index) super().__init__(interface_name=interface_name, recv_socket=rcv_s, send_socket=snd_s, vif_index=vif_index)
self.interface_enabled = True self.interface_enabled = True
from igmp.RouterState import RouterState from pimdm.igmp.RouterState import RouterState
self.interface_state = RouterState(self) self.interface_state = RouterState(self)
super()._enable() super()._enable()
......
import random import random
from Interface import Interface from pimdm.Interface import Interface
from Packet.ReceivedPacket import ReceivedPacket from pimdm.Packet.ReceivedPacket import ReceivedPacket
import Main from pimdm import Main
import traceback import traceback
from RWLock.RWLock import RWLockWrite from pimdm.RWLock.RWLock import RWLockWrite
from Packet.PacketPimHelloOptions import * from pimdm.Packet.PacketPimHelloOptions import *
from Packet.PacketPimHello import PacketPimHello from pimdm.Packet.PacketPimHello import PacketPimHello
from Packet.PacketPimHeader import PacketPimHeader from pimdm.Packet.PacketPimHeader import PacketPimHeader
from Packet.Packet import Packet from pimdm.Packet.Packet import Packet
from utils import HELLO_HOLD_TIME_TIMEOUT from pimdm.utils import HELLO_HOLD_TIME_TIMEOUT
from threading import Timer from threading import Timer
from tree.globals import REFRESH_INTERVAL from pimdm.tree.globals import REFRESH_INTERVAL
import socket import socket
import netifaces import netifaces
import logging import logging
...@@ -234,7 +234,7 @@ class InterfacePim(Interface): ...@@ -234,7 +234,7 @@ class InterfacePim(Interface):
if hello_hold_time == 0: if hello_hold_time == 0:
return return
print("ADD NEIGHBOR") print("ADD NEIGHBOR")
from Neighbor import Neighbor from pimdm.Neighbor import Neighbor
self.neighbors[ip] = Neighbor(self, ip, generation_id, hello_hold_time, state_refresh_capable) self.neighbors[ip] = Neighbor(self, ip, generation_id, hello_hold_time, state_refresh_capable)
self.force_send_hello() self.force_send_hello()
self.check_number_of_neighbors() self.check_number_of_neighbors()
......
import socket import socket
import struct import struct
from threading import Lock, Thread from threading import RLock, Thread
import traceback import traceback
import ipaddress import ipaddress
from RWLock.RWLock import RWLockWrite from pimdm.RWLock.RWLock import RWLockWrite
import Main
import UnicastRouting from pimdm.InterfacePIM import InterfacePim
from InterfacePIM import InterfacePim from pimdm.InterfaceIGMP import InterfaceIGMP
from InterfaceIGMP import InterfaceIGMP from pimdm.tree.KernelEntry import KernelEntry
from tree.KernelEntry import KernelEntry from pimdm import UnicastRouting, Main
class Kernel: class Kernel:
# MRT # MRT
...@@ -69,7 +68,7 @@ class Kernel: ...@@ -69,7 +68,7 @@ class Kernel:
self.socket = s self.socket = s
self.rwlock = RWLockWrite() self.rwlock = RWLockWrite()
self.interface_lock = Lock() self.interface_lock = RLock()
# Create register interface # Create register interface
# todo useless in PIM-DM... useful in PIM-SM # todo useless in PIM-DM... useful in PIM-SM
...@@ -108,12 +107,12 @@ class Kernel: ...@@ -108,12 +107,12 @@ class Kernel:
struct_mrt_add_vif = struct.pack("HBBI 4s 4s", index, flags, 1, 0, ip_interface, struct_mrt_add_vif = struct.pack("HBBI 4s 4s", index, flags, 1, 0, ip_interface,
socket.inet_aton("0.0.0.0")) socket.inet_aton("0.0.0.0"))
with self.rwlock.genWlock():
self.socket.setsockopt(socket.IPPROTO_IP, Kernel.MRT_ADD_VIF, struct_mrt_add_vif) self.socket.setsockopt(socket.IPPROTO_IP, Kernel.MRT_ADD_VIF, struct_mrt_add_vif)
self.vif_dic[socket.inet_ntoa(ip_interface)] = index self.vif_dic[socket.inet_ntoa(ip_interface)] = index
self.vif_index_to_name_dic[index] = interface_name self.vif_index_to_name_dic[index] = interface_name
self.vif_name_to_index_dic[interface_name] = index self.vif_name_to_index_dic[interface_name] = index
with self.rwlock.genWlock():
for source_dict in list(self.routing.values()): for source_dict in list(self.routing.values()):
for kernel_entry in list(source_dict.values()): for kernel_entry in list(source_dict.values()):
kernel_entry.new_interface(index) kernel_entry.new_interface(index)
......
import netifaces
import time
from prettytable import PrettyTable
import sys import sys
import time
import netifaces
import logging, logging.handlers import logging, logging.handlers
from TestLogger import RootFilter from prettytable import PrettyTable
from pimdm.TestLogger import RootFilter
from pimdm import UnicastRouting
from Kernel import Kernel
import UnicastRouting
interfaces = {} # interfaces with multicast routing enabled interfaces = {} # interfaces with multicast routing enabled
igmp_interfaces = {} # igmp interfaces igmp_interfaces = {} # igmp interfaces
...@@ -176,6 +175,7 @@ def main(): ...@@ -176,6 +175,7 @@ def main():
logger.addHandler(logging.StreamHandler(sys.stdout)) logger.addHandler(logging.StreamHandler(sys.stdout))
global kernel global kernel
from pimdm.Kernel import Kernel
kernel = Kernel() kernel = Kernel()
global unicast_routing global unicast_routing
......
from threading import Timer from threading import Timer
import time import time
from utils import HELLO_HOLD_TIME_NO_TIMEOUT, HELLO_HOLD_TIME_TIMEOUT, TYPE_CHECKING from pimdm.utils import HELLO_HOLD_TIME_NO_TIMEOUT, HELLO_HOLD_TIME_TIMEOUT, TYPE_CHECKING
from threading import Lock, RLock from threading import Lock, RLock
import Main
import logging import logging
if TYPE_CHECKING: if TYPE_CHECKING:
from InterfacePIM import InterfacePim from pimdm.InterfacePIM import InterfacePim
class Neighbor: class Neighbor:
......
import struct import struct
from utils import checksum from pimdm.utils import checksum
import socket import socket
from .PacketPayload import PacketPayload from .PacketPayload import PacketPayload
''' '''
......
import struct import struct
import socket import socket
from Packet.PacketPimEncodedGroupAddress import PacketPimEncodedGroupAddress from .PacketPimEncodedGroupAddress import PacketPimEncodedGroupAddress
from Packet.PacketPimEncodedUnicastAddress import PacketPimEncodedUnicastAddress from .PacketPimEncodedUnicastAddress import PacketPimEncodedUnicastAddress
from tree.globals import ASSERT_CANCEL_METRIC from pimdm.tree.globals import ASSERT_CANCEL_METRIC
''' '''
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
......
from Packet.PacketPimJoinPrune import PacketPimJoinPrune from .PacketPimJoinPrune import PacketPimJoinPrune
''' '''
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
......
from Packet.PacketPimJoinPrune import PacketPimJoinPrune from .PacketPimJoinPrune import PacketPimJoinPrune
''' '''
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
......
import struct import struct
from Packet.PacketPimHello import PacketPimHello from .PacketPimHello import PacketPimHello
from Packet.PacketPimJoinPrune import PacketPimJoinPrune from .PacketPimJoinPrune import PacketPimJoinPrune
from Packet.PacketPimAssert import PacketPimAssert from .PacketPimAssert import PacketPimAssert
from Packet.PacketPimGraft import PacketPimGraft from .PacketPimGraft import PacketPimGraft
from Packet.PacketPimGraftAck import PacketPimGraftAck from .PacketPimGraftAck import PacketPimGraftAck
from Packet.PacketPimStateRefresh import PacketPimStateRefresh from .PacketPimStateRefresh import PacketPimStateRefresh
from utils import checksum from pimdm.utils import checksum
from .PacketPayload import PacketPayload from .PacketPayload import PacketPayload
''' '''
0 1 2 3 0 1 2 3
......
import struct import struct
import socket import socket
from Packet.PacketPimEncodedUnicastAddress import PacketPimEncodedUnicastAddress from .PacketPimEncodedUnicastAddress import PacketPimEncodedUnicastAddress
from Packet.PacketPimJoinPruneMulticastGroup import PacketPimJoinPruneMulticastGroup from .PacketPimJoinPruneMulticastGroup import PacketPimJoinPruneMulticastGroup
''' '''
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
......
import struct import struct
import socket import socket
from Packet.PacketPimEncodedGroupAddress import PacketPimEncodedGroupAddress from .PacketPimEncodedGroupAddress import PacketPimEncodedGroupAddress
from Packet.PacketPimEncodedSourceAddress import PacketPimEncodedSourceAddress from .PacketPimEncodedSourceAddress import PacketPimEncodedSourceAddress
''' '''
0 1 2 3 0 1 2 3
......
import struct import struct
import socket import socket
from Packet.PacketPimEncodedUnicastAddress import PacketPimEncodedUnicastAddress from .PacketPimEncodedUnicastAddress import PacketPimEncodedUnicastAddress
from Packet.PacketPimEncodedGroupAddress import PacketPimEncodedGroupAddress from .PacketPimEncodedGroupAddress import PacketPimEncodedGroupAddress
''' '''
0 1 2 3 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
......
from Packet.Packet import Packet from .Packet import Packet
from Packet.PacketIpHeader import PacketIpHeader from .PacketIpHeader import PacketIpHeader
from Packet.PacketIGMPHeader import PacketIGMPHeader from .PacketIGMPHeader import PacketIGMPHeader
from .PacketPimHeader import PacketPimHeader from .PacketPimHeader import PacketPimHeader
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from Interface import Interface from pimdm.Interface import Interface
class ReceivedPacket(Packet): class ReceivedPacket(Packet):
......
#!/usr/bin/env python3
from pimdm.Daemon.Daemon import Daemon
from pimdm import Main
import _pickle as pickle
import socket
import sys
import os
import argparse
import traceback
def client_socket(data_to_send):
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Connect the socket to the port where the server is listening
server_address = '/tmp/pim_uds_socket'
#print('connecting to %s' % server_address)
try:
sock.connect(server_address)
sock.sendall(pickle.dumps(data_to_send))
data_rcv = sock.recv(1024 * 256)
if data_rcv:
print(pickle.loads(data_rcv))
except socket.error:
pass
finally:
#print('closing socket')
sock.close()
class MyDaemon(Daemon):
def run(self):
Main.main()
server_address = '/tmp/pim_uds_socket'
# Make sure the socket does not already exist
try:
os.unlink(server_address)
except OSError:
if os.path.exists(server_address):
raise
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
# Bind the socket to the port
sock.bind(server_address)
# Listen for incoming connections
sock.listen(1)
while True:
try:
connection, client_address = sock.accept()
data = connection.recv(256 * 1024)
print(sys.stderr, 'sending data back to the client')
print(pickle.loads(data))
args = pickle.loads(data)
if 'list_interfaces' in args and args.list_interfaces:
connection.sendall(pickle.dumps(Main.list_enabled_interfaces()))
elif 'list_neighbors' in args and args.list_neighbors:
connection.sendall(pickle.dumps(Main.list_neighbors()))
elif 'list_state' in args and args.list_state:
connection.sendall(pickle.dumps(Main.list_state()))
elif 'add_interface' in args and args.add_interface:
Main.add_pim_interface(args.add_interface[0], False)
connection.shutdown(socket.SHUT_RDWR)
elif 'add_interface_sr' in args and args.add_interface_sr:
Main.add_pim_interface(args.add_interface_sr[0], True)
connection.shutdown(socket.SHUT_RDWR)
elif 'add_interface_igmp' in args and args.add_interface_igmp:
Main.add_igmp_interface(args.add_interface_igmp[0])
connection.shutdown(socket.SHUT_RDWR)
elif 'remove_interface' in args and args.remove_interface:
Main.remove_interface(args.remove_interface[0], pim=True)
connection.shutdown(socket.SHUT_RDWR)
elif 'remove_interface_igmp' in args and args.remove_interface_igmp:
Main.remove_interface(args.remove_interface_igmp[0], igmp=True)
connection.shutdown(socket.SHUT_RDWR)
elif 'stop' in args and args.stop:
Main.stop()
connection.shutdown(socket.SHUT_RDWR)
elif 'test' in args and args.test:
Main.test(args.test[0], args.test[1])
connection.shutdown(socket.SHUT_RDWR)
except Exception:
connection.shutdown(socket.SHUT_RDWR)
traceback.print_exc()
finally:
# Clean up the connection
connection.close()
def main():
"""
Entry point for PIM-DM
"""
parser = argparse.ArgumentParser(description='PIM-DM protocol')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-start", "--start", action="store_true", default=False, help="Start PIM")
group.add_argument("-stop", "--stop", action="store_true", default=False, help="Stop PIM")
group.add_argument("-restart", "--restart", action="store_true", default=False, help="Restart PIM")
group.add_argument("-li", "--list_interfaces", action="store_true", default=False, help="List All PIM Interfaces")
group.add_argument("-ln", "--list_neighbors", action="store_true", default=False, help="List All PIM Neighbors")
group.add_argument("-ls", "--list_state", action="store_true", default=False, help="List state of IGMP")
group.add_argument("-mr", "--multicast_routes", action="store_true", default=False, help="List Multicast Routing table")
group.add_argument("-ai", "--add_interface", nargs=1, metavar='INTERFACE_NAME', help="Add PIM interface")
group.add_argument("-aisr", "--add_interface_sr", nargs=1, metavar='INTERFACE_NAME', help="Add PIM interface with State Refresh enabled")
group.add_argument("-aiigmp", "--add_interface_igmp", nargs=1, metavar='INTERFACE_NAME', help="Add IGMP interface")
group.add_argument("-ri", "--remove_interface", nargs=1, metavar='INTERFACE_NAME', help="Remove PIM interface")
group.add_argument("-riigmp", "--remove_interface_igmp", nargs=1, metavar='INTERFACE_NAME', help="Remove IGMP interface")
group.add_argument("-v", "--verbose", action="store_true", default=False, help="Verbose (print all debug messages)")
group.add_argument("-t", "--test", nargs=2, metavar=('ROUTER_NAME', 'SERVER_LOG_IP'), help="Tester... send log information to SERVER_LOG_IP. Set the router name to ROUTER_NAME")
args = parser.parse_args()
#print(parser.parse_args())
# This script must be run as root!
if os.geteuid() != 0:
sys.exit('PIM-DM must be run as root!')
daemon = MyDaemon('/tmp/Daemon-pim.pid')
if args.start:
print("start")
daemon.start()
sys.exit(0)
elif args.stop:
client_socket(args)
daemon.stop()
sys.exit(0)
elif args.restart:
daemon.restart()
sys.exit(0)
elif args.verbose:
os.system("tail -f /var/log/pimdm/stdout")
sys.exit(0)
elif args.multicast_routes:
os.system("ip mroute show")
sys.exit(0)
elif not daemon.is_running():
print("PIM-DM is not running")
parser.print_usage()
sys.exit(0)
client_socket(args)
if __name__ == "__main__":
main()
import socket import socket
import ipaddress import ipaddress
from pyroute2 import IPDB, IPRoute from pyroute2 import IPDB
from threading import RLock
import Main from pimdm.utils import if_indextoname
from utils import if_indextoname
def get_route(ip_dst: str): def get_route(ip_dst: str):
...@@ -24,9 +24,10 @@ def get_unicast_info(ip_dst): ...@@ -24,9 +24,10 @@ def get_unicast_info(ip_dst):
class UnicastRouting(object): class UnicastRouting(object):
ipdb = None ipdb = None
lock = RLock()
def __init__(self): def __init__(self):
UnicastRouting.ipr = IPRoute() #UnicastRouting.ipr = IPRoute()
UnicastRouting.ipdb = IPDB() UnicastRouting.ipdb = IPDB()
self._ipdb = UnicastRouting.ipdb self._ipdb = UnicastRouting.ipdb
self._ipdb.register_callback(UnicastRouting.unicast_changes, mode="post") self._ipdb.register_callback(UnicastRouting.unicast_changes, mode="post")
...@@ -50,6 +51,7 @@ class UnicastRouting(object): ...@@ -50,6 +51,7 @@ class UnicastRouting(object):
ip_bytes = socket.inet_aton(ip_dst) ip_bytes = socket.inet_aton(ip_dst)
ip_int = int.from_bytes(ip_bytes, byteorder='big') ip_int = int.from_bytes(ip_bytes, byteorder='big')
info = None info = None
with UnicastRouting.lock:
ipdb = UnicastRouting.ipdb # type:IPDB ipdb = UnicastRouting.ipdb # type:IPDB
for mask_len in range(32, 0, -1): for mask_len in range(32, 0, -1):
...@@ -77,6 +79,7 @@ class UnicastRouting(object): ...@@ -77,6 +79,7 @@ class UnicastRouting(object):
rpf_node = ip_dst rpf_node = ip_dst
oif = None oif = None
mask = 0 mask = 0
with UnicastRouting.lock:
unicast_route = UnicastRouting.get_route(ip_dst) unicast_route = UnicastRouting.get_route(ip_dst)
if unicast_route is not None: if unicast_route is not None:
oif = unicast_route.get("oif") oif = unicast_route.get("oif")
...@@ -103,6 +106,7 @@ class UnicastRouting(object): ...@@ -103,6 +106,7 @@ class UnicastRouting(object):
mask = unicast_route["dst_len"] mask = unicast_route["dst_len"]
interface_name = None if oif is None else if_indextoname(int(oif)) interface_name = None if oif is None else if_indextoname(int(oif))
from pimdm import Main
rpf_if = Main.kernel.vif_name_to_index_dic.get(interface_name) rpf_if = Main.kernel.vif_name_to_index_dic.get(interface_name)
return (metric_administrative_distance, metric_cost, rpf_node, rpf_if, mask) return (metric_administrative_distance, metric_cost, rpf_node, rpf_if, mask)
...@@ -110,6 +114,7 @@ class UnicastRouting(object): ...@@ -110,6 +114,7 @@ class UnicastRouting(object):
def unicast_changes(ipdb, msg, action): def unicast_changes(ipdb, msg, action):
print("unicast change?") print("unicast change?")
print(action) print(action)
UnicastRouting.lock.acquire()
if action == "RTM_NEWROUTE" or action == "RTM_DELROUTE": if action == "RTM_NEWROUTE" or action == "RTM_DELROUTE":
print(ipdb.routes) print(ipdb.routes)
mask_len = msg["dst_len"] mask_len = msg["dst_len"]
...@@ -128,6 +133,8 @@ class UnicastRouting(object): ...@@ -128,6 +133,8 @@ class UnicastRouting(object):
print(network_address + "/" + str(mask_len)) print(network_address + "/" + str(mask_len))
subnet = ipaddress.ip_network(network_address + "/" + str(mask_len)) subnet = ipaddress.ip_network(network_address + "/" + str(mask_len))
print(str(subnet)) print(str(subnet))
UnicastRouting.lock.release()
from pimdm import Main
Main.kernel.notify_unicast_changes(subnet) Main.kernel.notify_unicast_changes(subnet)
''' '''
elif action == "RTM_NEWADDR" or action == "RTM_DELADDR": elif action == "RTM_NEWADDR" or action == "RTM_DELADDR":
...@@ -169,9 +176,11 @@ class UnicastRouting(object): ...@@ -169,9 +176,11 @@ class UnicastRouting(object):
subnet = ipaddress.ip_network("0.0.0.0/0") subnet = ipaddress.ip_network("0.0.0.0/0")
Main.kernel.notify_unicast_changes(subnet) Main.kernel.notify_unicast_changes(subnet)
''' '''
else:
UnicastRouting.lock.release()
def stop(self): def stop(self):
if UnicastRouting.ipdb:
UnicastRouting.ipdb = None
if self._ipdb: if self._ipdb:
self._ipdb.release() self._ipdb.release()
if UnicastRouting.ipdb:
UnicastRouting.ipdb = None
...@@ -2,8 +2,9 @@ import logging ...@@ -2,8 +2,9 @@ import logging
from threading import Lock from threading import Lock
from threading import Timer from threading import Timer
from utils import GroupMembershipInterval, LastMemberQueryInterval, TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from .wrapper import NoMembersPresent from .wrapper import NoMembersPresent
from .igmp_globals import GroupMembershipInterval, LastMemberQueryInterval
if TYPE_CHECKING: if TYPE_CHECKING:
from .RouterState import RouterState from .RouterState import RouterState
......
from threading import Timer from threading import Timer
import logging import logging
from Packet.PacketIGMPHeader import PacketIGMPHeader from pimdm.Packet.PacketIGMPHeader import PacketIGMPHeader
from Packet.ReceivedPacket import ReceivedPacket from pimdm.Packet.ReceivedPacket import ReceivedPacket
from utils import Membership_Query, QueryResponseInterval, QueryInterval, OtherQuerierPresentInterval, TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from RWLock.RWLock import RWLockWrite from pimdm.RWLock.RWLock import RWLockWrite
from .querier.Querier import Querier from .querier.Querier import Querier
from .nonquerier.NonQuerier import NonQuerier from .nonquerier.NonQuerier import NonQuerier
from .GroupState import GroupState from .GroupState import GroupState
from .igmp_globals import Membership_Query, QueryResponseInterval, QueryInterval, OtherQuerierPresentInterval
if TYPE_CHECKING: if TYPE_CHECKING:
from InterfaceIGMP import InterfaceIGMP from pimdm.InterfaceIGMP import InterfaceIGMP
class RouterState(object): class RouterState(object):
......
# IGMP timers (in seconds)
RobustnessVariable = 2
QueryInterval = 125
QueryResponseInterval = 10
MaxResponseTime_QueryResponseInterval = QueryResponseInterval*10
GroupMembershipInterval = RobustnessVariable * QueryInterval + QueryResponseInterval
OtherQuerierPresentInterval = RobustnessVariable * QueryInterval + QueryResponseInterval/2
StartupQueryInterval = QueryInterval / 4
StartupQueryCount = RobustnessVariable
LastMemberQueryInterval = 1
MaxResponseTime_LastMemberQueryInterval = LastMemberQueryInterval*10
LastMemberQueryCount = RobustnessVariable
UnsolicitedReportInterval = 10
Version1RouterPresentTimeout = 400
# IGMP msg type
Membership_Query = 0x11
Version_1_Membership_Report = 0x12
Version_2_Membership_Report = 0x16
Leave_Group = 0x17
\ No newline at end of file
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..wrapper import NoMembersPresent from ..wrapper import NoMembersPresent
from ..wrapper import MembersPresent from ..wrapper import MembersPresent
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..wrapper import NoMembersPresent from ..wrapper import NoMembersPresent
from ..wrapper import CheckingMembership from ..wrapper import CheckingMembership
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..wrapper import MembersPresent from ..wrapper import MembersPresent
if TYPE_CHECKING: if TYPE_CHECKING:
......
from ipaddress import IPv4Address from ipaddress import IPv4Address
from utils import Membership_Query, QueryResponseInterval, LastMemberQueryCount, TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from Packet.PacketIGMPHeader import PacketIGMPHeader from ..igmp_globals import Membership_Query, QueryResponseInterval, LastMemberQueryCount
from Packet.ReceivedPacket import ReceivedPacket from pimdm.Packet.PacketIGMPHeader import PacketIGMPHeader
from pimdm.Packet.ReceivedPacket import ReceivedPacket
from . import NoMembersPresent, MembersPresent, CheckingMembership from . import NoMembersPresent, MembersPresent, CheckingMembership
if TYPE_CHECKING: if TYPE_CHECKING:
......
from Packet.PacketIGMPHeader import PacketIGMPHeader from pimdm.Packet.PacketIGMPHeader import PacketIGMPHeader
from utils import Membership_Query, LastMemberQueryInterval, TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..igmp_globals import Membership_Query, LastMemberQueryInterval
from ..wrapper import NoMembersPresent, MembersPresent, Version1MembersPresent from ..wrapper import NoMembersPresent, MembersPresent, Version1MembersPresent
if TYPE_CHECKING: if TYPE_CHECKING:
from ..GroupState import GroupState from ..GroupState import GroupState
......
from Packet.PacketIGMPHeader import PacketIGMPHeader from pimdm.Packet.PacketIGMPHeader import PacketIGMPHeader
from utils import Membership_Query, LastMemberQueryInterval, TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..igmp_globals import Membership_Query, LastMemberQueryInterval
from ..wrapper import Version1MembersPresent, CheckingMembership, NoMembersPresent from ..wrapper import Version1MembersPresent, CheckingMembership, NoMembersPresent
if TYPE_CHECKING: if TYPE_CHECKING:
from ..GroupState import GroupState from ..GroupState import GroupState
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..wrapper import MembersPresent from ..wrapper import MembersPresent
from ..wrapper import Version1MembersPresent from ..wrapper import Version1MembersPresent
if TYPE_CHECKING: if TYPE_CHECKING:
......
from ipaddress import IPv4Address from ipaddress import IPv4Address
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from utils import Membership_Query, QueryResponseInterval, LastMemberQueryCount, LastMemberQueryInterval from ..igmp_globals import Membership_Query, QueryResponseInterval, LastMemberQueryCount, LastMemberQueryInterval
from Packet.PacketIGMPHeader import PacketIGMPHeader from pimdm.Packet.PacketIGMPHeader import PacketIGMPHeader
from Packet.ReceivedPacket import ReceivedPacket from pimdm.Packet.ReceivedPacket import ReceivedPacket
from . import CheckingMembership, MembersPresent, Version1MembersPresent, NoMembersPresent from . import CheckingMembership, MembersPresent, Version1MembersPresent, NoMembersPresent
if TYPE_CHECKING: if TYPE_CHECKING:
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
from ..wrapper import NoMembersPresent from ..wrapper import NoMembersPresent
from ..wrapper import MembersPresent from ..wrapper import MembersPresent
if TYPE_CHECKING: if TYPE_CHECKING:
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from ..RouterState import RouterState from ..RouterState import RouterState
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from ..RouterState import RouterState from ..RouterState import RouterState
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from ..RouterState import RouterState from ..RouterState import RouterState
......
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from ..RouterState import RouterState from ..RouterState import RouterState
......
from tree.tree_if_upstream import TreeInterfaceUpstream from .tree_if_upstream import TreeInterfaceUpstream
from tree.tree_if_downstream import TreeInterfaceDownstream from .tree_if_downstream import TreeInterfaceDownstream
from .tree_interface import TreeInterface from .tree_interface import TreeInterface
from threading import Timer, Lock, RLock from threading import Lock, RLock
from tree.metric import AssertMetric from .metric import AssertMetric
import UnicastRouting from pimdm import UnicastRouting, Main
from time import time from time import time
import Main
import logging import logging
class KernelEntry: class KernelEntry:
...@@ -59,7 +58,7 @@ class KernelEntry: ...@@ -59,7 +58,7 @@ class KernelEntry:
return self.inbound_interface_index return self.inbound_interface_index
def get_outbound_interfaces_indexes(self): def get_outbound_interfaces_indexes(self):
outbound_indexes = [0]*Main.kernel.MAXVIFS outbound_indexes = [0] * Main.kernel.MAXVIFS
for (index, state) in self.interface_state.items(): for (index, state) in self.interface_state.items():
outbound_indexes[index] = state.is_forwarding() outbound_indexes[index] = state.is_forwarding()
return outbound_indexes return outbound_indexes
......
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import tree.globals as pim_globals import pimdm.tree.globals as pim_globals
from .metric import AssertMetric from .metric import AssertMetric
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from .tree_if_downstream import TreeInterfaceDownstream from .tree_if_downstream import TreeInterfaceDownstream
......
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from tree import globals as pim_globals from . import globals as pim_globals
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from .tree_if_downstream import TreeInterfaceDownstream from .tree_if_downstream import TreeInterfaceDownstream
......
'''
Created on Feb 23, 2015
This module is intended to have all constants and global values for pim_dm
@author: alex
'''
ASSERT_TIME = 180 ASSERT_TIME = 180
GRAFT_RETRY_PERIOD = 3 GRAFT_RETRY_PERIOD = 3
JP_OVERRIDE_INTERVAL = 3.0 JP_OVERRIDE_INTERVAL = 3.0
...@@ -15,6 +7,4 @@ REFRESH_INTERVAL = 60 # State Refresh Interval ...@@ -15,6 +7,4 @@ REFRESH_INTERVAL = 60 # State Refresh Interval
SOURCE_LIFETIME = 210 SOURCE_LIFETIME = 210
T_LIMIT = 210 T_LIMIT = 210
ASSERT_CANCEL_METRIC = 0xFFFFFFFF ASSERT_CANCEL_METRIC = 0xFFFFFFFF
\ No newline at end of file
...@@ -40,7 +40,7 @@ class AssertMetric(object): ...@@ -40,7 +40,7 @@ class AssertMetric(object):
@type tree_if: TreeInterface @type tree_if: TreeInterface
''' '''
(source_ip, _) = tree_if.get_tree_id() (source_ip, _) = tree_if.get_tree_id()
import UnicastRouting from pimdm import UnicastRouting
(metric_preference, metric_cost, _) = UnicastRouting.get_metric(source_ip) (metric_preference, metric_cost, _) = UnicastRouting.get_metric(source_ip)
return AssertMetric(metric_preference, metric_cost, tree_if.get_ip()) return AssertMetric(metric_preference, metric_cost, tree_if.get_ip())
......
from abc import ABCMeta, abstractstaticmethod from abc import ABCMeta, abstractstaticmethod
from tree import globals as pim_globals
class OriginatorStateABC(metaclass=ABCMeta): class OriginatorStateABC(metaclass=ABCMeta):
@abstractstaticmethod @abstractstaticmethod
......
...@@ -4,16 +4,17 @@ Created on Jul 16, 2015 ...@@ -4,16 +4,17 @@ Created on Jul 16, 2015
@author: alex @author: alex
''' '''
from threading import Timer from threading import Timer
from CustomTimer.RemainingTimer import RemainingTimer from pimdm.CustomTimer.RemainingTimer import RemainingTimer
from .assert_ import AssertState, AssertStateABC from .assert_ import AssertState
from .downstream_prune import DownstreamState, DownstreamStateABS from .downstream_prune import DownstreamState, DownstreamStateABS
from .tree_interface import TreeInterface from .tree_interface import TreeInterface
from Packet.PacketPimStateRefresh import PacketPimStateRefresh from pimdm.Packet.PacketPimStateRefresh import PacketPimStateRefresh
from Packet.Packet import Packet from pimdm.Packet.Packet import Packet
from Packet.PacketPimHeader import PacketPimHeader from pimdm.Packet.PacketPimHeader import PacketPimHeader
import traceback import traceback
import logging import logging
import Main from .. import Main
class TreeInterfaceDownstream(TreeInterface): class TreeInterfaceDownstream(TreeInterface):
LOGGER = logging.getLogger('pim.KernelEntry.DownstreamInterface') LOGGER = logging.getLogger('pim.KernelEntry.DownstreamInterface')
...@@ -135,7 +136,7 @@ class TreeInterfaceDownstream(TreeInterface): ...@@ -135,7 +136,7 @@ class TreeInterfaceDownstream(TreeInterface):
if self.is_pruned(): if self.is_pruned():
prune_indicator_bit = 1 prune_indicator_bit = 1
import UnicastRouting from pimdm import UnicastRouting
(metric_preference, metric, mask) = UnicastRouting.get_metric(state_refresh_msg_received.source_address) (metric_preference, metric, mask) = UnicastRouting.get_metric(state_refresh_msg_received.source_address)
assert_override_flag = 0 assert_override_flag = 0
......
...@@ -6,17 +6,17 @@ Created on Jul 16, 2015 ...@@ -6,17 +6,17 @@ Created on Jul 16, 2015
from .tree_interface import TreeInterface from .tree_interface import TreeInterface
from .upstream_prune import UpstreamState from .upstream_prune import UpstreamState
from threading import Timer from threading import Timer
from CustomTimer.RemainingTimer import RemainingTimer from pimdm.CustomTimer.RemainingTimer import RemainingTimer
from .globals import * from .globals import *
import random import random
from .metric import AssertMetric from .metric import AssertMetric
from .originator import OriginatorState, OriginatorStateABC from .originator import OriginatorState, OriginatorStateABC
from Packet.PacketPimStateRefresh import PacketPimStateRefresh from pimdm.Packet.PacketPimStateRefresh import PacketPimStateRefresh
import traceback import traceback
from . import DataPacketsSocket from . import DataPacketsSocket
import threading import threading
import logging import logging
import Main from .. import Main
class TreeInterfaceUpstream(TreeInterface): class TreeInterfaceUpstream(TreeInterface):
......
...@@ -4,22 +4,22 @@ Created on Jul 16, 2015 ...@@ -4,22 +4,22 @@ Created on Jul 16, 2015
@author: alex @author: alex
''' '''
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import Main from .. import Main
from threading import RLock from threading import RLock
import traceback import traceback
from .downstream_prune import DownstreamState from .downstream_prune import DownstreamState
from .assert_ import AssertState, AssertStateABC from .assert_ import AssertState, AssertStateABC
from Packet.PacketPimGraft import PacketPimGraft from pimdm.Packet.PacketPimGraft import PacketPimGraft
from Packet.PacketPimGraftAck import PacketPimGraftAck from pimdm.Packet.PacketPimGraftAck import PacketPimGraftAck
from Packet.PacketPimJoinPruneMulticastGroup import PacketPimJoinPruneMulticastGroup from pimdm.Packet.PacketPimJoinPruneMulticastGroup import PacketPimJoinPruneMulticastGroup
from Packet.PacketPimHeader import PacketPimHeader from pimdm.Packet.PacketPimHeader import PacketPimHeader
from Packet.Packet import Packet from pimdm.Packet.Packet import Packet
from Packet.PacketPimJoinPrune import PacketPimJoinPrune from pimdm.Packet.PacketPimJoinPrune import PacketPimJoinPrune
from Packet.PacketPimAssert import PacketPimAssert from pimdm.Packet.PacketPimAssert import PacketPimAssert
from Packet.PacketPimStateRefresh import PacketPimStateRefresh from pimdm.Packet.PacketPimStateRefresh import PacketPimStateRefresh
from .metric import AssertMetric from .metric import AssertMetric
from threading import Timer from threading import Timer
from .local_membership import LocalMembership from .local_membership import LocalMembership
......
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from utils import TYPE_CHECKING from pimdm.utils import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from .tree_if_upstream import TreeInterfaceUpstream from .tree_if_upstream import TreeInterfaceUpstream
......
...@@ -70,26 +70,3 @@ try: ...@@ -70,26 +70,3 @@ try:
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
except ImportError: except ImportError:
TYPE_CHECKING = False TYPE_CHECKING = False
# IGMP timers (in seconds)
RobustnessVariable = 2
QueryInterval = 125
QueryResponseInterval = 10
MaxResponseTime_QueryResponseInterval = QueryResponseInterval*10
GroupMembershipInterval = RobustnessVariable * QueryInterval + QueryResponseInterval
OtherQuerierPresentInterval = RobustnessVariable * QueryInterval + QueryResponseInterval/2
StartupQueryInterval = QueryInterval / 4
StartupQueryCount = RobustnessVariable
LastMemberQueryInterval = 1
MaxResponseTime_LastMemberQueryInterval = LastMemberQueryInterval*10
LastMemberQueryCount = RobustnessVariable
UnsolicitedReportInterval = 10
Version1RouterPresentTimeout = 400
# IGMP msg type
Membership_Query = 0x11
Version_1_Membership_Report = 0x12
Version_2_Membership_Report = 0x16
Leave_Group = 0x17
import sys import sys
from setuptools import setup, find_packages from setuptools import setup, find_packages
from setuptools.command.test import test as TestCommand
# we only support Python 3 version >= 3.4 # we only support Python 3 version >= 3.4
#if len(sys.argv) >= 2 and sys.argv[1] == "install" and sys.version_info < (3, 4): #if len(sys.argv) >= 2 and sys.argv[1] == "install" and sys.version_info < (3, 4):
...@@ -9,21 +7,21 @@ from setuptools.command.test import test as TestCommand ...@@ -9,21 +7,21 @@ from setuptools.command.test import test as TestCommand
dependencies = open("requirements.txt", "r").read().splitlines() dependencies = open("requirements.txt", "r").read().splitlines()
setup( setup(
name="pim-dm", name="pim-dm",
version="1.0",
url="http://github.com/pedrofran12/pim_dm",
license="MIT",
description="PIM-DM protocol", description="PIM-DM protocol",
long_description=open("README.md", "r").read(), long_description=open("README.md", "r").read(),
long_description_content_type="text/markdown",
version="1.0.1",
url="http://github.com/pedrofran12/pim_dm",
author='Pedro Oliveira',
author_email='pedro.francisco.oliveira@tecnico.ulisboa.pt',
license="MIT",
install_requires=dependencies, install_requires=dependencies,
packages=find_packages(exclude=["docs"]), packages=find_packages(exclude=["docs"]),
py_modules=["Run", "Interface", "InterfaceIGMP", "InterfacePIM", "Kernel", "Main", "Neighbor",
"TestLogger", "UnicastRouting", "utils"],
entry_points={ entry_points={
"console_scripts": [ "console_scripts": [
"pim-dm = Run:main", "pim-dm = pimdm.Run:main",
] ]
}, },
include_package_data=True, include_package_data=True,
...@@ -39,7 +37,13 @@ setup( ...@@ -39,7 +37,13 @@ setup(
"Operating System :: OS Independent", "Operating System :: OS Independent",
"Programming Language :: Python", "Programming Language :: Python",
"Programming Language :: Python :: 3", "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.2",
"Programming Language :: Python :: 3.3",
"Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.4",
"Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
], ],
python_requires='>=3.2',
) )
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment