Here we are going to introduce how to use jNetPcap to read pcap file offline. jNetPcap is an open-source java library. It contains:
If you want to learn about this package, the best place to start is with jNetPcap examples and tutorials.
Sample Code To Read Pcap File Offline
Consider we have a pcap file "test.pcap" and open it with wireshark look likes:
If you want to read it using jNetPcap, you can try below sample code:
- package test
- import org.jnetpcap.Pcap
- import org.jnetpcap.nio.JBuffer
- import org.jnetpcap.nio.JMemory
- import org.jnetpcap.packet.JFlow
- import org.jnetpcap.packet.JFlowKey
- import org.jnetpcap.packet.JPacket
- import org.jnetpcap.packet.Payload
- import org.jnetpcap.packet.PcapPacket
- import org.jnetpcap.packet.format.FormatUtils
- import org.jnetpcap.protocol.network.Arp
- import org.jnetpcap.protocol.network.Ip4
- import org.jnetpcap.protocol.network.Ip6
- import org.jnetpcap.protocol.tcpip.Tcp
- import org.jnetpcap.protocol.tcpip.Udp
- public static String GetIpAddress(byte[] rawBytes) {
- int i = 4;
- String ipAddress = "";
- for (byte raw : rawBytes)
- {
- ipAddress += (raw & 0xFF);
- if (--i > 0)
- {
- ipAddress += ".";
- }
- }
- return ipAddress;
- }
- public static void PrintUDP(Udp udp, PcapPacket packet)
- {
- String sip=null, dip=null
- Ip4 ip = new Ip4()
- Ip6 ip6 = new Ip6()
- if(packet.hasHeader(ip))
- {
- sip = FormatUtils.ip(ip.source())
- dip = FormatUtils.ip(ip.destination())
- }
- else if(packet.hasHeader(ip6))
- {
- sip = FormatUtils.ip(ip6.source())
- dip = FormatUtils.ip(ip6.destination())
- }
- printf("#%d UDP (%s:%d->%s:%d, %d)%n", packet.getFrameNumber(), sip, udp.source(), dip, udp.destination(), packet.size())
- }
- public static void PrintTCP(Tcp tcp, PcapPacket packet)
- {
- String sip=null, dip=null
- Ip4 ip = new Ip4()
- Ip6 ip6 = new Ip6()
- if(packet.hasHeader(ip))
- {
- sip = FormatUtils.ip(ip.source())
- dip = FormatUtils.ip(ip.destination())
- }
- else if(packet.hasHeader(ip6))
- {
- sip = FormatUtils.ip(ip6.source())
- dip = FormatUtils.ip(ip6.destination())
- }
- printf("#%d TCP seq=%08X (%s:%d->%s:%d, %d)%n", packet.getFrameNumber(), tcp.seq(), sip, tcp.source(), dip, tcp.destination(), packet.size())
- }
- String FILENAME = "data/test.pcap"
- StringBuilder errbuf = new StringBuilder()
- Pcap pcap = Pcap.openOffline(FILENAME, errbuf)
- if (pcap == null)
- {
- System.err.printf("\t[Error] Fail to read pcap file: %s\n", errbuf.toString()); // Error is stored in errbuf if any
- return;
- }
- PcapPacket packet = new PcapPacket(JMemory.POINTER)
- Tcp tcp = new Tcp()
- Udp udp = new Udp()
- Arp arp = new Arp()
- Ip4 ip = new Ip4()
- byte[] dIP = new byte[4], sIP = new byte[4]
- int rt=0
- seqMap = [:].withDefault { key->
- return []
- }
- /*
- * Each packet scanned, also has a flow key associated with it. The flow key
- * is generated based on the headers in each packet and stored with packet
- * state. We can use the flow key to uniquely identify packets belonging to
- * the same stream of packets between end host systems. We will keep a map
- * of various flows with packets in it.
- */
- Map
flows = new HashMap () - while((rt=pcap.nextEx(packet))==1)
- {
- JFlowKey key = packet.getState().getFlowKey()
- JFlow flow = flows.get(key);
- if (flow == null)
- {
- flow = new JFlow(key)
- flows.put(key, flow)
- }
- JPacket npacket = new PcapPacket(packet)
- if(!flow.add(npacket)) System.err.printf("\t[Error] Fail in adding packet in flow!\n")
- //else System.out.printf("\t[Info] Add packet successfully!\n")
- if (npacket.hasHeader(tcp))
- {
- PrintTCP(tcp, npacket)
- }
- else if(npacket.hasHeader(udp))
- {
- PrintUDP(udp, npacket)
- }
- else if(npacket.hasHeader(arp))
- {
- printf("#%d ARP:%s%n", npacket.getFrameNumber(), arp.protocolTypeDescription())
- }
- else
- {
- System.err.printf("#%d Unknown!\n", npacket.getFrameNumber())
- }
- }
- printf("\n")
- printf("\t[Info] Read packet in same flow (%d):\n", flows.size())
- for (JFlow flow : flows.values())
- {
- printf("\t\tFlow(%d):\n", flow.size())
- /*
- * Flows can be bi-directional. That is packets going between host A and B
- * would be considered in forward-direction, while packets between host B
- * and A can be considered reserverse direction. Although both forward and
- * reverse are going in the opposite directions, jnetpcap flows consider
- * them the same flows. You have 3 types of accessors for retrieving
- * packets from a flow. JFlow.getForward, JFlow.getReverse or
- * JFlow.getAll. JFlow.getAll gets a list of packets, no matter which
- * direction they are going, while the other 2 accessors only get the
- * packets that are going in the specified direction.
- */
- if (flow.isReversable())
- {
- /*
- * We can get directional flow packets, but only if the flow is
- * reversable. Not all flows are reversable and this is determined by
- * the header types. If a flow is not reversable, flow.getReverse will
- * return empty list, which is something we don't want to have to
- * process.
- */
- printf("\tForward->\n")
- List
forward = flow.getForward(); - for (JPacket p : forward)
- {
- if (p.hasHeader(tcp)) PrintTCP(tcp, p)
- //System.out.printf("%d, ", p.getFrameNumber());
- }
- System.out.println();
- printf("\tReverse<- n="" span="">) ->
- List
reverse = flow.getReverse(); - for (JPacket p : reverse)
- {
- if (p.hasHeader(tcp)) PrintTCP(tcp, p)
- //System.out.printf("%d, ", p.getFrameNumber());
- }
- System.out.println()
- }
- else
- {
- /*
- * Otherwise we have to get All the packets and there is no
- * forward/reverse direction associated with the packets. Here is how we
- * can do this a little more compactly.
- */
- for (JPacket p : flow.getAll())
- {
- //System.out.printf("%d, ", p.getFrameNumber());
- if (p.hasHeader(tcp)) PrintTCP(tcp, p)
- }
- }
- System.out.println();
- }
- if(rt==-1) System.err.printf("\t[Error] Fail to read pcap file!\n")
- pcap.close()
Supplement
* Tutorial 2 - API usage
* libpcap - Opening offline capture
* Accessing headers in a packet
* How do I convert raw IP address to String?
* jnetpcap - Convert byte[] to ip address v6
* Support forum - How to access data from PcapPacket?
沒有留言:
張貼留言