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 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.