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.