Jnetpcap, preparing UDP / TCP / IP / ICMP packet

Recently, I have been using Jnetpcap to send / receive raw packets over the network.

Jnetpcap provides sending packets by Pcap.sendPacket() . This method gets the raw buffer or bytes to send.

On the other hand, there are org.jnetpcap.protocol.* Classes that wrap protocol headers, and we can use them to decode captured packets.

When I use the code below to create an Ip4 package, it throws a NullPointerException:

 import org.jnetpcap.protocol.network.Ip4; public class Test { public static void main(String[] args) { Ip4 ip4 = new Ip4(); ip4.ttl(10); } } 

Error:

 Exception in thread "main" java.lang.NullPointerException at org.jnetpcap.nio.JBuffer.check(Unknown Source) at org.jnetpcap.nio.JBuffer.setUByte(Unknown Source) at org.jnetpcap.protocol.network.Ip4.ttl(Unknown Source) at jaeger.Test.main(Test.java:17) 

How can I create this package and then send it to Pcap.sendPacket() ?

Note. I'm really not interested in preparing bytes by bytes ... C / C ++ libpcap and Jpcap have functionality, but I want to use Jnetpcap!

+6
source share
2 answers

1) . The code throws an exception, because wrapper classes only work using previously allocated buffers, because the main purpose of the library is to analyze the buffers of captured packets. Thus, before using them, you must allocate a buffer.

2) Packets must be built with the delivery of all necessary bytes. But the code can be written so that only a few bytes are really needed (see above).

3) sendPacket expects a whole packet, a full Ethernet frame. Thus, the Ethernet, IP, TCP, and payload headers must be written to the buffer.

4) The main idea that allows you to use wrapper classes is to allocate a buffer, and then leave the library to scan headers, but minimal information (bytes) should be provided.

 JMemoryPacket packet = new JMemoryPacket(packetSize); packet.order(ByteOrder.BIG_ENDIAN); 

An Ethernet frame requires a protocol type (0x0800) at position 12:

 packet.setUShort(12, 0x0800); packet.scan(JProtocol.ETHERNET_ID); 

After scan you can extract the Ethernet instance and install the setters:

 Ethernet ethernet = packet.getHeader( new Ethernet() ); ethernet.destination(...); ... 

IP4 header needs version (0x04) and size (0x05) at position 14:

 packet.setUByte(14, 0x40 | 0x05); packet.scan(JProtocol.ETHERNET_ID); Ip4 ip4 = packet.getHeader( new Ip4() ); ip4.type(0x06); //TCP ip4.length( packetSize - ethernet.size() ); ip4.ttl(...); ... 

TCP header requires size (0x50):

 packet.setUByte(46, 0x50); packet.scan(JProtocol.ETHERNET_ID); Tcp tcp = packet.getHeader( new Tcp() ); tcp.seq(...); ... 

So the payload:

 Payload payload = packet.getHeader( new Payload() ); payload.set...(...); ... 

And finally:

 pcap.sendPacket( ByteBuffer.wrap( packet.getByteArray(0, packet.size() ) ); 

5) All necessary bytes can be written in one go to avoid so many calls to the scan method.

+8
source

You are faced with the problem of how to write subdedecs on jNetPcap ? Yes, JNetPcap takes bytes to send, but the contents can be filled with subheadings using the help I gave. If you want to send some data inside a package, many Java types have a toBytes() function or similar.

change
The API for this particular Icmp class is here . Similarly, this can be done for other classes on this link. Just google and give "Icmp class reference jnetpcap" or whatever for other types of headers.

edit2:
An easier way to create an ICMP packet is to use the ICMPPacket class , which has a simple constructor for the ICMP packet, where headers are created in a single Constructor call. According to the class reference, it does the following:

Extends the IP packet by adding an ICMP header and an ICMP data payload.

+1
source

Source: https://habr.com/ru/post/901543/


All Articles