How to format TCP header values and push to a byte array for packet test in Java

1k Views Asked by At

I am trying to figure out how to push some manually created TCP header data to a byte array. I will be able to use JnetPcap.send(byte[] packet) and see it with wireshark, all I need now is to create the packet as a byte array so I can send it along. I want to do this manually as there are plenty of library functions I could use to create the header.

I simply can't find any explanation on how to format the values or load them to the array. I am also not sure if the values I'm using will be valid. This is what I'm thinking of using...

public static int sourcePort = 1234; //16 bits
public static int destinationPort = 80; //16 bits
public static int sequenceNum = 0; //32 bits - Can this be arbitrary?
public static int ackNum = 0; //32 bits - sequenceNumber + next data start
public static int dataOffset = 5; //4 bits - Minimum value of 5
public static int reserved = 0; //4 bits - Always 0
public static int controlFlags = 0; //8 bits - Not sure if I need any
public static int windowSize = 0; //16 bits Can this be arbitrary?
public static int checkSum = 0; //16 bits - ?use TCP.calculateChecksum() 
public static int urgent = 0; //16 bits

byte[] packet = new byte[160];
//Now load the values into the byte[]

(I am also using JnetPcap built in get ethernet and get Ipv header functions)

UPDATE: I found this snippet which looks like it is the utility I need to put the hex values to byte array:

byte[] pktBytes = FormatUtils.toByteArray("0015c672234c90e6ba92661608004500002d358c4000800600000a000b050a090028c26e270fb8b256e3a2009f785018faf01f550000746573740a");
JMemoryPacket packet = new JMemoryPacket(pktBytes);

So how do I translate my values to go in here. Would it be literally the hex translations appended to each other?

So my 16 bit destinationPort = 80; becomes 0050 ... and 32 bit sequenceNum = 0; becomes 0000 0000 ... 4 bit dataOffset = 5; becomes 5. That seems like it could work, I'm going to give it a try.

(They have 118 hex digits, is that right for TCP header? my values would leave me with 40 hex digits, maybe they have a payload or IP/Ethernet header as well?)

2

There are 2 best solutions below

0
On BEST ANSWER

I found out that I can use the jNetPcap functions to load the header:

Tcp tcp = packet.getHeader(new Tcp());  
tcp.source(sourcePort);  
tcp.destination(destinationPort); 
tcp.seq(sequenceNum);
tcp.ack(ackNum);
tcp.hlen(dataOffset);
tcp.flags(controlFlags);
tcp.window(windowSize);       
tcp.checksum(tcp.calculateChecksum()); 
tcp.urgent(urgent);

This worked for me, but I also could have manually set the byte array and passed in the whole array with full layer 2-3-4 header to the send function.

0
On

The usual way is via a ByteArrayOutputStream wrapped in a DataOutputStream.