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

C程序从Linux IP堆栈中获取IP头字段的值,c,C,我正在开发一个程序,需要知道程序中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头字段的值。由于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\u BIT
为8,并且
sizeof(struct ipheader)
为20),您应该能够将其按原样包含在代码中,然后添加如下内容:

struct ipheader *iph = (struct ipheader *)blk;
printf ("TTL = %d\n", iph->ip_ttl);
在该代码中,您将有一个由
blk
指向的IP头,它可能是一个
char*
。将其转换为正确的指针类型将允许您轻松访问字段

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

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

其中一些值可以通过
SOL_IP/IPPROTO/IP
级别的
setsockopt()/getsockopt()
调用进行设置/检索。请参阅操作系统的文档(例如:在Linux上
MAN7IP
)。

您应该使用
setsockopt/getsockopt
例程与套接字机制进行接口。这些功能在不同级别上运行(
IPPROTO\u IP
IPPROTO\u TCP
等),一些选项仅适用于特定的插座类型(例如,选项
IP\u TTL
仅适用于
AF\u 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);
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));
设置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);
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));

您是否想知道如何解析现有数据包中的字段,或者如何首先捕获包含标题的数据包?我建议您先看一看-这会让您的生活更轻松。问题是如何获取这些系统值,因为在创建简单数据报包(UDP)时,我填充了SrcIP和端口,DEst IP address和port并发送数据包,其余值默认从系统堆栈中选取。因此,我想知道rest字段的值,例如:ttl、tos等。基本上,我提供的结构仅供参考,真正的问题是如何获取这些系统值,因为在创建简单数据报数据包(UDP)时我填写SrcIP和port、DEst IP address和port并发送数据包,其余值默认从系统堆栈中选取。其余值包括IP_ttl、IP_tos等