PACKET-IN 消息分类模块

Packet-In 消息分类模块

创建对象

IFloodlightProviderService floodlightProvider; //用于注册监听服务
protected static Logger log=LoggerFactory.getLogger(PktInHistory.class); //打印消息
protected IRestApiService restApi; //注册 REST API 服务

字符串用于判断包是什么类型的包

public final static String BROADCAST="broadcast";
public final static String MULTICAST="multicast";
public final static String UNICAST="unicast";

获取模块服务

    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
    // TODO Auto-generated method stub
    Collection<Class<? extends IFloodlightService>> I =new ArrayList<Class<? extends
            IFloodlightService>>();
    I.add(IPktInHistoryService.class);
    return I;
}

获取模块服务实例

public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
    // TODO Auto-generated method stub
    Map<Class<? extends IFloodlightService>,IFloodlightService> m =new HashMap<Class<? extends
            IFloodlightService>,IFloodlightService>();
    m.put(IPktInHistoryService.class,this);
    return m;
}

添加服务依赖

public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
    // TODO Auto-generated method stub
    Collection<Class<? extends IFloodlightService>> I =new ArrayList<Class<? extends
            IFloodlightService>>();
    I.add(IFloodlightProviderService.class);
    I.add(IRestApiService.class);
    return I;
}

init方法

public void init(FloodlightModuleContext context) throws FloodlightModuleException {
    // TODO Auto-generated method stub
    floodlightProvider=context.getServiceImpl(IFloodlightProviderService.class);
    restApi=context.getServiceImpl(IRestApiService.class);
}

实例化 floddlightProvider 对象和 restAPI对象

startUp方法

public void startUp(FloodlightModuleContext context) throws FloodlightModuleException {
    // TODO Auto-generated method stub
    floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
    restApi.addRestletRoutable(new PktInHistoryWebRoutable());
}

将 PACKET-IN 消息类型加入监听,其他类型的消息也是如此的添加
注册 REST API 服务

对 PACKET-IN 消息处理

public net.floodlightcontroller.core.IListener.Command receive(IOFSwitch sw, OFMessage msg,
        FloodlightContext cntx) {
    // TODO Auto-generated method stub
    switch(msg.getType()){
        case PACKET_IN:
            Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
            log.info("OFMessage:{} on switch {} \n" +"srcMac:{}\n"+"dstMac:{}\n"+"EtherType:{}\n",
                new Object[] { msg.getType(), sw.getId(), eth.getSourceMACAddress(),eth.getDestinationMACAddress(),eth.getEtherType()});
            PACKET_IN_COUNT.incrementAndGet();
            PacketInType(sw,msg,eth);
            break;
    default:
            break;
            
    }
    
    return Command.CONTINUE;
}

eth = IFloodlightProviderService.bcStore.get(cntx,IFloodlightProviderService.CONTEXT_PI_PAYLOAD)
用于获取 PACKET-IN 消息的内容
调用 PacketInType 方法打印出 PACKET-IN 消息的信息

PacketInType 方法

