完成MY_PF_INET域的初始化
来源:互联网 发布:sjf算法例题 编辑:程序博客网 时间:2024/05/21 22:21
前面两篇中,我们已经做了两步关于family初始化的工作:创建并注册了family中的三种协议:TCP, UDP和RAW;向net_families数组注册我们的MY_PF_INET域。
接下来,我们描述其余的要做的初始化工作,其实很多工作我们并没有真正完成,大多数只是留下一个空的函数,先使它们具备一个框架,留待日后完善。
第三步,我们添加一些基本的协议,分别是TCP, UDP, ICMP, IGMP。这在概念上可能点混乱,暂且不管,先关注其实现。有一个数组:
struct net_protocol *inet_protos[MAX_INET_PROTOS];
#define MAX_INET_PROTOS 256
它包含了当前系统中所有已添加的协议,结构struct net_protocol用于注册协议,其内容很简单:
struct net_protocol {
int (*handler)(struct sk_buff *skb);
void (*err_handler) (struct sk_buff * skb, u32 info);
int no_policy;
};
现在碰到一个问题,即TCP, UDP, ICMP, IGMP协议已经由真正的PF_INET域注册到数组中了,我们这个假冒的MY_PF_INET域再要使用数组中的这些项,肯定会失败,所以,我们继续寻找空项:
#define MY_IPPROTO_ICMP (IPPROTO_ICMP + 60)
#define MY_IPPROTO_IGMP (IPPROTO_IGMP + 60)
#define MY_IPPROTO_TCP (IPPROTO_TCP + 60)
#define MY_IPPROTO_UDP (IPPROTO_UDP + 60)
必须要说明的是,这是一个很危险的动作,因为我们不能保证IPPROTO_ICMP+60是未使用的。
第四步,初始化inetsw数组,inetsw的每一项是一个链表,链表中所有的项都是一个struct inet_protosw,并且同一个链表中的结构体具有相同的套接字类型。在MY_PF_INET域中,我们有三个inet_protosw,分别是: static struct inet_protosw myinetsw_array[] =
{
{
.type = SOCK_STREAM,
.protocol = MY_IPPROTO_TCP,
.prot = &mytcp_prot,
.ops = &myinet_stream_ops,
.capability = -1,
.no_check = 0,
.flags = INET_PROTOSW_PERMANENT,
},
{
.type = SOCK_DGRAM,
.protocol = MY_IPPROTO_UDP,
.prot = &myudp_prot,
.ops = &myinet_dgram_ops,
.capability = -1,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_PERMANENT,
},
{
.type = SOCK_RAW,
.protocol = IPPROTO_IP, /* wild card */
.prot = &myraw_prot,
.ops = &myinet_sockraw_ops,
.capability = CAP_NET_RAW,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
}
}
它们分别放入inetsw中,各占一项,不会形成链表。这里容易混淆的是prot跟ops,它们提供相似的接口。但它们在层次上是有所差异的,比如 SOCK_STREAM中,prot是tcp协议相关的操作,而ops是inet域中流协议相关的操作。
第五步,各个模块的初始化,包括tcp, ip, ip_fragment, arp等等,我们暂时全部留空,不追究其细节。
第六步,向网络栈添加一个协议处理器。inet域的协议处理结构如下:
static struct packet_type myip_packet_type = {
.type = __constant_htons(ETH_P_IP),
.func = myip_rcv,
};
该结构最终被加入static struct list_head ptype_base[16],从而完成添加工作。
接下来,我们描述其余的要做的初始化工作,其实很多工作我们并没有真正完成,大多数只是留下一个空的函数,先使它们具备一个框架,留待日后完善。
第三步,我们添加一些基本的协议,分别是TCP, UDP, ICMP, IGMP。这在概念上可能点混乱,暂且不管,先关注其实现。有一个数组:
struct net_protocol *inet_protos[MAX_INET_PROTOS];
#define MAX_INET_PROTOS 256
它包含了当前系统中所有已添加的协议,结构struct net_protocol用于注册协议,其内容很简单:
struct net_protocol {
int (*handler)(struct sk_buff *skb);
void (*err_handler) (struct sk_buff * skb, u32 info);
int no_policy;
};
现在碰到一个问题,即TCP, UDP, ICMP, IGMP协议已经由真正的PF_INET域注册到数组中了,我们这个假冒的MY_PF_INET域再要使用数组中的这些项,肯定会失败,所以,我们继续寻找空项:
#define MY_IPPROTO_ICMP (IPPROTO_ICMP + 60)
#define MY_IPPROTO_IGMP (IPPROTO_IGMP + 60)
#define MY_IPPROTO_TCP (IPPROTO_TCP + 60)
#define MY_IPPROTO_UDP (IPPROTO_UDP + 60)
必须要说明的是,这是一个很危险的动作,因为我们不能保证IPPROTO_ICMP+60是未使用的。
第四步,初始化inetsw数组,inetsw的每一项是一个链表,链表中所有的项都是一个struct inet_protosw,并且同一个链表中的结构体具有相同的套接字类型。在MY_PF_INET域中,我们有三个inet_protosw,分别是: static struct inet_protosw myinetsw_array[] =
{
{
.type = SOCK_STREAM,
.protocol = MY_IPPROTO_TCP,
.prot = &mytcp_prot,
.ops = &myinet_stream_ops,
.capability = -1,
.no_check = 0,
.flags = INET_PROTOSW_PERMANENT,
},
{
.type = SOCK_DGRAM,
.protocol = MY_IPPROTO_UDP,
.prot = &myudp_prot,
.ops = &myinet_dgram_ops,
.capability = -1,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_PERMANENT,
},
{
.type = SOCK_RAW,
.protocol = IPPROTO_IP, /* wild card */
.prot = &myraw_prot,
.ops = &myinet_sockraw_ops,
.capability = CAP_NET_RAW,
.no_check = UDP_CSUM_DEFAULT,
.flags = INET_PROTOSW_REUSE,
}
}
它们分别放入inetsw中,各占一项,不会形成链表。这里容易混淆的是prot跟ops,它们提供相似的接口。但它们在层次上是有所差异的,比如 SOCK_STREAM中,prot是tcp协议相关的操作,而ops是inet域中流协议相关的操作。
第五步,各个模块的初始化,包括tcp, ip, ip_fragment, arp等等,我们暂时全部留空,不追究其细节。
第六步,向网络栈添加一个协议处理器。inet域的协议处理结构如下:
static struct packet_type myip_packet_type = {
.type = __constant_htons(ETH_P_IP),
.func = myip_rcv,
};
该结构最终被加入static struct list_head ptype_base[16],从而完成添加工作。
- 完成MY_PF_INET域的初始化
- SparkContext创建初始化完成的主要工作
- Java 多叉树的实现,完成树的初始化和遍历
- Java 多叉树的实现,完成树的初始化和遍历
- Java 多叉树的实现,完成树的初始化和遍历
- Objective-C的数组的初始化完成后再使用
- 通过Struts Plugin完成Hibernate的SessionFactory初始化
- 两行代码完成alfresco的环境初始化
- 在函数中完成结构体的初始化
- 初始化iframe数据,判断iframe加载是否完成的问题
- 使用OGG完成Tandem到DB2 UDB的初始化迁移
- 虚拟机安装完成以后的初始化操作笔记
- CentOS 7安装完成后初始化的方法
- java多叉树的实现类,完成树的初始化和遍历
- extjs grid中columns用到的store未初始化完成的解决办法
- 嵌入式中main函数起来之前,startup要完成的初始化过程
- 创建一个数组, 实现初始化数组、清空数组、完成数组元素的逆置。
- 关于MySql安装完成,默认链接的初始化密码修改[mac版MySQL初始密码]
- Linux netfilter源码分析(6)
- a^b%c
- Linux netfilter源码分析(7)
- 在一测试环境下的RAC出错解决
- MongoDB学习 (六):查询
- 完成MY_PF_INET域的初始化
- erlang gen_tcp 解析 http协议
- Linux top 命令详解
- scons构建入门
- APACHE配置多个站点 -多站点配置
- (转载)C/C++ 点和箭头操作符的区别
- Centos6.3(32bit)网络配置校园锐捷
- 【不为人知的三大暴力破解软件】
- Linux curl 详解