packet_type结构
struct packet_type {
unsigned short type; //协议类型:ETH_P_IP, ETH_P_ARP……
struct net_device *dev;
int (*func) (struct sk_buff *, struct net_device *, struct packet_type *); //回调函数指针,协议处理机(protocol handler) www.it165.net
void *af_packet_priv;
struct list_head *list;
};
注册协议处理机
主要调用dev_add_packet函数来实现。本例示范如何注册IP协议处理机ip_rcv.
static struct packet_type ip_packet_type =
{
.type = _ _constant_htons(ETH_P_IP),
.func = ip_rcv,
}
int ip_rcv(struct sk_buff *buf, struct net_device *nd, struct packet_type *pt)
{
}
void _ _init ip_init(void)
{
dev_add_pack(&ip_packet_type);
...
}
协议定义
ETH_P_IP 0x0800 ip_rcv
ETH_P_X25 0x0805 X25_lap_receive_frame
ETH_P_ARP 0x0806 arp_rcv
ETH_P_BPQ 0x08FF bpq_rcv
ETH_P_DNA_RT 0x6003 dn_route_rcv
ETH_P_RARP 0x8035 ic_rarp_recv
ETH_P_8021Q 0x8100 vlan_skb_rcv
ETH_P_IPX 0x8137 ipx_rcv
ETH_P_IPV6 0x86DD ipv6_rcv
ETH_P_PPP_DISC
ETH_P_PPP_SES 0x8863
0x8864 pppoe_disc_rcvpppoe_rcv
网络路由表及过滤器(Iptables/Netfilter)
Netfilter: 在协议栈不同点的一系列钩子
Iptables: 用户空间控制工具,可以添加/删除/修改Netfilter钩子和规则
内核模块可以在以上任何一点(1~5)注册钩子来监听数据包。
表类型是*filter *nat *mangle。
可以注册以下动作:
Netfilter钩子
本例示范如何在ip_rcv函数中注册钩子ip_rcv_finish。
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \
NF_HOOK_THRESH(pf,hook, skb, indev, outdev, okfn, INT_MIN)
#define NF_HOOK_THRESH(pf, hook, &(skb), indev, outdev, okfn, thresh)
({int __ret;
if ((__ret = nf_hook_thresh(pf, hook, &(skb), indev, outdev, okfn, INT_MIN,
cond))==1),
__ret = okfn(skb);
__ret;})
static inline nf_hook_thresh(int pf, unsigned int hook, struct sk_buff **pskb,
struct net_device *indev,
struct net_device *outdev,
int (*okfn)(struct sk_buff *),
int thresh,
int cond)
{
nf_hook_slow(....);
}
ip_rcv_finish(...)
{
}
ip_rcv(…)
{
…
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish)
…
}
下面是具体处理流程:
链路层处理
桥接
桥接处理过程如下:
Ebtables
Ebtables: 可以在桥接内核模块不同点上注册一系列钩子。原型如下:
NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, br_handle_frame_finish)