public   List<String> PacketInType(IOFSwitch sw, OFMessage m, Ethernet eth) {
        //int l3type = eth.getEtherType().getValue();
        String etherType = eth.getEtherType().toString();
        // L2 Type
        String l2Type = null;
        if (eth.isBroadcast()) {
            l2Type = BROADCAST;
        }
        else if (eth.isMulticast()) {
            l2Type = MULTICAST;
        }
        else {
            l2Type = UNICAST;
        }
        etherType = "EtherType: " + TypeAnalyse.l3TypeAliasMap.get(etherType);
        List<String>list = new ArrayList<String>();
        list.add(l2Type);
        list.add(etherType);
        // L4 counters
        if (eth.getPayload() instanceof IPv4) {
            MacAddress dlAddr = eth.getSourceMACAddress();
            IPv4Address ipv4Src = getSrcIPv4AddrFromARP(eth, dlAddr);
            IPv4Address ipv4Dst = getDstIPv4AddrFromARP(eth, dlAddr);
            IPv4 ipV4 = (IPv4)eth.getPayload();
            String l4name = ipV4.getProtocol().toString();
            l4name = TypeAnalyse.l4TypeAliasMap.get(l4name);
            String ipv4SrcIp=IPv4.fromIPv4Address(ipv4Src.getInt());
            String ipv4DstIp=IPv4.fromIPv4Address(ipv4Dst.getInt());
            list.add("IPV4_"+l4name);
            list.add("IPv4Src:"+ipv4SrcIp);
            list.add("IPv4Dst:"+ipv4DstIp);
        }
        // L4 counters
        else if (eth.getPayload() instanceof IPv6) {
            IPv6 ipv6 = (IPv6)eth.getPayload();
            String l4name = ipv6.getNextHeader().toString();
            if (TypeAnalyse.l4TypeAliasMap != null &&
                    TypeAnalyse.l4TypeAliasMap.containsKey(l4name)) {
                l4name = TypeAnalyse.l4TypeAliasMap.get(l4name);
                if(l4name.equals("L4_UDP")) PACKET_IN_IPV6_COUNT.incrementAndGet();
            }
            else {
                l4name = "IPV6_" + l4name;
            }
            IPv6Address ipv6SrcIp=ipv6.getSourceAddress();
            String ipv6srcIp=ipv6SrcIp.toString();
            IPv6Address ipv6DstIp=ipv6.getDestinationAddress();
            String ipv6dstIp=ipv6DstIp.toString();
            list.add(l4name);
            list.add("srcIP:"+ipv6srcIp);
            list.add("DstIP:"+ipv6dstIp);
          
        }
        //遍历 List,打印内容,(单播、组播、广播)类型、EtherType、源 IP, 目的 IP
        for(Iterator<String> i = list.iterator();i.hasNext(); ){
            String str = (String) i.next();
            System.out.println(str);
        }
        return null;
    }

判断是单播、组播、广播、以太网类型
IPV4还是 IPV6,获得对应的类型,例如是 ICMP 包或者 UDP 包,同时再获取内部的源 IP 地址和目的 IP 地址

类型分析类-TypeAnalyse.java

  • 用于 PacketInType 分析包是属于 ARP 还是 IPV4,IPV6等类型信息

TypeAnalyse.java

package net.floodlightcontroller.pktinhistory;

import java.util.HashMap;
import java.util.Map;

public  class TypeAnalyse {

    public static final Map<String,String> l3TypeAliasMap = 
            new HashMap<String, String>();
    static {
        l3TypeAliasMap.put("0x0599", "L3_V1Ether");
        l3TypeAliasMap.put("0x800", "L3_IPv4");
        l3TypeAliasMap.put("0x806", "L3_ARP");
        l3TypeAliasMap.put("0x8035", "L3_RARP");
        l3TypeAliasMap.put("0x809b", "L3_AppleTalk");
        l3TypeAliasMap.put("0x80f3", "L3_AARP");
        l3TypeAliasMap.put("0x8100", "L3_802_1Q");
        l3TypeAliasMap.put("0x8137", "L3_Novell_IPX");
        l3TypeAliasMap.put("0x8138", "L3_Novell");
        l3TypeAliasMap.put("0x86dd", "L3_IPv6");
        l3TypeAliasMap.put("0x8847", "L3_MPLS_uni");
        l3TypeAliasMap.put("0x8848", "L3_MPLS_multi");
        l3TypeAliasMap.put("0x8863", "L3_PPPoE_DS");
        l3TypeAliasMap.put("0x8864", "L3_PPPoE_SS");
        l3TypeAliasMap.put("0x886f", "L3_MSFT_NLB");
        l3TypeAliasMap.put("0x8870", "L3_Jumbo");
        l3TypeAliasMap.put("0x889a", "L3_HyperSCSI");
        l3TypeAliasMap.put("0x88a2", "L3_ATA_Ethernet");
        l3TypeAliasMap.put("0x88a4", "L3_EtherCAT");
        l3TypeAliasMap.put("0x88a8", "L3_802_1ad");
        l3TypeAliasMap.put("0x88ab", "L3_Ether_Powerlink");
        l3TypeAliasMap.put("0x88cc", "L3_LLDP");
        l3TypeAliasMap.put("0x88cd", "L3_SERCOS_III");
        l3TypeAliasMap.put("0x88e5", "L3_802_1ae");
        l3TypeAliasMap.put("0x88f7", "L3_IEEE_1588");
        l3TypeAliasMap.put("0x8902", "L3_802_1ag_CFM");
        l3TypeAliasMap.put("0x8906", "L3_FCoE");
        l3TypeAliasMap.put("0x9000", "L3_Loop");
        l3TypeAliasMap.put("0x9100", "L3_Q_in_Q");
        l3TypeAliasMap.put("0xcafe", "L3_LLT");
    }
    
