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_IP
, IPPROTO_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));