这是我找到的traceroute的java源码,请大家帮我看看为什么出错

liublack010101 2012-04-26 11:11:21
这是我找到的java版本的traceroute的源码。http://code.google.com/p/fpb/wiki/TracerouteSample。
可是我的执行结果全部都是timeout。运行ping命令就可以成功。
麻烦大家帮我看看,是不是什么地方错了?怎么修改?谢谢
这是traceroute的源码:

package com.fineqt.fpb.protocol.sample;

import com.fineqt.fpb.lib.api.comm.CommTimeoutException;
import com.fineqt.fpb.lib.api.comm.pcap.IPcapSocket;
import com.fineqt.fpb.lib.api.util.IValueDumper;
import com.fineqt.fpb.lib.api.value.IIntegerValue;
import com.fineqt.fpb.lib.api.value.IRecordSetValue;
import com.fineqt.fpb.lib.api.value.IValueTextStyle;
import com.fineqt.fpb.protocol.ProtocolUtils;

/**
* 使用ICMPv4协议实现的Traceroute应用。 使用ICMPv4协议的Echo Request和Echo
* Reply报文和IPv4的TTL字段来实现Traceroute应用。
*/
public class TracerouteApp extends PingApp {
public final static int DEFAULT_MAX_HOPS = 20;
private int maxHops = DEFAULT_MAX_HOPS;

public TracerouteApp(IPcapSocket socket, String srcMac, String dstMac,String srcIp)
{
super(socket, srcMac, dstMac, srcIp);
}

public void trace(String dstIp) throws Exception {
byte[] resData = new byte[1514];
socket.setTimeout(timeout);
// 打开套接字
socket.open();
try {
// 设置Pcap套接字的过滤条件。(过滤条件的书写规则可以参考WinPcap的用户手册)
socket.setFilter("ip dst " + srcIp + " and icmp", true);
// 生成随机的ICMP Echo请求的标识符
int icmpId = (int) (Math.random() * 0xFFFF);
boolean reachedDst = false;
// 持续尝试直到到达了最大的HOP数
for (int i = 1; i <= maxHops; i++) {
// sequence NO. of ICMP
int seqNo = i;
// field of TTL in IP, increase 1 each time
int ttl = i;
// 生成ICMP Echo请求报文
IRecordSetValue pingRequest = createPingRequest(dstIp, icmpId, seqNo);

pingRequest.findField("payload/ipv4/header/timeToLive").setText(Integer.toString(ttl));
// 对报文数据包内的可计算字段进行自动计算(这里是IP协议的HeaderLength和TotalLength字段)
ser.calculate(pingRequest);
// 打印报文内容
if (dumpPacket) {
IValueDumper.INSTANCE.dump(pingRequest);
}
// 编码
byte data[] = ser.encode(pingRequest, false);
// 发送编码数据
socket.write(data);
// 起始时间
long startTime = System.currentTimeMillis();
// 已花费时间(计算超时)
long totalTime = 0;
// 循环接收数据包直到超时
while (totalTime < timeout) {
// 接收数据
int len;
try {
len = socket.read(resData);
} catch (CommTimeoutException e) {
totalTime = timeout;
break;
}
// 解码(底层协议为Ethernet所以使用EtherProtocol作为推测类型)
IRecordSetValue pingResponse = (IRecordSetValue) ProtocolUtils
.decode(resData, 0, len, module.getType("EtherProtocol"));
// 打印报文
if (dumpPacket) {
IValueDumper.INSTANCE.dump(pingResponse);
}
// 取得花费时间
totalTime = System.currentTimeMillis() - startTime;
// 从Icmpv4Protocol中取出EchoReply字段
IRecordSetValue echoReply = (IRecordSetValue) pingResponse
.findField("payload/ipv4/payload/icmpv4/echoReply");
if (echoReply != null)
{
// 判断EchoReply的标识符和序号是否与EchoRequest的一致
if (((IIntegerValue) echoReply.getField("identifier")).getInteger() != icmpId
|| ((IIntegerValue) echoReply.getField("sequenceNumber"))
.getInteger() != seqNo)
{
continue;
}
reachedDst = true;
}
if (echoReply != null|| pingResponse
.findField("payload/ipv4/payload/icmpv4/timeExceeded") != null)
{
// 取得目标设备的IP地址
IRecordSetValue ipv4Header = (IRecordSetValue) pingResponse
.findField("payload/ipv4/header");
String tempIp = ipv4Header.getField("sourceAddress")
.getTextAs(IValueTextStyle.IPV4_ADDRESS);
String newTtl = ipv4Header.getField("timeToLive").getText();
// 打印检验结果
String msg = "(" + i + ") from " + tempIp + ", "
+ totalTime + "(ms), " + " ttl=" + newTtl + ".";
System.out.println(msg);
break;
}
}
// 判断是否超时
if (totalTime >= timeout) {
System.out.println("timeout");
}
// 判断是否到达了目标点
if (!reachedDst) {
continue;
} else {
break;
}
}
// 打印统计信息
String msg = "Traceroute completed. ";
if (reachedDst) {
msg += dstIp + " reached.";
} else {
msg += dstIp + " didn't reach.";
}
System.out.println(msg);

} finally {
// 关闭套接字
socket.close();
}

}

public int getMaxHops() {
return maxHops;
}

public void setMaxHops(int maxHops) {
this.maxHops = maxHops;
}
}