    protected static final Map<String,String> l4TypeAliasMap = 
            new HashMap<String, String>();
    static {
        l4TypeAliasMap.put("0x00", "L4_HOPOPT");
        l4TypeAliasMap.put("0x01", "L4_ICMP");
        l4TypeAliasMap.put("0x02", "L4_IGAP_IGMP_RGMP");
        l4TypeAliasMap.put("0x03", "L4_GGP");
        l4TypeAliasMap.put("0x04", "L4_IP");
        l4TypeAliasMap.put("0x05", "L4_ST");
        l4TypeAliasMap.put("0x06", "L4_TCP");
        l4TypeAliasMap.put("0x07", "L4_UCL");
        l4TypeAliasMap.put("0x08", "L4_EGP");
        l4TypeAliasMap.put("0x09", "L4_IGRP");
        l4TypeAliasMap.put("0x0a", "L4_BBN");
        l4TypeAliasMap.put("0x0b", "L4_NVP");
        l4TypeAliasMap.put("0x0c", "L4_PUP");
        l4TypeAliasMap.put("0x0d", "L4_ARGUS");
        l4TypeAliasMap.put("0x0e", "L4_EMCON");
        l4TypeAliasMap.put("0x0f", "L4_XNET");
        l4TypeAliasMap.put("0x10", "L4_Chaos");
        l4TypeAliasMap.put("0x11", "L4_UDP");
        l4TypeAliasMap.put("0x12", "L4_TMux");
        l4TypeAliasMap.put("0x13", "L4_DCN");
        l4TypeAliasMap.put("0x14", "L4_HMP");
        l4TypeAliasMap.put("0x15", "L4_Packet_Radio");
        l4TypeAliasMap.put("0x16", "L4_XEROX_NS_IDP");
        l4TypeAliasMap.put("0x17", "L4_Trunk_1");
        l4TypeAliasMap.put("0x18", "L4_Trunk_2");
        l4TypeAliasMap.put("0x19", "L4_Leaf_1");
        l4TypeAliasMap.put("0x1a", "L4_Leaf_2");
        l4TypeAliasMap.put("0x1b", "L4_RDP");
        l4TypeAliasMap.put("0x1c", "L4_IRTP");
        l4TypeAliasMap.put("0x1d", "L4_ISO_TP4");
        l4TypeAliasMap.put("0x1e", "L4_NETBLT");
        l4TypeAliasMap.put("0x1f", "L4_MFE");
        l4TypeAliasMap.put("0x20", "L4_MERIT");
        l4TypeAliasMap.put("0x21", "L4_DCCP");
        l4TypeAliasMap.put("0x22", "L4_Third_Party_Connect");
        l4TypeAliasMap.put("0x23", "L4_IDPR");
        l4TypeAliasMap.put("0x24", "L4_XTP");
        l4TypeAliasMap.put("0x25", "L4_Datagram_Delivery");
        l4TypeAliasMap.put("0x26", "L4_IDPR");
        l4TypeAliasMap.put("0x27", "L4_TP");
        l4TypeAliasMap.put("0x28", "L4_ILTP");
        l4TypeAliasMap.put("0x29", "L4_IPv6_over_IPv4");
        l4TypeAliasMap.put("0x2a", "L4_SDRP");
        l4TypeAliasMap.put("0x2b", "L4_IPv6_RH");
        l4TypeAliasMap.put("0x2c", "L4_IPv6_FH");
        l4TypeAliasMap.put("0x2d", "L4_IDRP");
        l4TypeAliasMap.put("0x2e", "L4_RSVP");
        l4TypeAliasMap.put("0x2f", "L4_GRE");
        l4TypeAliasMap.put("0x30", "L4_DSR");
        l4TypeAliasMap.put("0x31", "L4_BNA");
        l4TypeAliasMap.put("0x32", "L4_ESP");
        l4TypeAliasMap.put("0x33", "L4_AH");
        l4TypeAliasMap.put("0x34", "L4_I_NLSP");
        l4TypeAliasMap.put("0x35", "L4_SWIPE");
        l4TypeAliasMap.put("0x36", "L4_NARP");
        l4TypeAliasMap.put("0x37", "L4_Minimal_Encapsulation");
        l4TypeAliasMap.put("0x38", "L4_TLSP");
        l4TypeAliasMap.put("0x39", "L4_SKIP");
        l4TypeAliasMap.put("0x3a", "L4_ICMPv6");
        l4TypeAliasMap.put("0x3b", "L4_IPv6_No_Next_Header");
        l4TypeAliasMap.put("0x3c", "L4_IPv6_Destination_Options");
        l4TypeAliasMap.put("0x3d", "L4_Any_host_IP");
        l4TypeAliasMap.put("0x3e", "L4_CFTP");
        l4TypeAliasMap.put("0x3f", "L4_Any_local");
        l4TypeAliasMap.put("0x40", "L4_SATNET");
        l4TypeAliasMap.put("0x41", "L4_Kryptolan");
        l4TypeAliasMap.put("0x42", "L4_MIT_RVDP");
        l4TypeAliasMap.put("0x43", "L4_Internet_Pluribus");
        l4TypeAliasMap.put("0x44", "L4_Distributed_FS");
        l4TypeAliasMap.put("0x45", "L4_SATNET");
        l4TypeAliasMap.put("0x46", "L4_VISA");
        l4TypeAliasMap.put("0x47", "L4_IP_Core");
        l4TypeAliasMap.put("0x4a", "L4_Wang_Span");
        l4TypeAliasMap.put("0x4b", "L4_Packet_Video");
        l4TypeAliasMap.put("0x4c", "L4_Backroom_SATNET");
        l4TypeAliasMap.put("0x4d", "L4_SUN_ND");
        l4TypeAliasMap.put("0x4e", "L4_WIDEBAND_Monitoring");
        l4TypeAliasMap.put("0x4f", "L4_WIDEBAND_EXPAK");
        l4TypeAliasMap.put("0x50", "L4_ISO_IP");
        l4TypeAliasMap.put("0x51", "L4_VMTP");
        l4TypeAliasMap.put("0x52", "L4_SECURE_VMTP");
        l4TypeAliasMap.put("0x53", "L4_VINES");
        l4TypeAliasMap.put("0x54", "L4_TTP");
        l4TypeAliasMap.put("0x55", "L4_NSFNET_IGP");
        l4TypeAliasMap.put("0x56", "L4_Dissimilar_GP");
        l4TypeAliasMap.put("0x57", "L4_TCF");
        l4TypeAliasMap.put("0x58", "L4_EIGRP");
        l4TypeAliasMap.put("0x59", "L4_OSPF");
        l4TypeAliasMap.put("0x5a", "L4_Sprite_RPC");
        l4TypeAliasMap.put("0x5b", "L4_Locus_ARP");
        l4TypeAliasMap.put("0x5c", "L4_MTP");
        l4TypeAliasMap.put("0x5d", "L4_AX");
        l4TypeAliasMap.put("0x5e", "L4_IP_within_IP");
        l4TypeAliasMap.put("0x5f", "L4_Mobile_ICP");
        l4TypeAliasMap.put("0x61", "L4_EtherIP");
        l4TypeAliasMap.put("0x62", "L4_Encapsulation_Header");
        l4TypeAliasMap.put("0x64", "L4_GMTP");
        l4TypeAliasMap.put("0x65", "L4_IFMP");
        l4TypeAliasMap.put("0x66", "L4_PNNI");
        l4TypeAliasMap.put("0x67", "L4_PIM");
        l4TypeAliasMap.put("0x68", "L4_ARIS");
        l4TypeAliasMap.put("0x69", "L4_SCPS");
        l4TypeAliasMap.put("0x6a", "L4_QNX");
        l4TypeAliasMap.put("0x6b", "L4_Active_Networks");
        l4TypeAliasMap.put("0x6c", "L4_IPPCP");
        l4TypeAliasMap.put("0x6d", "L4_SNP");
        l4TypeAliasMap.put("0x6e", "L4_Compaq_Peer_Protocol");
        l4TypeAliasMap.put("0x6f", "L4_IPX_in_IP");
        l4TypeAliasMap.put("0x70", "L4_VRRP");
        l4TypeAliasMap.put("0x71", "L4_PGM");
        l4TypeAliasMap.put("0x72", "L4_0_hop");
        l4TypeAliasMap.put("0x73", "L4_L2TP");
        l4TypeAliasMap.put("0x74", "L4_DDX");
        l4TypeAliasMap.put("0x75", "L4_IATP");
        l4TypeAliasMap.put("0x76", "L4_ST");
        l4TypeAliasMap.put("0x77", "L4_SRP");
        l4TypeAliasMap.put("0x78", "L4_UTI");
        l4TypeAliasMap.put("0x79", "L4_SMP");
        l4TypeAliasMap.put("0x7a", "L4_SM");
        l4TypeAliasMap.put("0x7b", "L4_PTP");
        l4TypeAliasMap.put("0x7c", "L4_ISIS");
        l4TypeAliasMap.put("0x7d", "L4_FIRE");
        l4TypeAliasMap.put("0x7e", "L4_CRTP");
        l4TypeAliasMap.put("0x7f", "L4_CRUDP");
        l4TypeAliasMap.put("0x80", "L4_SSCOPMCE");
        l4TypeAliasMap.put("0x81", "L4_IPLT");
        l4TypeAliasMap.put("0x82", "L4_SPS");
        l4TypeAliasMap.put("0x83", "L4_PIPE");
        l4TypeAliasMap.put("0x84", "L4_SCTP");
        l4TypeAliasMap.put("0x85", "L4_Fibre_Channel");
        l4TypeAliasMap.put("0x86", "L4_RSVP_E2E_IGNORE");
        l4TypeAliasMap.put("0x87", "L4_Mobility_Header");
        l4TypeAliasMap.put("0x88", "L4_UDP_Lite");
        l4TypeAliasMap.put("0x89", "L4_MPLS");
        l4TypeAliasMap.put("0x8a", "L4_MANET");
        l4TypeAliasMap.put("0x8b", "L4_HIP");
        l4TypeAliasMap.put("0x8c", "L4_Shim6");
        l4TypeAliasMap.put("0x8d", "L4_WESP");
        l4TypeAliasMap.put("0x8e", "L4_ROHC");
    }
}

