加入收藏 | 设为首页 | 会员中心 | 我要投稿 常州站长网 (https://www.0519zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核实践 - 如何添加网络协议[二]:实现

发布时间:2016-09-28 18:42:11 所属栏目:Linux 来源:站长网
导读:副标题#e# 内核版本:2.6.34 实现思路: 报文在网络协议栈中的流动,对于接收来讲,是 对报文的脱壳的过程,由于报文是已知的输入,只要逐个解析协议号;对于发送来讲,是各层发送函数的嵌套调用,由于没有已 知的输入,只能按事先设计好的协议进行层层构造
副标题[/!--empirenews.page--]

内核版本:2.6.34

实现思路:

报文在网络协议栈中的流动,对于接收来讲,是 对报文的脱壳的过程,由于报文是已知的输入,只要逐个解析协议号;对于发送来讲,是各层发送函数的嵌套调用,由于没有已 知的输入,只能按事先设计好的协议进行层层构造。但无论报文怎样的流动,核心是报文所在设备(skb->dev)的变化,相当 于各层之间传递的交接棒。

按照上述思路,brcm协议接收的处理作为模块brcm_packet_type加入 到ptype_base中就可以了;brcm协议发送的处理则复杂一点,发送的嵌套调用完全是依赖于设备来推动的,因此要有一种新创建 的设备X,插入到vlan设备和网卡设备之间。

因此,至少要有brcm_packet_type来加入ptype_base和register_brcm_dev() 来向系统注册设备X。进一步考虑,设备X在全局量init_net中有存储,但我们还需要知道设备X与vlan设备以及网卡设备是何种 组织关系,所以在这里设计了brcm_group_hash来存储这种关系。为了对设备感兴趣的事件作出响应,添加自己的notifier到 netdev_chain中。另外,为了用户空间具有一定控制能力(如创建、删除),还需要添加brcm相关的ioctl调用。为了让它看起来 更完整,一种新的设备在proc中也应有对应项,用来调试和查看设备。

从最简单开始

要 让网络协议栈能够接收一种新协议是很简单的,由于已经有报文作为输入,我们要做的仅仅是编写好brcm_packet_type,然后在 注册模块时只用做一件事:dev_add_pack。

static int __init 

brcm_proto_init(void)
{
 dev_add_pack(&brcm_packet_type);     
}

static struct packet_type brcm_packet_type __read_mostly = {     
 .type = cpu_to_be16(ETH_P_BRCM),     
 .func = brcm_skb_recv, /* BRCM receive method */ 
};     

int brcm_skb_recv(struct sk_buff *skb, struct net_device *dev,     
    struct packet_type *ptype, struct net_device *orig_dev)     
{
 struct brcm_hdr *bhdr;     
 struct brcm_rx_stats *rx_stats;     

 skb = skb_share_check(skb, GFP_ATOMIC);     
 if(!skb)     
  goto err_free;     
 bhdr = (struct brcm_hdr *)skb->data;     

 rcu_read_lock();     
 skb_pull_rcsum(skb, BRCM_HLEN);     
 // set protocol     
 skb->protocol = bhdr->brcm_encapsulated_proto;     
 // reorder skb     
 skb = brcm_check_reorder_header(skb);     
 if (!skb)      
  goto err_unlock;     

 netif_rx(skb);     
 rcu_read_unlock();     
 return NET_RX_SUCCESS;     

err_unlock:     
 rcu_read_unlock();     

err_free:     
 kfree_skb(skb);     
 return NET_RX_DROP;     
}

注册这个模块后,协议栈就能正常接收带brcm报头的报文的,代码中ETH_P_BRCM是brcm的协议号,BRCM_HLEN是brcm 的报头长度。正是由于有报文作为输入,接收变得十分简单。

但这仅仅是能接收而已,发送的报 文还是不带brcm报头的,而且接收的这段代码也很粗略,没有变更skb的设备,没有记录流量,没有对brcm报头作有意义的处理 ,下面逐一进行添加。

(编辑:常州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读