C程序从Linux IP堆栈获取IP头字段的值

我正在开发一个程序,我需要知道程序中的IP头字段的值。因为IP头是20个字节:

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; }; 

有什么方法可以让我知道C程序中这些字段的值吗?

如果您的编译器没有在该结构中引入任何对齐块(确保CHAR_BIT为8且sizeof(struct ipheader)为20),您应该只能将它包含在代码中,然后添加类似:

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

在该代码中,您将拥有blk指向的IP头,这可能是一个char* 。 将其转换为正确的指针类型将允许您轻松访问字段。

以下完整程序显示了这一点:

 #include  #include  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; } 

按预期输出:

 TTL = 55 sum = 7777 dst = 99999999 

其中一些值可以通过SOL_IP/IPPROTO/IP级别的setsockopt()/getsockopt()调用来设置/检索。 请查阅您的操作系统文档(例如:在Linux man 7 ip )。

您应该使用setsockopt/getsockopt例程来与套接字机制进行交互。 这些function在不同级别( IPPROTO_IPIPPROTO_TCP等)上运行,某些选项仅适用于特定套接字类型(例如,选项IP_TTL仅适用于AF_INET套接字)。

得到TTL值:

 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); 

设置TTL值:

 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));