When parsing TCP header, there's a field named data offset with length of 4 bits. When parsing the header, fields need to be reversed to host oder. Here comes the question: when reversing these fields that are not 16- or 32-bits long which means I can't use ntohs
and ntohl
, do I reverse them field-wise or byte-wise, or in another way?
Let's suppose one byte contains two fields, f1
and f2
of size 4 bits each. The data is 1000 0100
. For the field-wise reversal, the result should be 0001 0010
. For the byte-wise reversal, the result is 0010 0001
. Which one is correct?
Update:
Here is the struct
I'm using to parse the header:
#pragma pack(push, 1)
struct tcp_hdr_t {
uint16_t src_port;
uint16_t dst_port;
uint32_t seq;
uint32_t ack;
uint8_t data_offset : 4;
uint8_t f_reserved : 3;
uint8_t f_ns : 1;
uint8_t f_cwr : 1;
uint8_t f_ece : 1;
uint8_t f_urg : 1;
uint8_t f_ack : 1;
uint8_t f_psh : 1;
uint8_t f_rst : 1;
uint8_t f_syn : 1;
uint8_t f_fin : 1;
uint16_t window_size;
uint16_t checksum;
uint16_t urgent_p;
};
#pragma pack(pop)
If I don't reverse field of data offset and flags, the result is wrong compared with it from Wireshark.
As you can see, the raw data is 0xa002
, but the result seems like 0xa
for data offset doesn't need to be reversed, but the part of flags seems reversed.