Linux Netfilter开发小结

前置知识:





IP包:
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
	unsigned char	ip_hl:4,		/* header length */
		ip_v:4;			/* version */
#endif
	unsigned char	ip_tos;			/* type of service */
	short	ip_len;	/* total length */
	unsigned short	ip_id;/* identification */
	short	ip_off;		
	unsigned char	ip_ttl;/* time to live */
	unsigned char	ip_p;/* protocol */
	unsigned short	ip_sum;	
          struct	in_addr ip_src,ip_dst;/* source and dest address */
};



IHL(Internet Header Length 报头长度),位于IP报文的第二个字段,4位,表示IP报文头部按32位字长(32位,4字节)计数的长度,也即报文头的长度等于IHL的值乘以4。 (ip_hl)




TCP头
struct tcphdr {
	u_short	th_sport;	/* source port */
	u_short	th_dport;	/* destination port */
	tcp_seq	th_seq;	/* sequence number */
	tcp_seq	th_ack;	/* acknowledgement number */
#if BYTE_ORDER == LITTLE_ENDIAN
	u_char	th_x2:4,	/* (unused) */
		th_off:4;	/* data offset */
#endif
#if BYTE_ORDER == BIG_ENDIAN
	u_char	th_off:4,	/* data offset */
		th_x2:4;	/* (unused) */
#endif
	u_char	th_flags;
#define	TH_FIN	0x01
#define	TH_SYN	0x02
#define	TH_RST	0x04
#define	TH_PUSH	0x08
#define	TH_ACK	0x10
#define	TH_URG	0x20
#define TH_FLAGS (TH_FIN|TH_SYN|
             TH_RST|TH_ACK|TH_URG)


	u_short	th_win;	/* window */
	u_short	th_sum;	/* checksum */
	u_short	th_urp;	/* urgent pointer */
};





UDP
struct udphdr 
{
	u_short	uh_sport;		/* source port */
	u_short	uh_dport;		/* destination port */
	short	uh_ulen;		/* udp length */
	u_short	uh_sum;	
		/* udp checksum */
};






ARP
typedef struct _ETHERNET_FRAME
{
    BYTE    DestinationAddress[6]; 
       BYTE    SourceAddress[6];    
      	WORD    FrameType;    // in host-order
} EHTERNET_FRAME, *PETHERNET_FRAME;


typedef struct _ARP_HEADER
{  
	WORD    HardType;      //硬件类型  
	WORD    ProtocolType;  //协议类型 
	BYTE    HardLength;    //硬件地址长度  
	BYTE    ProtocolLength; //协议地址长度    
	WORD    Opcode;        //操作类型      
	BYTE    SourceMAC[6];          
	BYTE    SourceIP[4];          
	BYTE    DestinationMAC[6];      
	BYTE    DestinationIP[4];    
} ARP_HEADER, *PARP_HEADER;


typedef struct _ARP
{    
	EHTERNET_FRAME EthernetFrame;    
	ARP_HEADER  ArpHeader;
}ARP, *PARP;









其他的可以看或文章最尾部的参考文章
数据包报头百度百科
http://baike.baidu.com/link?url=DuxdZVeorGksQX94G8UP19wx_iy-o504SjAhiQjZuRWSWNaZEVthpt6cm4L_z0FryXPqF4-YPtaN0UBbe_8Yeq


基于linux内核的网络防火墙开发

Linux核心网络堆栈中有一个全局变量 : 
struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS],该变量是一个二维数组,其中第一维用于指定协议族,第二维用于指定hook的类型(即5个HOOK点 )。注册一个Netfilter hook实际就是在由协议族和hook类型确定的链表中添加一个新的节点。 


在Linux防火墙开发中,有5个地方可以拦截





图很清楚的说明了在对应的位置能干什么


Filter:包过滤
Nat:地址转换
Mangle:修改包数据


规则链:
五个钩子函数(hook functions),也叫五个规则链。
1.PREROUTING (路由前)
2.INPUT (数据包流入口)
3.FORWARD (转发管卡)
4.OUTPUT(数据包出口)
5.POSTROUTING(路由后)
这是NetFilter规定的五个规则链,任何一个数据包,只要经过本机,必将经过这五个链中的其中一个链。  


5个HOOK点的定义:
NF_INET_PRE_ROUTING    在完整性校验之后,选路确定之前
NF_INET_LOCAL_IN        在选路确定之后,且数据包的目的是本地主机
NF_INET_FORWARD        目的地是其它主机地数据包
NF_INET_LOCAL_OUT     来自本机进程的数据包在其离开本地主机的过程中
NF_IP_POST_ROUTING    在数据包离开本地主机“上线”之前 
NF_INET_POST_ROUTING 同上


对包的处理结果:

NF_DROP        丢弃该数据包
NF_ACCEPT    保留该数据包
NF_STOLEN    忘掉该数据包
NF_QUEUE     将该数据包插入到用户空间
NF_REPEAT    再次调用该hook函数 

优先级:
enum nf_ip_hook_priorities {
        NF_IP_PRI_FIRST = INT_MIN,
        NF_IP_PRI_CONNTRACK_DEFRAG = -400,
        NF_IP_PRI_RAW = -300,
        NF_IP_PRI_SELINUX_FIRST = -225,
        NF_IP_PRI_CONNTRACK = -200,
        NF_IP_PRI_MANGLE = -150,
        NF_IP_PRI_NAT_DST = -100,
        NF_IP_PRI_FILTER = 0,
        NF_IP_PRI_SECURITY = 50,
        NF_IP_PRI_NAT_SRC = 100,
        NF_IP_PRI_SELINUX_LAST = 225,
        NF_IP_PRI_CONNTRACK_CONFIRM = INT_MAX,
        NF_IP_PRI_LAST = INT_MAX,
};

一般写NF_IP_PRI_FIRST啦~或+1 +2...



///开始编写防火墙//
在注册之前 我们需要填写一个结构

struct nf_hook_ops {
      struct list_head list;
      /* 此下的值由用户填充 */
      nf_hookfn *hook//回调函数;
      int pf;//协议 IPV4 还是ipV6
      int hooknum;//hook点
      /* Hook以升序的优先级排序 */
     int priority;
};


例子:
   
 struct nf_hook_ops   nfho;
    /* 填充我们的hook数据结构 */    
    nfho.hook = hook_func;  /* 处理函数 */    
    nfho.hooknum  = NF_INET_PRE_ROUTING;
    /* 使用IPv4的第一个hook */    
    nfho.pf       = PF_INET; 
    //优先级 /* 让我们的函数首先执行 */  
    nfho.priority = NF_IP_PRI_F
  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值