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,948評論 18 139
  • 簡介 用簡單的話來定義tcpdump,就是:dump the traffic on a network,根據使用者...
    保川閱讀 5,989評論 1 13
  • 一說到REST,我想大家的第一反應就是“啊,就是那種前后臺通信方式。”但是在要求詳細講述它所提出的各個約束,以及如...
    時待吾閱讀 3,467評論 0 19
  • ——讀書筆記|《躍遷:成為高手的技術》(古典著) 焦慮是這個時代的底色,世界太快,身體在狂奔,無奈靈魂落在身后泣不...
    花之葭閱讀 399評論 0 5
  • 我且是如此執拗 像快破繭的那隻蛹 不動彈,偏偏不是無法動彈,而是不想動彈。 前幾日 我在夜裡 變成你巷子外那棵樹,...
    沁歡閱讀 89評論 0 0