PktInHistoryResource类

@Get("json")
public HashMap<String,String> retrieve(){
    IPktInHistoryService pihr =(IPktInHistoryService)getContext().getAttributes().
            get(IPktInHistoryService.class.getCanonicalName());
    Long count_packet_in=pihr.getPACKET_IN_Count();
    Long count_packet_in_UDP=pihr.getPACKET_IN_UDP_Count();
    HashMap<String,String>resp=new HashMap<String,String>();
    resp.put("Packet-In-Total", Long.toString(count_packet_in));
    resp.put("Packet-In-UDP-Total", Long.toString(count_packet_in_UDP));
    return resp;
}

可以通过REST API打印PACKET-IN 包数量以及 PACKET-IN 中 UDP 包的数量
具体 REST API 想要获得的数据就可以放到 resp 中,之后调用 REST API 接口就能打印出来

PktInHistoryWebRoutable类

@Override
public Restlet getRestlet(Context context) {
    // TODO Auto-generated method stub
    Router router=new Router(context);
    router.attach("/pktinhistory/json", PktInHistoryResource.class);
    return router;
}

@Override
public String basePath() {
    // TODO Auto-generated method stub
    return "/wm/statics" ;
}

绑定 REST API 服务地址
用于之后直接用REST API 接口得到数据

