11.4.4 定位IP包头的编程方法

11.4.4  定位IP包头的编程方法

获得以太网帧后,当协议为0x0800时,其负载部分为IP协议。IP协议的数据结构如图11.12所示。

 

11.12  IP数据的示意图

IP头部的数据结构定义在头文件<Linux/ip.h>中,代码如下:

 

struct iphdr {

#if defined(__LITTLE_ENDIAN_BITFIELD)/*小端*/

    __u8     ihl:4,              /*IP头部长度,单位为32bit*/

        version:4;              /*IP版本,值为4*/

#elif defined (__BIG_ENDIAN_BITFIELD)/*大端*/

    __u8     version:4,          /*IP版本,值为4*/

            ihl:4;              /*IP头部长度,单位为32bit*/

#else

#error  "Please fix <asm/byteorder.h>"

#endif

    __u8     tos;                /*服务类型*/

    __be16  tot_len;            /*总长度*/

    __be16  id;                 /*标识*/

    __be16  frag_off;           /*片偏移*/

    __u8     ttl;                /*生存时间*/

    __u8     protocol;           /*协议类型*/

    __u16   check;              /*头部校验和*/

    __be32  saddr;              /*IP地址*/

    __be32  daddr;              /*目的IP地址*/

      /*IP选项*/

};

 

若捕获的以太帧中h_proto的取值为0x0800,将类型为iphdr的结构指针指向帧头后面载荷数据的起始位置,则可以得到IP数据包的报头部分。通过saddrdaddr可以得到IP报文的源IP地址和目的IP地址,下面的代码打印IP报文的源IP地址和目的IP地址。

 

/*打印IP报文的源IP地址和目的IP地址*/

if(ntohs(p_ethhdr->h_proto)==0x0800)       /*0x0800:IP*/

{

    /*定位IP头部*/

    struct iphdr*p_iphdr = (struct iphdr*) (ef + ETH_HLEN);

    /*打印源IP地址*/

    printf("src ip:%s/n", inet_ntoa(p_iphdr->saddr));

    /*打印目的IP地址*/

    printf("dest ip:%s/n", inet_ntoa(p_iphdr->daddr));

你可能感兴趣的:(数据结构,编程,struct)