ImageVerifierCode 换一换
格式:DOCX , 页数:7 ,大小:16.68KB ,
资源ID:25396170      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/25396170.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ptypebase和ptypeall理解netidreceiveskb函数注解.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ptypebase和ptypeall理解netidreceiveskb函数注解.docx

1、ptypebase和ptypeall理解netidreceiveskb函数注解ptype_base和ptype_all理解,netid_receive_skb()函数注解 在数据包接收过程的那篇笔记中可以知道,在数据包的处理函数netif_receive_skb中,会先看ptype_all中是否有注册的协议,如果有,则调用相应的处理函数,然后再到ptype_base中,找到合适的协议,将skb发送到相关协议的处理函数.比如ip协议(ip_rcv)或者arp(arp_rcv)等等.此篇笔记讲的是有关ptype_all和ptype_base的相关知识点.ptype_base和ptype_all在内

2、核中存储的情况如下图:可以看到,ptype_base为一个hash表,而ptype_all为一个双向链表.每一个里面注册的协议都用一个struct packet_type表示.struct packet_type unsigned short type; /*协议类型*/struct net_device *dev; int (*func) (struct sk_buff *, struct net_device *,struct packet_type *);void *data; /* Private to the packet type */struct packet_type *nex

3、t;其中需要注意的是dev参数,此参数表明了协议只处理来自dev指向device的数据,当dev=NULL时,表示该协议处理来自所有device的数据.这样,当注册自己的协议时,就可以指定自己想要监听或者接收的device.其中注册和注销协议的函数为:dev_add_pack(.)和dev_remove_pack(.)这两个函数很简单,分别如下:void dev_add_pack(struct packet_type *pt)int hash;br_write_lock_bh(BR_NETPROTO_LOCK);#ifdef CONFIG_NET_FASTROUTE/* Hack to det

4、ect packet socket */if (pt-data) & (int)(pt-data)!=1) netdev_fastroute_obstacles+;dev_clear_fastroute(pt-dev);#endifif (pt-type = htons(ETH_P_ALL) netdev_nit+;pt-next=ptype_all;ptype_all=pt; else hash=ntohs(pt-type)&15;pt-next = ptype_basehash;ptype_basehash = pt;br_write_unlock_bh(BR_NETPROTO_LOCK)

