Packet-In 消息分類模塊
創(chuàng)建對(duì)象
IFloodlightProviderService floodlightProvider; //用于注冊(cè)監(jiān)聽(tīng)服務(wù)
protected static Logger log=LoggerFactory.getLogger(PktInHistory.class); //打印消息
protected IRestApiService restApi; //注冊(cè) REST API 服務(wù)
字符串用于判斷包是什么類型的包
public final static String BROADCAST="broadcast";
public final static String MULTICAST="multicast";
public final static String UNICAST="unicast";
獲取模塊服務(wù)
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;
}
獲取模塊服務(wù)實(shí)例
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;
}
添加服務(wù)依賴
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);
}
實(shí)例化 floddlightProvider 對(duì)象和 restAPI對(duì)象
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 消息類型加入監(jiān)聽(tīng)宅荤,其他類型的消息也是如此的添加
注冊(cè) REST API 服務(wù)
對(duì) 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 消息的內(nèi)容
調(diào)用 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,打印內(nèi)容窗价,(單播栖袋、組播、廣播)類型正蛙、EtherType督弓、源 IP, 目的 IP
for(Iterator<String> i = list.iterator();i.hasNext(); ){
String str = (String) i.next();
System.out.println(str);
}
return null;
}
判斷是單播乒验、組播愚隧、廣播、以太網(wǎng)類型
IPV4還是 IPV6锻全,獲得對(duì)應(yīng)的類型狂塘,例如是 ICMP 包或者 UDP 包,同時(shí)再獲取內(nèi)部的源 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;
}
可以通過(guò)REST API打印PACKET-IN 包數(shù)量以及 PACKET-IN 中 UDP 包的數(shù)量
具體 REST API 想要獲得的數(shù)據(jù)就可以放到 resp 中荞胡,之后調(diào)用 REST API 接口就能打印出來(lái)
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 服務(wù)地址
用于之后直接用REST API 接口得到數(shù)據(jù)
PktInHistory 的服務(wù)IPktInHistoryService
public interface IPktInHistoryService extends IFloodlightService {
public ConcurrentCircularBuffer<SwitchMessagePair>getBuffer();
public Long getPACKET_IN_Count();
public Long getPACKET_IN_UDP_Count();
}
用于在 REST API 中獲取當(dāng)前計(jì)數(shù)的值
此處指寫(xiě)了兩個(gè)計(jì)數(shù)的,一個(gè)是所有的 PACKET-IN 包了嚎,另一個(gè)是 PACKET-IN 包中的 UDP 的包
在對(duì)應(yīng)的 PKtInHistory 中的對(duì)應(yīng)方法
public Long getPACKET_IN_UDP_Count() {
// TODO Auto-generated method stub
return PACKET_IN_UDP_COUNT.get();
}
Mininet 環(huán)境配置
neal@ubuntu:~$ sudo mn --switch ovs,protocols=OpenFlow13,port=6653 --controller=remote --ip=127.0.0.1 --mac --topo=tree,2 --test iperf
然后在 Floodlight 中查看對(duì)應(yīng)的打印信息
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'
運(yùn)行:neal@ubuntu:~/Floodlight/example$ ./cli.py pktin_cnt
獲得如下結(jié)果:
{
"Packet-In-Total": "67",
"Packet-In-UDP-Total": "33"
}
Number of items: 2
可以直接獲得包的統(tǒng)計(jì)值