yolo03 2023-11-17 20:42 采纳率: 0%
浏览 1
已结题

SDN用CMS算法做流量统计

#mytopo.py
from mininet.topo import Topo
class MyTopo(Topo):
    def __init__(self):
        Topo.__init__(self)
        
        #add hosts
        h1=self.addHost('h1',ip='10.1.1.1')
        h2=self.addHost('h2',ip='10.1.1.2')
        h3=self.addHost('h3',ip='10.1.1.3')
        
        #add switchs
        s1=self.addSwitch('s1')
        
        #add controllers
        c0 = self.addController('c0', controller=RemoteController, ip='127.0.0.1', port=6633)
        
        #add links
        self.addLink(h1, s1,1,1)
        self.addLink(h2, s1,1,2)
        self.addLink(h3, s1,1,3)
        self.addLink(c0,s1,1,4)

topos = { 'mytopo': ( lambda: MyTopo() ) }

#construction.py
from scapy.all import *


def construction():
    srcp = 1024
    x=0
    
    for i in range(10):
        ip_layer = IP(src="10.0.0.1", dst="10.0.0.2",proto=6)
        tcp_layer = TCP(sport=srcp , dport=80,flags="S")
        tcp_packet = ip_layer / tcp_layer
        wrpcap("./w/output_"+ str(x) +"pcap", tcp_packet)
        x+=1
    
    for i in range(6):
        ip_layer = IP(src="10.0.0.1", dst="10.0.0.2",proto=6)
        tcp_layer = TCP(sport=srcp + 1, dport=80,flags="S")
        tcp_packet = ip_layer / tcp_layer
        wrpcap("./w/output_"+ str(x) +"pcap", tcp_packet)
        x+=1
    
    for i in range(3):
        ip_layer = IP(src="10.0.0.1", dst="10.0.0.2",proto=6)
        tcp_layer = TCP(sport=srcp + 2, dport=80,flags="S")
        tcp_packet = ip_layer / tcp_layer
        wrpcap("./w/output_"+ str(x) +"pcap", tcp_packet)
        x+=1
    
    for i in range(9):
        ip_layer = IP(src="10.0.0.1", dst="10.0.0.2",proto=6)
        tcp_layer = TCP(sport=srcp + 3, dport=80,flags="S")
        tcp_packet = ip_layer / tcp_layer
        wrpcap("./w/output_"+ str(x) +"pcap", tcp_packet)
        x+=1
    
    for i in range(2):
        ip_layer = IP(src="10.0.0.1", dst="10.0.0.2",proto=6)
        tcp_layer = TCP(sport=srcp + 4, dport=80,flags="S")
        tcp_packet = ip_layer / tcp_layer
        wrpcap("./w/output_"+ str(x) +"pcap", tcp_packet)
        x+=1
    
    for i in range(3):
        ip_layer = IP(src="10.0.0.1", dst="10.0.0.2",proto=6)
        tcp_layer = TCP(sport=srcp + 5, dport=80,flags="S")
        tcp_packet = ip_layer / tcp_layer
        wrpcap("./w/output_"+ str(x) +"pcap", tcp_packet)
        x+=1
        
if __name__ == '__main__':
    construction()

#CM.py
import mytopo
import construction
from scapy.all import *  
from collections import defaultdict 
import os 
from scapy.all import rdpcap

class CountMinSketch: 
    def __init__(self, w, d): 
        self.w = w  
        self.d = d 
        self.tables = [defaultdict(int) for _ in range(w)]  # 创建包含w个默认字典的列表,每个字典的默认值为0

    def add(self, item):  # 添加元素
        for table in self.tables:  # 遍历每个表
            h = hash(item) % (1 << self.d)  # 计算哈希值h,取模2^d
            table[h] += 1 

    def estimate(self, item):
        min_estimate = float('inf')  # 初始化为正无穷大
        for table in self.tables:
            h = hash(item) % (1 << self.d)
            if table[h] < min_estimate: 
                min_estimate = table[h]
        return min_estimate 

def process_packet(packet, sketch):  # 处理数据包
    key = (packet['Source'],packet['Destination'],packet['Src Port'], packet['Dst Port'], packet['Protocol'])  # 五元组作为键
    sketch.add(key)
    return sketch

