James King
James King

Reputation: 1614

When to use ntohs function in net programming?

I am learning net programming using WinPcap. Here is the snippet:

int ip_hlen = (ih->ver_ihl & 0xf) * 4; /* get ip header length */
tcp_header *th = (tcp_header *) ((u_char*)ih + ip_len);
int tcp_hlen = (ntohs(th->th_len_resv_code) & 0xf000) >> 12)*4; /* get tcp header length */

The problem is why ntohs is only used when getting tcp_hlen not ip_hlen.
Indeed, ntohs only taks in u_short as parameter explains a little. http://msdn.microsoft.com/en-us/library/windows/desktop/ms740075%28v=vs.85%29.aspx

I am still puzzled about when using ntohs when not.

Here is the struct of IP and TCP packet definition:

/* ipv4 header */
typedef struct ip_header {
    u_char ver_ihl;         /* version and ip header length */
    u_char tos;             /* type of service */
    u_short tlen;           /* total length */
    u_short identification; /* identification */
    u_short flags_fo;       // flags and fragment offset
    u_char ttl;             /* time to live */
    u_char proto;           /* protocol */
    u_short crc;            /* header checksum */
    ip_address saddr;       /* source address */
    ip_address daddr;       /* destination address */
    u_int op_pad;           /* option and padding */
}ip_header;

/* tcp header */
typedef struct tcp_header {
    u_short th_sport;         /* source port */
    u_short th_dport;         /* destination port */
    u_int th_seq;             /* sequence number */
    u_int th_ack;             /* acknowledgement number */
    u_short th_len_resv_code; /* datagram length and reserved code */
    u_short th_window;        /* window */
    u_short th_sum;           /* checksum */
    u_short th_urp;           /* urgent pointer */
}tcp_header;

Upvotes: 1

Views: 4410

Answers (4)

Jonas Bötel
Jonas Bötel

Reputation: 4482

It's pretty simple. You'll need ntohs (read Net TO Host conversion for Short values) whenever you are encountering a 16 bit value in received via network. The reason is endianess of different systems when encoding those numbers into multibytes.

Upvotes: 0

kfsone
kfsone

Reputation: 24269

ntohs is Network To Host - Short. A short is 16 bits. An example of when you would use ntohs is the 16-bit 'port' value, if you are extracting a port value from a sockaddr struct.

uint16_t portNo = ntohs(sock.sin_port);

you should be doing the converce, htons, when oyu put the port number into sockaddr structs in the first place.

You only need to use it in places where you are expecting endianess conversion. Parts of headers and protocol variables, in particular. For the user portion of packets (your data) its at your discretion.

Upvotes: 0

Artur
Artur

Reputation: 7257

If your value is 8bit long there is no worry about endianess. That is all. You cannot reorder bytes in one byte.

Upvotes: 2

unwind
unwind

Reputation: 399959

Because the IP header length field is so small (only four bits), it is assumed to fit in one byte, and thus it can never have any endianness-issues. There is only one byte, so no bytes to swap using the ntohs() function.

Upvotes: 5

Related Questions