我是Python和Pox Controller的初学者。我想在痘痘中添加代码,以对收到的数据包进行分类。我希望它计算在源&amp之间传播的IP数据包;目标IP/端口对,并在一定时间内具有相同的协议。我想要这样的列表:
[[SRC IP,DS TIP,SRC端口,DST端口,协议= TCP,Flow Count = X]
[SRC IP,DS提示,SRC端口,DST端口,协议= IP,Flow Count = Y]
[SRC IP,DS TIP,SRC端口,DST端口,协议= ICMP,Flow Count = Z]]
我使用了python中的列表列表,这意味着每流1个列表。我将代码的流量计数部分添加到Pox的L2_LEARNING组件(_Handle_packetin函数内部)。因此,每次在控制器中收到packet_in时,都将执行计算。
但是我有一个错误: RuntimeError:最大递归深度超过。
我在代码中没有使用任何递归功能!我什至已经增加了允许的堆栈深度,但是错误仍然存在。
此外,我不知道如何在特定时间间隔安排程序以填写列表(命名:流列表),我有点困惑,因为每个包含在控制器的数据包都应该是另一方面,在此计算中考虑了每个数据包的计算会导致上述错误!
您能告诉我如何以特定的间隔计算流量计数(上述)?以及在我的程序中将代码放置在哪里?
在何处放置用于打印流列表的命令,仅在此时间间隔打印完整的列表,而不是每次收到Controller中的数据包时打印列表。
以及如何求解(超过最大递归深度)错误?
这是代码:
sys.setrecursionlimit(10000)
class LearningSwitch (object):
flowlist=[]
def __init__ (self, connection, transparent):
.......
LearningSwitch.flowlist=[]
def _handle_PacketIn (self, event):
flag=0
packet = event.parsed
if packet.type == packet.IP_TYPE:
ip_packet=packet.payload
#-------------TCP-----------------
if (packet.find('tcp')):
tcp_packet = ip_packet.payload
for thisflow in LearningSwitch.flowlist:
if (thisflow[0]==packet.next.srcip and thisflow[1]==packet.next.dstip and thisflow [2]==tcp_packet.srcport and thisflow[3]==tcp_packet.dstport,thisflow[4]== "TCP"):
thisflow[5]+=1
flag=1
if (flag!=1):
LearningSwitch.flowlist.append([packet.next.srcip,packet.next.dstip,tcp_packet.srcport,tcp_packet.dstport,"TCP",1])
#---------- ICMP --------------------
elif (packet.find('icmp')):
icmp_packet = ip_packet.payload
for thisflow in LearningSwitch.flowlist:
if (thisflow[0]==ip_packet.srcip and thisflow[1]==ip_packet.dstip and thisflow[4]== "ICMP"):
thisflow[5]+=1
flag=1
if (flag!=1):
LearningSwitch.flowlist.append([packet.next.srcip,packet.next.dstip,"--","--","ICMP",1])
#------------ IPV4 ---------------------
elif (packet.find('ipv4')):
for thisflow in LearningSwitch.flowlist:
if (thisflow[0]==packet.next.srcip and thisflow[1]==packet.next.dstip and thisflow[4]== "IP"):
thisflow[5]+=1
flag=1
if (flag!=1):
LearningSwitch.flowlist.append([packet.next.srcip,packet.next.dstip,"--","--","IP",1])
print LearningSwitch.flowlist
#---- The rest of the code is from L2_learning component
.
.
.
.
class l2_learning (object):
def __init__ (self, transparent):
core.openflow.addListeners(self)
self.transparent = transparent
def _handle_ConnectionUp (self, event):
log.debug("Connection %s" % (event.connection,))
LearningSwitch(event.connection, self.transparent)
def launch (transparent=False, hold_down=_flood_delay):
"""
Starts an L2 learning switch.
"""
try:
global _flood_delay
_flood_delay = int(str(hold_down), 10)
assert _flood_delay >= 0
except:
raise RuntimeError("Expected hold-down to be a number")
core.registerNew(l2_learning, str_to_bool(transparent))
这是错误:
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 347, in __cmp__
return -other.__cmp__(self)
File "/home/manager/pox/pox/lib/addresses.py", line 214, in __cmp__
return -other.__cmp__(self)
RuntimeError: maximum recursion depth exceeded
谢谢您的帮助。
为了具有重复函数,您需要从recoco模块中的计时器类。第一个导入计时器
from pox.lib.recoco import Timer
创建一个将打印列表的函数。此功能属于
类学习开关(对象):
因此,这是该类的一种方法,我们以后可以用自我引用。
def print_list(self):
"""
just print the list
Returns:
nada
"""
if LearningSwitch.flowlist:
print LearningSwitch.flowlist
然后,我们创建一个函数,该功能将每秒调用上面的打印功能。传递参数在每个调用之间传递的秒
传递 def _timer_func(self, dt):
"""
recurring function, calls a function every dt seconds
Returns:
nada
"""
Timer(dt, self.print_list, recurring=True)
最后,我们在class的初始
self._timer_func(2)
传递此处2秒。从_handle_packetin删除打印。您不再需要它了。完整的代码可以在此处找到
使用的矿物的命令是
sudo mn --controller=remote