if __name__ == "__main__":
    w = 10
    d = 5
    sketch = CountMinSketch(w, d)
    
    # 获取目录work下的所有文件名
    file_list = os.listdir("w")
    packets = []

    for file_name in file_list:
        if file_name.endswith(".pcap"):
            packets_temp=rdpcap(os.path.join("w",file_name))
            packets.extend(packets_temp)

    for packet in packets:
        sketch = process_packet(packet, sketch) 

    for key in sketch.tables[0]:
        print(f"{key}: {sketch.estimate(key)}")


#construction.py是自己用scapy库构造数据包,mytopo.py是搭建拓扑,CM.py是用count-min sketch 来统计构造的数据包中每个流的数量,哈希键值是五元组(源IP,目的IP,源端口,目的端口,传输层协议),结果在终端运行的时候报下面这个错误,根据网上的教程把scapy目录下的all.py里面关于ipv6的代码注释掉了还是没用,想求助一下有人知道怎么解决吗

img

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2023-11-17 20:42
    关注

    引自强大而免费的微信小程序:皆我百晓生

    你的代码主要有三部分组成:mytopo.py用于搭建拓扑,construction.py用于构造数据包,CM.py使用Count-Min Sketch算法统计流量。根据你提供的信息,我将逐个分析并解决你的问题。

    解决问题的思路

    1. 首先分析错误信息,定位问题可能出现的地方。
    2. 排查可能的原因并尝试解决。
    3. 确保代码逻辑正确,遵循Count-Min Sketch算法的实现细节。
    4. 运行代码并验证结果。

    解决问题的步骤

    1. 错误信息分析

    根据你提供的错误信息,问题出现在CM.py文件中的rdpcap()函数上。请确认错误是由这一行代码引起的。

    2. 排查可能的原因

    由于你注释了Scapy中处理IPv6的代码,可能导致在读取.pcap文件时发生错误。你可以尝试使用Scapy中专门处理IPv4数据包的函数来替换rdpcap()函数。

    将CM.py文件中的rdpcap()函数替换为以下代码:

    from scapy.compat import raw
    from scapy.layers.l2 import Ether
    
    
    def rdpcap_patched(filename):
        packets = []
        with open(filename, "rb") as f:
            data = f.read()
        
        while data:
            pkt_len = raw(Ether(data)).h[2] * 256 + raw(Ether(data)).h[3]
            packet = Ether(data[:pkt_len])
            packets.append(packet)
            data = data[pkt_len:]
        
        return packets
    
    
    # 将下面的代码块
    for file_name in file_list:
        if file_name.endswith(".pcap"):
            packets_temp=rdpcap(os.path.join("w",file_name))
            packets.extend(packets_temp)
            
    # 替换为这段代码
    for file_name in file_list:
        if file_name.endswith(".pcap"):
            packets_temp = rdpcap_patched(os.path.join("w", file_name))
            packets.extend(packets_temp)
    

    3. 确保代码逻辑正确

    请确认Count-Min Sketch的实现代码与算法一致,并正确处理每个数据包以进行统计。

    4. 运行代码并验证结果

    运行修改后的代码,并检查输出结果。确保代码可以执行无报错。

    希望以上步骤对你有帮助。如果问题仍然存在,请提供更详细的错误信息以便我们进一步帮助你解决问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月17日
  • 创建了问题 11月17日

悬赏问题

  • ¥15 大二软件工程基础大题
  • ¥200 使用python编写程序,采用socket方式获取网页实时刷新的数据,能定时print()出来就行。
  • ¥15 matlab如何根据图片中的公式绘制e和v的曲线图
  • ¥15 我想用Python(Django)+Vue搭建一个用户登录界面,但是在运行npm run serve时报错了如何解决?
  • ¥15 QQ邮箱过期怎么恢复?
  • ¥15 登录他人的vue项目显示服务器错误
  • ¥15 (标签-android|关键词-app)
  • ¥60 如何批量获取json的url
  • ¥15 comsol仿真压阻传感器
  • ¥15 Python线性规划函数optimize.linprog求解为整数