经过好几个月的慵懒的生活之后终于又有机会写一些代码啦,这次的领域比较陌生,竟然是网络拓扑发现方向的,那么就在此总结一些大体思路,再粘贴一下核心代码喽,至于其余的封装就不贴了,只贴一下核心算法部分啦~~~
接收这个任务首先拿到的是一堆的数据文件,看着就烦人,要在其中提取我想要的地址转发表?搞笑死掉,神能找得到啊,于是我首先用perl脚本对数据文件进行了简要的处理并且输出到一个文件中,由于地址转发表的相关文件有两种格式(谁知道谁搞的这种东西啊,弄了还不弄成一种格式的)于是写了两套处理脚本如下:
isoFormat.pl
#!/usr/bin/perl -w
my $ip;
my @content;
my $sum = 0;
my %portHash;
my %portStateHash;
my %resultHash;
open RESULTCONTENT,">>result.txt";
while(<>){
$ip = $ARGV;
if($ip =~ /(.+)\.txt/){
$ip = $1;
}
chomp;
if(/^iso\.3\.6\.1\.2\.1\.17\.4\.3\.1\.1\.(.+)\s=\sHex-STRING:\s(.*)/){
chomp;
$content[$sum] = "$_";
$sum++;
}
if(/^iso\.3\.6\.1\.2\.1\.17\.4\.3\.1\.2\.(.+)\s=\sINTEGER:\s(\S*)/){
chomp $2;
$portHash{$1} = $2;
}
if(/^iso\.3\.6\.1\.2\.1\.17\.4\.3\.1\.3\.(.+)\s=\sINTEGER:\s(\S*)/){
chomp $2;
$portStateHash{$1} = "$portHash{$1}"."-$2";
}
}
foreach (@content){
if(/^iso\.3\.6\.1\.2\.1\.17\.4\.3\.1\.1\.(.+)\s=\sHex-STRING:\s(.*)/){
$resultHash{$1} = "$portStateHash{$1}"."-$2";
}
}
foreach(keys %resultHash){
print RESULTCONTENT"$ip"."\-$resultHash{$_}\n";
}
specialFormat.pl
#!/usr/bin/perl -w
my $ip;
my @content;
my $sum = 0;
my %portHash;
my %portStateHash;
my %resultHash;
open RESULTCONTENT,">>result.txt";
while(<>){
$ip = $ARGV;
if($ip =~ /(.+)\.txt/){
$ip = $1;
}
chomp;
if(/^\w+:\sdot1dTpFdbAddress\.(.+)\s\(octet string\)\s(.+)\s?\[.+\]/){
chomp;
$content[$sum] = "$_";
$sum++;
}
if(/^\w+:\sdot1dTpFdbPort\.(.+)\s\(integer\)\s(\w+)/){
chomp $2;
$portHash{$1} = $2;
}
if(/^\w+:\sdot1dTpFdbStatus\.(.+)\s\(integer\)\s\w+\((\w+)\)/){
chomp $2;
$portStateHash{$1} = "$portHash{$1}"."-$2";
}
}
foreach (@content){
if(/^\w+:\sdot1dTpFdbAddress\.(.+)\s\(octet string\)\s(.+)\s?\[.+\]/){
$resultHash{$1} = "$portStateHash{$1}"."-$2";
$resultHash{$1} =~ s/\:/ /g;
}
}
foreach(keys %resultHash){
print RESULTCONTENT"$ip"."\-$resultHash{$_}\n";
}
处理完成后生成了统一格式的文件即:设备ip-端口号-端口状态-转发地址
之后又手动整理了设备mac与ip的对应文件格式为:设备ip - 设备mac地址
对生成好的规范格式的文件进行初始化生成完整的java对象集那么我们的任务便是处理这些对象识别之间的链接关系:核心算法代码如下:
package com.madonglin.finder.manager.imp;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import com.madonglin.finder.cache.SwitchCache;
import com.madonglin.finder.manager.NetDealer;
import com.madonglin.finder.vo.Link;
import com.madonglin.finder.vo.Port;
import com.madonglin.finder.vo.Switch;
public class DownPortNetDealer implements NetDealer {
@Override
public List<Link> workoutNetLinks(String markMac) {
SwitchCache cache = SwitchCache.getSwitchCache();
List<Switch> switches = cache.getSwitchs();
LinkedList<Switch> leafSwitches = new LinkedList<Switch>();
List<Switch> rootSwitches = new ArrayList<Switch>();
List<Link> links = new ArrayList<Link>();
//分析交换机的上下行接口
for(Switch tempSwitch : switches){
for(String key : tempSwitch.getKeys()){
Port tempPort = tempSwitch.getPort(key);
List<String> allMacs = tempPort.getAllMacs();
if(allMacs != null && allMacs.contains(markMac)){
tempSwitch.addUpPort(tempPort);
}else{
tempSwitch.addDownPort(tempPort);
//判断后代节点数
//FIXME 交换域确定影响结果
for(String mac : tempPort.getAllMacs()){
Switch compareSwitch = new Switch("");
compareSwitch.setMac(mac);
if(switches.contains(compareSwitch)){
tempSwitch.addChild();
//为子设备添加祖先信息
int index = switches.indexOf(compareSwitch);
Switch childSwitch = switches.get(index);
childSwitch.addParents(tempSwitch, tempPort);
}
}
}
}
}
//确定叶子节点
for(Switch temp : switches){
if(temp != null && 0 == temp.getChildNum()){
leafSwitches.addLast(temp);
}
if(0 == temp.getParentsKeys().size()){
rootSwitches.add(temp);
}
}
//判断链接关系
while(!leafSwitches.isEmpty()){
Switch tempSwitch = leafSwitches.removeFirst();
if(null != tempSwitch){
Switch fatherSwitch = null;
for(Switch key : tempSwitch.getParentsKeys()){
if(null == fatherSwitch){
fatherSwitch = key;
//FIXME 如果相同呢?
}else if(key.getChildNum() < fatherSwitch.getChildNum()){
fatherSwitch = key;
}
key.delChild();
if(0 == key.getChildNum()){
leafSwitches.addLast(key);
}
}
if(!rootSwitches.contains(tempSwitch)){
Link link = new Link();
link.setSwitchSrc(fatherSwitch.getIp());
link.setSwitchDes(tempSwitch.getIp());
link.setPortNumSrc(tempSwitch.getParentsPort(fatherSwitch).getNum());
link.setPortNumDes(tempSwitch.getUpPort().get(0).getNum());
links.add(link);
}
}
}
return links;
}
}
看个大概意思吧哈哈,经过我测试识别结果还算比较准确的