这是主函数的源码:
/*************************************************************************
Protocol Meter, copyright (C) 2007-2008 fineqt.com

Protocol Meter is free software; you can redistribute it and/or modify it
under the terms of version 2.1 of the GNU Lesser General Public License as
published by the Free Software Foundation.

Protocol Meter is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details at gnu.org.
**************************************************************************/
package com.fineqt.fpb.protocol.sample;

import java.net.SocketException;

import com.fineqt.fpb.lib.api.comm.pcap.IPcapSocket;
import com.fineqt.fpb.lib.api.comm.pcap.IPcapSocketFactory;
import com.fineqt.fpb.lib.api.comm.pcap.NetworkInterface;
import com.fineqt.fpb.lib.api.util.IFpbSystem;
import com.fineqt.fpb.lib.api.util.IValueSerializer;
import com.fineqt.fpb.lib.api.value.IValue;

public class SampleMain {
//本地的物理地址
private static final String LOCAL_MAC = "E0:05:C5:74:CB:E1";
//本地的IP地址
private static final String LOCAL_IP = "192.168.0.2";
//FPB的安装根目录
private static final String FPB_HOME = "D:/tools/com.fineqt.fpb.lib";
//FPB协议定义文件所在的目录,通常是FPB的安装根目录下的protocol目录。
private static final String FPB_PROTOCOL_FOLDER =
"D:/tools/com.fineqt.fpb.protocol/protocol";
//网络接口数组
private static NetworkInterface[] ifs;
//默认使用网络接口序号
final static int INTERFACE_INDEX = 0;

public static void main(String[] args) throws Exception {
//FPB系统初始化
IFpbSystem.INSTANCE.init(FPB_HOME, FPB_PROTOCOL_FOLDER);

SampleMain main = new SampleMain();
//Arp
main.testArp();
//Ping
main.testPing();
//TraceRoute
main.testTraceroute();
//TCP Connection
// main.testTcpConnect();
//HTTP GET
// main.testHttpGet();
}

public void testArp() throws Exception {
System.out.println("--------------- do testArp ---------------");
String dstIp = "192.168.0.44";
//生成Pcap套接字来实现链路层通信
IPcapSocket socket = IPcapSocketFactory.INSTANCE.createPcapSocket();
socket.setDevice(getInterface().name);
//生成Arp对象
ArpApp arp = new ArpApp(socket, LOCAL_MAC, LOCAL_IP);
//设置是否打印数据通信内容
arp.setDumpPacket(true);
//取得目标设备的MAC地址
String dstMac = arp.askMac(dstIp);
//打印
System.out.println("Mac for " + dstIp + " is " + dstMac + ".");
}

public void testTraceroute() throws Exception {
System.out.println("--------------- do testTraceroute ---------------");
//网关IP地址
String gatewayIp = "192.168.0.1";
//目标IP地址
String dstIp = "192.168.0.95";
//生成Pcap套接字来实现链路层通信
IPcapSocket socket = IPcapSocketFactory.INSTANCE.createPcapSocket();
socket.setDevice(getInterface().name);
//生成Arp对象
ArpApp arp = new ArpApp(socket, LOCAL_MAC, LOCAL_IP);
//设置是否打印数据通信内容
// arp.setDumpPacket(true);
//取得目标设备的MAC地址
String dstMac = arp.askMac(gatewayIp);
//生成Ping对象
TracerouteApp trace = new TracerouteApp(socket, LOCAL_MAC, dstMac, LOCAL_IP);
// trace.setDumpPacket(true);
//执行
trace.trace(dstIp);
}
...全文
369 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
liublack010101 2012-04-26
  • 打赏
  • 举报
回复
他们说这是使用ICMPv4协议的Echo Request和Echo Reply报文和IPv4协议的TTL字段来实现Traceroute应用。用了已定义的EtherProtocol类型和Ipv4Protocol和Icmpv4Protocol类型来实现了TracerouteApp类。
我到底什么地方不对?

50,558

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