2

我是 python 和 pox 控制器的初学者。我想在 pox 中添加一个代码,以对收到的数据包进行分类。我希望它计算在某个时间段内在源和目标 IP/端口对之间传输并使用相同协议的 IP 数据包。我想要一个这样的列表:

[ [Src ip , ds tip, src port , dst port , protocol=tcp , flow count=x]

[src ip , ds tip, src port , dst port , protocol=IP , flow count=y]

[ Src ip , ds tip, src 端口 , dst 端口 , 协议=ICMP , 流数=z] ]

我在 python 中使用了一个列表列表,这意味着每个流有 1 个列表。我将代码的流量计数部分添加到 pox 的 L2_learning 组件(在 _handle_PacketIn 函数内)。因此,每次在控制器中接收到 packet_in 时,都会执行计算。

但我得到一个错误:RuntimeError: maximum recursion depth exceeded

我没有在代码中使用任何递归函数!我什至增加了允许的堆栈深度,但错误仍然存​​在。

另外,我不知道如何安排程序以特定时间间隔填充列表列表(命名为:flowlist),我有点困惑,因为每个到达控制器的数据包都应该在这个考虑另一方面,计算每个数据包都会导致上述错误!

您能否告诉我如何以特定的时间间隔计算流量计数(如上所述)?以及在我的程序中将这个调度的代码放在哪里?

在哪里放置打印流列表的命令,仅在该时间间隔打印完成的列表,而不是每次在控制器中接收到数据包时打印列表。

以及如何解决(超出最大递归深度)错误?

这是代码:

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

谢谢你的热心帮助。

4

1 回答 1

0

为了具有循环功能,您需要 recoco 模块中的 Timer 类。首次导入定时器

from pox.lib.recoco import Timer

创建一个将打印列表的函数。该功能属于

学习开关类(对象):

所以它是这个类的一个方法,后面我们可以用self来引用它。

  def print_list(self):
    """
    just print the list
    Returns:
            nada
    """
    if LearningSwitch.flowlist:
      print LearningSwitch.flowlist

然后我们创建一个函数,它将每隔 dt 秒调用一次上面的打印函数。传递参数在每次调用之间经过的秒数

  def _timer_func(self, dt):
    """
    recurring function, calls a function every dt seconds
    Returns:
            nada
    """
    Timer(dt, self.print_list, recurring=True)

最后我们在类的init中调用_timer_func

self._timer_func(2)

经过这里2秒。从 _handle_PacketIn 中删除打印。你不再需要它了。完整的代码可以在这里找到

使用的 mininet 命令是

sudo mn --controller=remote
于 2016-06-22T18:54:52.850 回答