PktInHistory 的服务IPktInHistoryService

public interface IPktInHistoryService extends IFloodlightService {

    public ConcurrentCircularBuffer<SwitchMessagePair>getBuffer();
    public Long getPACKET_IN_Count();
    public Long getPACKET_IN_UDP_Count();
}

用于在 REST API 中获取当前计数的值
此处指写了两个计数的,一个是所有的 PACKET-IN 包,另一个是 PACKET-IN 包中的 UDP 的包


在对应的 PKtInHistory 中的对应方法

public Long getPACKET_IN_UDP_Count() {
    // TODO Auto-generated method stub
    return PACKET_IN_UDP_COUNT.get();
}

Mininet 环境配置

neal@ubuntu:~$ sudo mn --switch ovs,protocols=OpenFlow13,port=6653 --controller=remote --ip=127.0.0.1  --mac --topo=tree,2 --test iperf

然后在 Floodlight 中查看对应的打印信息

2016-12-06 21:37:40.753 INFO  [n.f.p.PktInHistory] 
OFMessage:PACKET_IN on switch 00:00:00:00:00:00:00:01 
srcMac:ce:72:93:42:23:ce
dstMac:33:33:00:00:00:fb
EtherType:0x86dd
multicast
EtherType: L3_IPv6
L4_UDP
srcIP:fe80::cc72:93ff:fe42:23ce
DstIP:ff02::fb

