C 如何从iph访问IP_DF和IP_MF->;使用netfilter时的frag_偏移

C 如何从iph访问IP_DF和IP_MF->;使用netfilter时的frag_偏移,c,linux-kernel,kernel,netfilter,C,Linux Kernel,Kernel,Netfilter,我正在尝试编写一个netfilter模块,并希望访问IPHeader中表示DF和MF字段的字段。我可以根据需要访问大多数其他字段,但我认为我必须从结构中的ipheader中提取DF和MF字段,并对它们进行操作,例如,我想根据接收的数据包类型设置或取消设置DF位 下面的结构有“frag_off”,我如何从中访问/重写IP_DF和IP_MF struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4,

我正在尝试编写一个netfilter模块,并希望访问IPHeader中表示DF和MF字段的字段。我可以根据需要访问大多数其他字段,但我认为我必须从结构中的ipheader中提取DF和MF字段,并对它们进行操作,例如,我想根据接收的数据包类型设置或取消设置DF位

下面的结构有“frag_off”,我如何从中访问/重写IP_DF和IP_MF

struct iphdr {
    #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8    ihl:4,
                version:4;
    #elif defined (__BIG_ENDIAN_BITFIELD)
        __u8    version:4,
                ihl:4;
    #else
        #error  "Please fix <asm/byteorder.h>"
    #endif
         __u8   tos;
         __u16  tot_len;
         __u16  id;
         __u16  frag_off;
         __u8   ttl;
         __u8   protocol;
         __u16  check;
         __u32  saddr;
         __u32  daddr;
         /*The options start here. */
};

#define IP_MF 0x2000 /* Flag: "More Fragments" */
#define IP_OFFSET 0x1FFF /* "Fragment Offset" part */
#define IP_DF 0x4000 /* dont fragment flag */
      printk(KERN_INFO "IP_FRAG_OFF : %d", (iph->frag_off & IP_OFFSET));
      printk(KERN_INFO "MF: %d", (iph->frag_off & IP_MF));
struct iphdr{
#如果已定义(uuu LITTLE_ENDIAN_位字段)
__u8国际人道主义法:4,
版本:4;
#elif已定义(_BIG_ENDIAN_位域)
__u8版本:4,
国际人道主义法:4;
#否则
#错误“请修复”
#恩迪夫
__u8 tos;
__u16托特伦;
__u16-id;
__u16 frag_off;
__u8 ttl;
__u8协议;
__u16检查;
__u32-saddr;
__u32 daddr;
/*选项从这里开始*/
};
#定义IP_MF 0x2000/*标志:“更多碎片”*/
#定义IP_偏移0x1FF/*“碎片偏移”零件*/
#定义IP_DF 0x4000/*不分段标志*/
printk(内核信息“IP\u FRAG\u OFF:%d”,(iph->FRAG\u OFF&IP\u OFFSET));
printk(KERN_INFO“MF:%d”,(iph->frag_off&IP_MF));

字段frag\u off为16位。 前3位是标志,其余13位是偏移量

标志位为:first为保留位,必须为0。第二个是DF,第三个是MF。 因此,要访问DF,您应该通过“frag_off&0x4000”隔离第二位,并将IP_DF声明为0x4000,这样您就可以执行“iph->frag_off&IP_DF”

MF 0x2000和偏移量IP_偏移量0x1FF相同