C to get IP header field values ​​from Linux IP stack

I am developing a program in which I need to know the values ​​of the IP header fields inside my program. Since the IP header is 20 bytes:

struct ipheader { unsigned char ip_hl:4, ip_v:4; /* this means that each member is 4 bits */ unsigned char ip_tos; unsigned short int ip_len; unsigned short int ip_id; unsigned short int ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short int ip_sum; unsigned int ip_src; unsigned int ip_dst; }; 

Is there any way to know the values ​​of these fields inside my C program?

+2
c
source share
3 answers

If your compiler does not enter any alignment blocks in this structure (make sure CHAR_BIT is 8 and sizeof(struct ipheader) is 20), you should just include it in your code as is, and then add something like:

 struct ipheader *iph = (struct ipheader *)blk; printf ("TTL = %d\n", iph->ip_ttl); 

In this code, you will have the IP header blk points to, which is probably char* . Casting it to the right type of pointer allows you to easily access fields.

The following complete program shows this in action:

 #include <stdio.h> #include <limits.h> struct ipheader { /* 0 */ unsigned char ip_hl:4, ip_v:4; /* 1 */ unsigned char ip_tos; /* 2 */ unsigned short int ip_len; /* 3 */ unsigned short int ip_id; /* 4 */ unsigned short int ip_off; /* 5 */ unsigned char ip_ttl; /* 6 */ unsigned char ip_p; /* 7 */ unsigned short int ip_sum; /* 8 */ unsigned int ip_src; /* 9 */ unsigned int ip_dst; }; int main (void) { char blk[] = { '\x00','\x11','\x22','\x22','\x33','\x33','\x44','\x44', '\x55','\x66','\x77','\x77','\x88','\x88','\x88','\x88', '\x99','\x99','\x99','\x99' }; struct ipheader *iph = (struct ipheader *)(&blk); printf ("TTL = %x\n", iph->ip_ttl); printf ("sum = %x\n", iph->ip_sum); printf ("dst = %x\n", iph->ip_dst); return 0; } 

The output, as expected:

 TTL = 55 sum = 7777 dst = 99999999 
+1
source share

Some of these values ​​can be set / obtained by calling setsockopt()/getsockopt() at the SOL_IP/IPPROTO/IP level. Refer to your OS documentation (for example: on Linux man 7 ip ).

+1
source share

You must use setsockopt/getsockopt to interact with the socket engine. These functions work at different levels ( IPPROTO_IP , IPPROTO_TCP , etc.), and some parameters are available only for certain types of sockets (for example, the IP_TTL option is available only for AF_INET sockets).

get the TTL value:

 int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); unsigned int opt_val; unsigned int opt_len; getsockopt(sock, IPPROTO_IP, IP_TTL, &opt_val, &opt_len); printf("ttl %d\n", opt_val); 

set TTL value:

 int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); unsigned char ttl_val = 32; setsockopt(sock, IPPROTO_IP, IP_TTL, &ttl_val, sizeof(ttl_val)); 
0
source share

All Articles