2016-12-06 21:37:46.666 INFO  [n.f.p.PktInHistory] 
OFMessage:PACKET_IN on switch 00:00:00:00:00:00:00:01 
srcMac:ce:72:93:42:23:ce
dstMac:33:33:00:00:00:02
EtherType:0x86dd

multicast
EtherType: L3_IPv6
L4_ICMPv6
srcIP:fe80::cc72:93ff:fe42:23ce
DstIP:ff02::2

在 cli.py 中添加一条 Rest api 命令

elif args.cmd =='pktin_cnt':
path='/wm/statics/pktinhistory/json'

运行:neal@ubuntu:~/Floodlight/example$ ./cli.py pktin_cnt

获得如下结果:
{
"Packet-In-Total": "67",
"Packet-In-UDP-Total": "33"
}
Number of items: 2

可以直接获得包的统计值

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,962评论 19 139
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 5,989评论 1 13
  • 一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式。”但是在要求详细讲述它所提出的各个约束,以及如...
    时待吾阅读 3,467评论 0 19
  • ——读书笔记|《跃迁:成为高手的技术》(古典著) 焦虑是这个时代的底色,世界太快,身体在狂奔,无奈灵魂落在身后泣不...
    花之葭阅读 399评论 0 5
  • 我且是如此執拗 像快破繭的那隻蛹 不動彈,偏偏不是無法動彈,而是不想動彈。 前幾日 我在夜裡 變成你巷子外那棵樹,...
    沁歡阅读 89评论 0 0