📄 packetanalyzer.java
字号:
package joel.ethernettools;
/**
* MAIN PACKET ANALYZER CLASS.
* SUPPORTED PROTOCOLS:
* DATA-LINK-LAYER:
* ETHERNET->RFC894
* ARP/RARP->RFC826
* PPPOE[USED FOR xDSL]
* NETWORK-LAYER:
* ICMP->RFC792
* IP->RFC791
* TCP
* UDP->RFC768
*/
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.GregorianCalendar;
import java.util.InvalidPropertiesFormatException;
import java.util.Properties;
import jpcap.packet.DatalinkPacket;
import jpcap.packet.EthernetPacket;
import jpcap.packet.Packet;
public class PacketAnalyzer implements Runnable {
//3rd layer protocols,load from .xml file.
private Properties ProtocolTypes;
//packet property container temporarily.
private Properties info = new Properties();
private Packet packet;
private ProcessedPacket prsdPacket;
//standard ethernet head length.
private int ETHERNET_HEAD_LENGTH = 14;
//PPPoE & PPP protocol difinition.not included in jpcap.
private final int PPPoE_SESSION_LENTH = 6, PPP_LENTH = 2;
//PPPoE protocol flag.not included in jpcap.
private final int ETHERNET_PPPoE = -30620;
//standard ip-head-length=20 bytes
//xxxEntrance means the start byte of xxxProtocol in CompleteData(byte[]).
private int ipHeadLength = 0, TCPUDPEntrance = 0, IPEntrance = 0;
//packet pool is for holding packet/OriginalPacket/ProcessedPacket temporarily for further log or analyze.
private PacketPool pool;
//second-layer=datalink-layer(like pppoe/ppp/arp/rarp,etc)
//third-layer=network-layer(like ip,ipx,etc)
private String SecondLayerProtocolType, ThirdLayerProtocolType;
//system message outputer
private MsgProvider provider;
//record current thread fetched/processed packet count.
private int PacketFetched=0,PacketProcessed=0;
/**
* default constructor.
*/
public PacketAnalyzer() {
this.loadProtocolTypes();
provider = new MsgProvider();
}
/**
* set the <code>PacketPool</code> for getting Packet/OriginalPacket/ProcessedPacket.
* @param pool
*
*/
protected void setPacketPool(PacketPool pool) {
this.pool = pool;
}
protected void setMsgReceiver(MsgReceiver m) {
provider.addMsgReceiver(m);
}
private void processCaptureInfo() {
info.put("CAPTURED_TIME", GregorianCalendar.getInstance().getTime()
.toString());
info.put("PACKET_LENGTH", Integer.toString(packet.len));
}
private byte[] combineCompleteData(byte[] head, byte[] data) {
byte[] temp = new byte[head.length + data.length];
int i = 0;
for (; i < head.length; i++)
temp[i] = head[i];
for (int k = 0; i < temp.length; k++, i++)
temp[i] = data[k];
return temp;
}
public void run() {
provider.addNewMsg("analyze thread started.name="
+ Thread.currentThread().getName());
byte[] CompleteData;
while (true) {
while ((this.packet = pool.getNewPacket()) == null) {
try {
Thread.currentThread().sleep(
Math.round(Math.random() * 1000 * 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// skip PPPoE echo/reply packets.
if (packet.len == 30 || packet.len == 60)
continue;
PacketFetched++;
info.clear();
this.processCaptureInfo();
this.processDatalinkProperties(packet.datalink);
if (SecondLayerProtocolType.equals("ARP")) {
prsdPacket=new ProcessedPacket(info);
pool.addNewProcessedPacket(prsdPacket);
continue;
}
CompleteData = this.combineCompleteData(packet.header, packet.data);
if (SecondLayerProtocolType.equals("PPPoE"))
this.IPEntrance = this.ETHERNET_HEAD_LENGTH
+ this.PPPoE_SESSION_LENTH + this.PPP_LENTH;
else
this.IPEntrance = this.ETHERNET_HEAD_LENGTH;
this.ipHeadLength = this.convertBintoInt(
new byte[] { CompleteData[this.IPEntrance] }, 4, 8) * 4;
this.TCPUDPEntrance = this.IPEntrance + this.ipHeadLength;
this.setIPHeadProperties(CompleteData, IPEntrance);
if (SecondLayerProtocolType.equals("ICMP")) {
prsdPacket=new ProcessedPacket(info);
pool.addNewProcessedPacket(prsdPacket);
continue;
}
if (ThirdLayerProtocolType.equals("TCP")) {
this
.setTCPUDPPacketPortProperties(CompleteData,
TCPUDPEntrance);
this.setTCPPacketProperties(CompleteData, TCPUDPEntrance);
}
if (ThirdLayerProtocolType.equals("UDP")) {
this
.setTCPUDPPacketPortProperties(CompleteData,
TCPUDPEntrance);
}
info.put("PACKET_DATA",OriginalPacket.convertByteArrayToString(CompleteData));
PacketProcessed++;
prsdPacket=new ProcessedPacket(info);
pool.addNewProcessedPacket(prsdPacket);
CompleteData=null;
this.prsdPacket=null;
}
}
/**
* convert byte to binary,then convert to int.
*
* @param b
* @see #convertBintoInt(byte[], int, int)
* @return
*/
private int convertBinToInt(final byte b[]) {
return this.convertBintoInt(b, 0, 8 * b.length);
}
/**
* convert byte to binary,then convert to int.
* 1.convert each byte in byte[] to BinString.
* 2.each byte must be 8 bits,if less,fill with 0 in high-bit.
* 3.combine every BinString to one BinString.
* 4.convert BinString to int.
* @param b
* @param start
* ,start position
* @param end
* ,end position
* @return
*/
private int convertBintoInt(final byte[] b, int start, int end) {
int v = 0, k = 0;
if (start * end < 0 || start > end || b == null)
throw new IllegalArgumentException("start=" + start + ",end=" + end
+ ",b" + b == null ? "=" : "<>" + "null");
String s, s2 = "";
for (int i = 0; i < b.length; i++) {
s = Integer.toBinaryString((int) b[i] & 0xff);
k = 8 - s.length();
for (; k > 0; k--)
s = "0" + s;
s2 += s;
}
char[] str = s2.toCharArray();
for (int i = start; i < end; i++) {
if (str[i] == '0')
continue;
else
v += Math.pow(2, str.length - i - 1);
}
return v;
}
/**
* set TCP/UDP src/dst port property.
* src/dst port is 2-byte,which can be 0-65535.
* @param data which is CompleteData.
* @param entrance which is TCPUDPEntrance.
*/
private void setTCPUDPPacketPortProperties(final byte[] data, int entrance) {
byte[] temp = new byte[2];
int port = 0;
temp[0] = data[entrance];
temp[1] = data[entrance + 1];
port = this.getPortByByteArray(temp);
info.put("SOURCE_PORT", port == 0 ? "UNKNOWN" : String.valueOf(port));
temp[0] = data[entrance + 2];
temp[1] = data[entrance + 3];
port = this.getPortByByteArray(temp);
info.put("DESTINATION_PORT", port == 0 ? "UNKNOWN" : String
.valueOf(port));
}
/**
* convert data to port NO.
*
* @param data
* byte[2]
* @return port NO.
*/
private int getPortByByteArray(final byte[] data) {
int port = 0;
if (data.length != 2)
return port;
port = this.convertBinToInt(data);
return port;
}
/**
* set TCP Packet property.
* including TCP-flag,which is
* U=URGENT.
* A=ACKNOWLEDGE
* P=PUSH
* R=RESET
* S=SYNCHRONIZE
* F=FINISH
*
* @param data
* @param entrance
*/
private void setTCPPacketProperties(final byte[] data, int entrance) {
String flag = "";
char[] flags;
String str = Integer.toBinaryString((int) data[entrance + 13]);
for (int i = 6 - str.length(); i > 0; i--)
str = "0" + str;
flags = str.toCharArray();
for (int i = 0; i < flags.length; i++) {
if (flags[i] == '1')
switch (i) {
case 0: {
flag += "U";
continue;
}
case 1: {
flag += "A";
continue;
}
case 2: {
flag += "P";
continue;
}
case 3: {
flag += "R";
continue;
}
case 4: {
flag += "S";
continue;
}
case 5: {
flag += "F";
continue;
}
}
}
info.put("TCP_FLAG", flag);
}
/**
* set data-link layer property.
* which including:
* src mac address
* dst mac address
* data-link layer frame-type
* @param datalink
*/
private void processDatalinkProperties(final DatalinkPacket datalink) {
info.put("DATELINK_ETHERNET_FRAMETYPE", this
.getEthernetFrameType(datalink));
info.put("DATELINK_ETHERNET_SRCADDR", this
.getMACAddr(((EthernetPacket) datalink).src_mac));
info.put("DATELINK_ETHERNET_DSTADDR", this
.getMACAddr(((EthernetPacket) datalink).dst_mac));
}
/**
* set ip-head property.
* which including:
* ip sub-protocol type
* src ip address
* dst ip address
* @param data
* @param ipEntrance
*/
private void setIPHeadProperties(byte[] data, int ipEntrance) {
ThirdLayerProtocolType = this.getIPProtocolType(data, ipEntrance);
info.put("IP_SUB_PROTOCOL_TYPE", ThirdLayerProtocolType);
info.put("IP_SRCADDR", this.getIPAddr(data, true, ipEntrance));
info.put("IP_DSTADDR", this.getIPAddr(data, false, ipEntrance));
}
/**
* get src/dst ip address from CompleteData.
* @param data which is CompleteData.
* @param isSrcIPAddr which is a boolean flag.
* @param ipEntrance which is the ipEntrance.
* @return a String representation of InetAddress.
*/
private String getIPAddr(final byte[] data, boolean isSrcIPAddr,
int ipEntrance) {
String ip = "UNKNOWN";
int position = isSrcIPAddr ? ipEntrance + 12 : ipEntrance + 16;
byte[] temp_ip = new byte[4];
for (int i = 0; i < temp_ip.length; i++) {
temp_ip[i] = data[i + position];
}
try {
ip = InetAddress.getByAddress(temp_ip).getHostAddress();
} catch (UnknownHostException e) {
ip = "UNKNOWN";
}
return ip;
}
/**
* load third-layer-protocols from xml file.
*/
private void loadProtocolTypes() {
ProtocolTypes = new Properties();
try {
ProtocolTypes.loadFromXML(new FileInputStream(System.getProperty("user.dir")+System.getProperty("file.separator")+"XML/protocol_list.xml"));
} catch (InvalidPropertiesFormatException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("load protocol types end.");
}
/**
* get a String representation of third-layer-protocol type.
* @param data which is CompleteData
* @param ipEntrance which is ipEntrance
* @return a String representation of third-layer-protocol type.
*/
private String getIPProtocolType(final byte[] data, int ipEntrance) {
// System.out.println("processing ip procotol type.");
String temp = String.valueOf((int) data[ipEntrance + 9] & 0xff);
temp = ProtocolTypes.getProperty(temp);
return temp == null ? "UNKNOWN" : temp;
}
private String getMACAddr(final byte[] mac) {
String temp = "";
temp = NIC.getMACString(mac);
return temp;
}
/**
* get string representation of protocol flag in datalinkhead of the packet.
*
* @param p which is a data-link-layer packet from packet.
* @return string representation.
*/
private String getEthernetFrameType(final DatalinkPacket p) {
EthernetPacket ether = (EthernetPacket) p;
switch (ether.frametype) {
case EthernetPacket.ETHERTYPE_ARP: {
SecondLayerProtocolType = "ARP";
break;
}
case EthernetPacket.ETHERTYPE_IP: {
SecondLayerProtocolType = "IP";
break;
}
case EthernetPacket.ETHERTYPE_IPV6: {
SecondLayerProtocolType = "IPV6";
break;
}
case EthernetPacket.ETHERTYPE_LOOPBACK: {
SecondLayerProtocolType = "LOOPBACK";
break;
}
case EthernetPacket.ETHERTYPE_PUP: {
SecondLayerProtocolType = "Xerox PUP";
break;
}
case EthernetPacket.ETHERTYPE_REVARP: {
SecondLayerProtocolType = "RARP";
break;
}
case EthernetPacket.ETHERTYPE_VLAN: {
SecondLayerProtocolType = "802.1Q VLAN";
break;
}
case ETHERNET_PPPoE: {
SecondLayerProtocolType = "PPPoE";
break;
}
default:
SecondLayerProtocolType = "UNKOWN";
}
return SecondLayerProtocolType;
}
/**
* @param args
*/
public static void main(String[] args) {
java.util.Vector v=new java.util.Vector();
}
protected int getPacketFetched() {
return PacketFetched;
}
protected int getPacketProcessed() {
return PacketProcessed;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -