linux内核网络初始化,Linux内核--网络栈实现分析
本文分析基于内核Linux Kernel 1.2.13
以后的系列博文将深入分析Linux内核的网络栈实现原理,这里看到曹桂平博士的分析后,也决定选择Linux内核1.2.13版本进行分析。
原因如下:
1.功能和网络栈层次已经非常清晰
2.该版本与其后续版本的衔接性较好
3.复杂度相对新的内核版本较小,复杂度低,更容易把握网络内核的实质
4.该内核版本比较系统资料可以查询
下面开始零基础分析Linux内核网络部分的初始化过程。
经过系统加电后执行的bootsect.S,setup.S,head.S,可以参考以前分析的0.11内核。原理相同。
进行前期的准备工作后,系统跳转到init/main.c下的start_kernel函数执行。
网络栈的层次结构如下图:(注:该图片摘自《Linux内核网络栈源代码情景分析》)
start_kernel函数经过平台初始化,内存初始化,陷阱初始化,中断初始化,进程调度初始化,缓冲区初始化等,然后执行socket_init(),最后开中断执行init()。
内核的网络战初始化函数socket_init()函数的实现在net/socket.c中
下面是该函数的实现
voidsock_init(void)//网络栈初始化
{
inti;
printk("Swansea University Computer Society NET3.019\n");
/*
* Initialize all address (protocol) families.
*/
for(i = 0; i
/*
* Initialize the protocols module.
*/
proto_init();
#ifdef CONFIG_NET
/*
* Initialize the DEV module.
*/
dev_init();
/*
* And the bottom half handler
*/
bh_base[NET_BH].routine= net_bh;
enable_bh(NET_BH);
#endif
}其中的地址族协议初始化语句for (i = 0; i < NPROTO; ++i) pops[i] = NULL;
这里文件中定义的NPROTO为16
#define NPROTO16/* should be enough for now..*/
而pop[i]是如何定义的呢?
static struct proto_ops *pops[NPROTO];
proto_ops结构体是什么呢?该结构体的定义在include/linux/net.h中,该结构体是具体的操作函数集合,是联系BSD套接字和INET套接字的接口,可以把BSD套接字看做是INET套接字的抽象,结构示意图如下:
具体定义在net.h中
structproto_ops {
intfamily;
int(*create) (structsocket *sock,intprotocol);
int(*dup) (structsocket *newsock,structsocket *oldsock);
int(*release) (structsocket *sock,structsocket *peer);
int(*bind) (structsocket *sock,structsockaddr *umyaddr,
intsockaddr_len);
int(*connect) (structsocket *sock,structsockaddr *uservaddr,
intsockaddr_len,intflags);
int(*socketpair) (structsocket *sock1,structsocket *sock2);
int(*accept) (structsocket *sock,structsocket *newsock,
intflags);
int(*getname) (structsocket *sock,structsockaddr *uaddr,
int*usockaddr_len,intpeer);
int(*read) (structsocket *sock,char*ubuf,intsize,
intnonblock);
int(*write) (structsocket *sock,char*ubuf,intsize,
intnonblock);
int(*select) (structsocket *sock,intsel_type,
select_table *wait);
int(*ioctl) (structsocket *sock, unsignedintcmd,
unsignedlongarg);
int(*listen) (structsocket *sock,intlen);
int(*send) (structsocket *sock,void*buff,intlen,intnonblock,
unsigned flags);
int(*recv) (structsocket *sock,void*buff,intlen,intnonblock,
unsigned flags);
int(*sendto) (structsocket *sock,void*buff,intlen,intnonblock,
unsigned flags,structsockaddr *,intaddr_len);
int(*recvfrom) (structsocket *sock,void*buff,intlen,intnonblock,
unsigned flags,structsockaddr *,int*addr_len);
int(*shutdown) (structsocket *sock,intflags);
int(*setsockopt) (structsocket *sock,intlevel,intoptname,
char*optval,intoptlen);
int(*getsockopt) (structsocket *sock,intlevel,intoptname,
char*optval,int*optlen);
int(*fcntl) (structsocket *sock, unsignedintcmd,
unsignedlongarg);
};可以看到,这里实际上就是一系列操作的函数,有点类似于文件系统中的file_operations。通过参数传递socket完成操作。
接下来是proto_init()协议初始化。
voidproto_init(void)
{
externstructnet_proto protocols[];/* Network protocols 全局变量,定义在protocols.c中 */
structnet_proto *pro;
/* Kick all configured protocols. */
pro = protocols;
while(pro->name != NULL)
{
(*pro->init_func)(pro);
pro++;
}
/* We're all done... */
}全局的protocols定义如下:
structnet_proto protocols[] = {
#ifdef CONFIG_UNIX
{"UNIX", unix_proto_init },
#endif
#if defined(CONFIG_IPX)||defined(CONFIG_ATALK)
{"802.2", p8022_proto_init },
{"SNAP", snap_proto_init },
#endif
#ifdef CONFIG_AX25
{"AX.25", ax25_proto_init },
#endif
#ifdef CONFIG_INET
{"INET", inet_proto_init },
#endif
#ifdef CONFIG_IPX
{"IPX", ipx_proto_init },
#endif
#ifdef CONFIG_ATALK
{"DDP", atalk_proto_init },
#endif
{ NULL, NULL }
};而结构体net_proto的定义net.h中为
structnet_proto {
char*name;/* Protocol name */
void(*init_func)(structnet_proto *);/* Bootstrap */
};以后注重讨论标准的INET域
让我们回到proto_init()函数
接下来会执行inet_proto_init()函数,进行INET域协议的初始化。该函数的实现在net/inet/af_inet.c中
其中的
(void) sock_register(inet_proto_ops.family, &inet_proto_ops);
intsock_register(intfamily,structproto_ops *ops)
{
inti;
cli();//关中断
for(i = 0; i
{
if(pops[i] != NULL)
continue;//如果不空,则跳过
pops[i] = ops;//进行赋值
pops[i]->family = family;
sti();//开中断
return(i);//返回用于刚刚注册的协议向量号
}
sti();//出现异常,也要开中断
return(-ENOMEM);
}
参数中的inet_proto_ops定义如下:
staticstructproto_ops inet_proto_ops = {
AF_INET,
inet_create,
inet_dup,
inet_release,
inet_bind,
inet_connect,
inet_socketpair,
inet_accept,
inet_getname,
inet_read,
inet_write,
inet_select,
inet_ioctl,
inet_listen,
inet_send,
inet_recv,
inet_sendto,
inet_recvfrom,
inet_shutdown,
inet_setsockopt,
inet_getsockopt,
inet_fcntl,
};其中AF_INET宏定义为2,即INET协议族号为2,后面是函数指针,INET域的操作函数。
然后
printk("IP Protocols: ");
for(p = inet_protocol_base; p != NULL;)//将inet_protocol_base指向的一个inet_protocol结构体加入数组inet_protos中
{
structinet_protocol *tmp = (structinet_protocol *) p->next;
inet_add_protocol(p);
printk("%s%s",p->name,tmp?", ":"\n");
p = tmp;
}
/*
* Set the ARP module up
*/
arp_init();//对地址解析层进行初始化
/*
* Set the IP module up
*/
ip_init();//对IP层进行初始化协议初始化完成后再执行dev_init()设备的初始化。
这是大体的一个初始化流程,讨论的不是很详细,后续会进行Linux内核网络栈源代码的详细分析。
linux内核网络初始化,Linux内核--网络栈实现分析相关推荐
- linux恢复硬盘初始状态,初始化Linux数据盘(fdisk)
初始化Linux数据盘(fdisk)TkV南京数据恢复-西数科技: 硬盘/手机/SSD数据恢复专家. 025-83608636 18913825606 查看PDFTkV南京数据恢复-西数科技: 硬盘/ ...
- linux 字符串数组初始化,Linux命令行 – 数组
在上一章中,我们查看了 shell 怎样操作字符串和数字的.目前我们所见到的数据类型在计算机科学圈里被 称为标量变量:也就是说,只能包含一个值的变量. 在本章中,我们将看看另一种数据结构叫做数组,数组 ...
- Linux内核--网络栈实现分析(二)--数据包的传递过程--转
转载地址http://blog.csdn.net/yming0221/article/details/7492423 作者:闫明 本文分析基于Linux Kernel 1.2.13 注:标题中的&qu ...
- linux内核网络协议栈--linux bridge(十九)
1 . 前言 本文是参考附录上的资料整理而成,以帮助读者更好的理解kernel中brdige 模块代码. 2. 网桥的原理 2.1 桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口" ...
- linux内核网络协议栈--linux网络设备理解(十三)
网络层次 linux网络设备驱动与字符设备和块设备有很大的不同. 字符设备和块设备对应/dev下的一个设备文件.而网络设备不存在这样的设备文件.网络设备使用套接字socket访问,虽然也使用read, ...
- 浅析linux内核网络协议栈--linux bridge
1 . 前言 本文是参考附录上的资料整理而成,以帮助读者更好的理解kernel中brdige 模块代码. 2. 网桥的原理 2.1 桥接的概念 简单来说,桥接就是把一台机器上的若干个网络接口" ...
- 调试linux内核前的多虚拟机网络配置(图文教程)
需求: Linux源代码的分析中重要的一部分,是网络管理内核.最基本的内核调试平是两台联网的机器.内核调试平台由开发机和目标机两台机器构成,并要为他们配置网络.内核调试平台分为硬件物理结构和软件虚拟结 ...
- linux 网络瘫痪,Linux内核发现TCP漏洞,小流量也能DoS瘫痪设备
卡内基梅隆大学的 CERT/CC 发出一个 Linux 内核漏洞警告,称 Linux 4.9 内核或者更高版本中出现一个 TCP 漏洞,该漏洞可使攻击者通过极小流量对系统发动 DoS (Denial- ...
- 【树莓派学习笔记】树莓派4B上运行uboot并从网络启动linux内核(上)
[树莓派学习笔记]树莓派4B上运行uboot并从网络启动linux内核(上) 文章目录 [树莓派学习笔记]树莓派4B上运行uboot并从网络启动linux内核(上) 前言 1. 硬件需求与软件版本汇总 ...
最新文章
- 计算机房装修对门的要求,防火门尺寸要求有哪些 防火门尺寸规范
- 如何把class里的vector结构体memcpy出来_面试官:请说出线程安全的 ArrayList 有哪些,除了Vector...
- structs2文件下载
- JSON 解析的两种方法
- C++ Primer 有感(重载操作符)
- mysql课程表学时_Mysql 巩固提升 (学生表_课程表_成绩表_教师表)
- Java7和8在虚拟机上的差异:Perm Generation vs. Metaspace
- python链接MySQL数据库
- Mozilla推荐的CSS属性书写顺序及命名规则
- 使用STL标准模板库实现的个人通讯录
- awk命令详解+示例
- ba无标度网络python_python绘制BA无标度网络示例代码
- 笔记本电脑Haswell黑苹果opencore睡眠实战
- HTML+CSS网页设计期末课程大作业 【茶叶文化网站设计题材】web前端开发技术 web课程设计 网页规划与设计
- 你和语言模型,谁的填空能力更强?
- 对100层楼两个玻璃球测试问题的理解
- 【Android】自定义View的位置参数
- abstract(抽象)的定义和使用
- queue和deque的区别
- 获取微信小程序的昵称和手机号