5、;此函数判断协议类型,然后加到ptype_base或者ptype_all中.void dev_remove_pack(struct packet_type *pt)struct packet_type *pt1;br_write_lock_bh(BR_NETPROTO_LOCK);if (pt-type = htons(ETH_P_ALL) netdev_nit-;pt1=&ptype_all; else pt1=&ptype_basentohs(pt-type)&15;for (; (*pt1) != NULL; pt1 = &(*pt1)-next) if (pt = (*pt1) *pt

6、1 = pt-next;#ifdef CONFIG_NET_FASTROUTEif (pt-data)netdev_fastroute_obstacles-;#endifbr_write_unlock_bh(BR_NETPROTO_LOCK);return;br_write_unlock_bh(BR_NETPROTO_LOCK);printk(KERN_WARNING dev_remove_pack: %p not found.n, pt);此函数也很简单,只是把协议从相关的链表中移除.下面以ip协议为例子来看看相关的实现:ip协议结构体的定义如下:static struct packet_t

7、ype ip_packet_type =_constant_htons(ETH_P_IP),NULL, /* All devices */ip_rcv,(void*)1,NULL,;当ipv4协议栈初始化时,会调用ip_init.之后,所有协议类型为ETH_P_IP的包都会交由ip_rcv处理.代码如下:void _init ip_init(void)dev_add_pack(&ip_packet_type);ip_rt_init();inet_initpeers();#ifdef CONFIG_IP_MULTICASTproc_net_create(igmp, 0, ip_mc_procin

8、fo);#endif这样在系统启动之后,ip协议便被注册到ptype_base链表中,相应的处理函数为ip_rcv.arp协议和其他类型的协议(在ptype_base或者ptype_all中的)的执行过程同理.本人初学网络,水平很菜,如有错误,希望看到的朋友们及时指出,不胜感激.ps1:记得刚来实验室的时候,做的截包模块的第一种方法是用的netfilter,第二种方法主要就是用到的这块知识.现在总结起来,觉得还算简单,当初却用了很长时间,想想,真是难者不会,会者不难啊.今天看书的时候,好像又发现了另外一种方法可以实现我的要求,记录在ps2上.ps2:在数据链路层截包的另一种方法:用PF_PAC

9、KET socket type.linux可以用此类型套节字直接从链路层截获或者注入数据.发送数据时,直接发送到dev_queue_xmit.而接收函数时,可以在数据包通过路由之前截获到.如tcpdump和Ethereal都是用到了此套接字.那么总结起来可以看出,截获数据包至少可以有三种方法实现,第一种的netfilter是在协议栈中截获数据包,而利用ptype_all或者ptype_base和后面这种套节字的方法是在链路层截获数据包./当网络设备收到网络数据包时,最终会在软件中断环境里调用此函数 /当网络设备收到网络数据包时,最终会在软件中断环境里调用此函数 cpp view plainco

10、pyprint?int netif_receive_skb(struct sk_buff *skb) /ptype_all 用于sniffer这样的程序 / 发送一份拷贝给这些注册的sniffer程序 list_for_each_entry_rcu(ptype, &ptype_all, list) if (!ptype-dev | ptype-dev = skb-dev) if (pt_prev) ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = ptype; / 内核编译开Bridge_config,则将该数据包让网桥函数来处理,否则h

11、andle_bridge定义为空操作, / 返回skb,让协议栈来处理上层协议。 skb = handle_bridge(skb, &pt_prev, &ret, orig_dev); if (!skb) goto out; skb = handle_macvlan(skb, &pt_prev, &ret, orig_dev); if (!skb) goto out; /对该数据包转达到其他L3协议的处理函数 type = skb-protocol; list_for_each_entry_rcu(ptype, &ptype_basentohs(type)&15, list) if (ptyp

12、e-type = type & (!ptype-dev | ptype-dev = skb-dev) if (pt_prev) ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = ptype; int netif_receive_skb(struct sk_buff *skb) /ptype_all 用于sniffer这样的程序 / 发送一份拷贝给这些注册的sniffer程序 list_for_each_entry_rcu(ptype, &ptype_all, list) if (!ptype-dev | ptype-dev = skb-d

13、ev) if (pt_prev) ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = ptype; / 内核编译开Bridge_config,则将该数据包让网桥函数来处理,否则handle_bridge定义为空操作, / 返回skb,让协议栈来处理上层协议。 skb = handle_bridge(skb, &pt_prev, &ret, orig_dev); if (!skb) goto out; skb = handle_macvlan(skb, &pt_prev, &ret, orig_dev); if (!skb) goto out

14、; /对该数据包转达到其他L3协议的处理函数 type = skb-protocol; list_for_each_entry_rcu(ptype, &ptype_basentohs(type)&15, list) if (ptype-type = type & (!ptype-dev | ptype-dev = skb-dev) if (pt_prev) ret = deliver_skb(skb, pt_prev, orig_dev); pt_prev = ptype; netif_receive_skb()的主要作用体现在两个遍历链表的操作中,其中之一为遍历ptype_all 链,这些为注册到内核的一些 sniffer,将上传给这些sniffer,另一个就是遍历 ptype_base,这个就是具体的协议类型。当 eth1 接收到一个IP数据包时,它首先分别发送一份副本给每个 ptype_all 链表中的 packet_type,它们都由 package_rcv 处理,然后再根据HASH 值,在遍历另一个HASH 表时,发送一份给类型为 ETH_P_IP 的类型,它由 ip_rcv处理。如果这个链中还注册有其它 IP层的协议,它也会同时发送一个副本给它。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1