I'm very confused in when to use ntohs and ntohl. I know when you use ntohs for uint16_t and ntohl uint32_t. But what about those with unsigned int or those where a specific amount of bits is specified (e.g. u_int16_t doff:4;).
Here is my working code to demostrate the issue:
// Utility/Debugging method for dumping raw packet data
void dump(const unsigned char *data, int length) {
unsigned int i;
static unsigned long pcount = 0;
// Decode Packet Header
struct ether_header *eth_header = (struct ether_header *) data;
printf("\n\n === PACKET %ld HEADER ===\n", pcount);
printf("\nSource MAC: ");
for (i = 0; i < 6; ++i) {
printf("%02x", eth_header->ether_shost[i]);
if (i < 5) {
printf(":");
}
}
printf("\nDestination MAC: ");
unsigned short ethernet_type = ntohs(eth_header->ether_type);
printf("\nType: %hu\n", ethernet_type); //Why not nthos?
if (ethernet_type == ETHERTYPE_IP) { //IP Header
printf("\n == IP HEADER ==\n");
struct ip *ip_hdr = (struct ip*) (data + sizeof(struct ether_header));
unsigned int size_ip = ip_hdr->ip_hl * 4; //why no nthos or nthol
printf("\nip_hdr->ip_hl: %u", ip_hdr->ip_hl); //why no nthos or nthol
printf("\nIP Version: %u", ip_hdr->ip_v); //why no nthos or nthol
printf("\nHeader Length: %u", ip_hdr->ip_hl); //why no nthos or nthol
printf("\nTotal Length: %hu", ntohs(ip_hdr->ip_len)); //?is this right?
// TCP Header
printf("\n== TCP HEADER ==\n");
struct tcphdr *tcp_hdr = (struct tcphdr*) (data + sizeof(struct ether_header) + size_ip);
unsigned int size_tcp = tcp_hdr->doff * 4; //why no nthos or nthol
printf("\n Source Port: %" PRIu16, ntohs(tcp_hdr->th_sport));
printf("\n Destination Port: %" PRIu16, ntohs(tcp_hdr->th_dport));
printf("\n fin: %" PRIu16, tcp_hdr->fin ); //As this is 1 bit, both nthos or nthol will work
printf("\n urg: %" PRIu16, tcp_hdr->urg ); //As this is 1 bit, both nthos or nthol will work
printf("\n ack_seq: %" PRIu32, ntohl(tcp_hdr->ack_seq));
u_int16_t sourcePort = ntohs(tcp_hdr->th_sport);
u_int16_t destinationPort = ntohs(tcp_hdr->th_sport);
if (sourcePort == 80 || destinationPort == 80){
printf("\n\nPORT 80!!!\n");
//Transport payload!
printf("\n\ === TCP PAYLOAD DATA == \n");
// Decode Packet Data (Skipping over the header)
unsigned int headers_size = ETH_HLEN + size_ip + size_tcp;
unsigned int data_bytes = length - headers_size;
const unsigned char *payload = data + headers_size;
const static int output_sz = 500; // Output this many bytes at a time
while (data_bytes > 0) {
int output_bytes = data_bytes < output_sz ? data_bytes : output_sz;
// Print data in raw hexadecimal form
printf("| ");
// Print data in ascii form
for (i = 0; i < output_bytes; ++i) {
char byte = payload[i];
if ( (byte > 31 && byte < 127) || byte == '\n') {
// Byte is in printable ascii range
printf("%c", byte); //why no nthos or nthol
} else {
printf(".");
}
}
payload += output_bytes;
data_bytes -= output_bytes;
}
}
}
pcount++;
}
As you can see there are times I use ntohs/ntohl and there are times I use neither. I don't understand when to use which.