free BSD协议栈代码
free BSD协议栈源码分析----domain和protosw
- 写在开头
- domaininit初始化
- protosw结构定义
- inetsw --internet的protosw结构
写在开头
最近在学习freeBSD4.4 协议栈的代码,也就是TCP/IP详解中配套使用的协议栈版本,开这篇博客,也是对自己学习过程的一个输出总结。
domaininit初始化
整个tcp/ip协议栈的初始化是在domaininit函数内,每种协议族都已一个domain结构,如unix域协议,tcp/ip协议等。
tcp/ip协议栈的一些信息是在inetdomain结构中声明:
先看下domain结构体:
struct domain {int dom_family; /* AF_xxx */ :域类型,一般是AF开头,如AF_INETchar *dom_name;//域名称,如 internetvoid (*dom_init) /* 域初始化函数 */__P((void));int (*dom_externalize) /* externalize access rights */__P((struct mbuf *));int (*dom_dispose) /* dispose of internalized rights */__P((struct mbuf *));struct protosw *dom_protosw, *dom_protoswNPROTOSW;//具体的域协议信息,域协议结构体的结尾struct domain *dom_next;/*用来连接下一个domain结构*/int (*dom_rtattach) /* initialize routing table */__P((void **, int));int dom_rtoffset; /* an arg to rtattach, in bits */int dom_maxrtkey; /* for routing layer */
};
domaininit初始化(部分次要代码已略去):
domaininit()
{register struct domain *dp;register struct protosw *pr;ADDDOMAIN(unix);//将unixdomain挂载到domains上ADDDOMAIN(route);//将routedomain挂载到domains上ADDDOMAIN(inet);//将inetdomain挂载到domains上,也就是tcp/ip协议的domain结构/*这里开始调用相应的domain结构中的初始化接口*/for (dp = domains; dp; dp = dp->dom_next) {if (dp->dom_init)(*dp->dom_init)();for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)/*这里开始调用inetsw中的协议初始化接口*/if (pr->pr_init)(*pr->pr_init)();}if (max_linkhdr < 16) /* 链路层首部长度不能小于16 */max_linkhdr = 16;max_hdr = max_linkhdr + max_protohdr;max_datalen = MHLEN - max_hdr;timeout(pffasttimo, (void *)0, 1);//启动定时器,调用protosw中的pffasttimotimeout(pfslowtimo, (void *)0, 1);//启动定时器,调用protosw中的pr_slowtimo
}
/*ADDDOMAIN这个宏的作用,就是把每个domain挂载到domains指针上,利用dom_next将所有domain结构连接起来形成一个链表结构,最后整个domains指向这个链表的第一个成员*/
#define ADDDOMAIN(x) { \extern struct domain __CONCAT(x,domain); \__CONCAT(x,domain.dom_next) = domains; \domains = &__CONCAT(x,domain); \
}
protosw结构定义
每一种协议族都有相应的protosw结构,
struct protosw {short pr_type; /* socket的类型*/struct domain *pr_domain; /* domain protocol a member of */short pr_protocol; /* protocol number */short pr_flags; /* see below */
/* protocol-protocol hooks */void (*pr_input)(); /* input to protocol (from below) */int (*pr_output)(); /* output to protocol (from above) */void (*pr_ctlinput)(); /* control input (from below) */int (*pr_ctloutput)(); /* control output (from above) */
/* user-protocol hook */int (*pr_usrreq)(); /* user request: see list below */
/* utility hooks */void (*pr_init)(); /* initialization hook */void (*pr_fasttimo)(); /* fast timeout (200ms) */void (*pr_slowtimo)(); /* slow timeout (500ms) */void (*pr_drain)(); /* flush any excess space possible */int (*pr_sysctl)(); /* sysctl for protocol */
};
inetsw --internet的protosw结构
struct protosw inetsw[] = {
{ 0, &inetdomain, 0, 0,0, ip_output, 0, 0,0,ip_init, 0, ip_slowtimo, ip_drain, ip_sysctl
},
{ SOCK_DGRAM, &inetdomain, IPPROTO_UDP, PR_ATOMIC|PR_ADDR,udp_input, 0, udp_ctlinput, ip_ctloutput,udp_usrreq,udp_init, 0, 0, 0, udp_sysctl
},
{ SOCK_STREAM, &inetdomain, IPPROTO_TCP, PR_CONNREQUIRED|PR_WANTRCVD,tcp_input, 0, tcp_ctlinput, tcp_ctloutput,tcp_usrreq,tcp_init, tcp_fasttimo, tcp_slowtimo, tcp_drain,
},
{ SOCK_RAW, &inetdomain, IPPROTO_RAW, PR_ATOMIC|PR_ADDR,rip_input, rip_output, 0, rip_ctloutput,rip_usrreq,0, 0, 0, 0,
},
{ SOCK_RAW, &inetdomain, IPPROTO_ICMP, PR_ATOMIC|PR_ADDR,icmp_input, rip_output, 0, rip_ctloutput,rip_usrreq,0, 0, 0, 0, icmp_sysctl
},
{ SOCK_RAW, &inetdomain, IPPROTO_IGMP, PR_ATOMIC|PR_ADDR,igmp_input, rip_output, 0, rip_ctloutput,rip_usrreq,igmp_init, igmp_fasttimo, 0, 0,
},
#ifdef TPIP
{ SOCK_SEQPACKET,&inetdomain, IPPROTO_TP, PR_CONNREQUIRED|PR_WANTRCVD,tpip_input, 0, tpip_ctlinput, tp_ctloutput,tp_usrreq,tp_init, 0, tp_slowtimo, tp_drain,
},
#endif
/* EON (ISO CLNL over IP) */
#ifdef EON
{ SOCK_RAW, &inetdomain, IPPROTO_EON, 0,eoninput, 0, eonctlinput, 0,0,eonprotoinit, 0, 0, 0,
},
#endif
#ifdef NSIP
{ SOCK_RAW, &inetdomain, IPPROTO_IDP, PR_ATOMIC|PR_ADDR,idpip_input, rip_output, nsip_ctlinput, 0,rip_usrreq,0, 0, 0, 0,
},
#endif/* raw wildcard */
{ SOCK_RAW, &inetdomain, 0, PR_ATOMIC|PR_ADDR,rip_input, rip_output, 0, rip_ctloutput,rip_usrreq,rip_init, 0, 0, 0,
},
};
inetsw数组中共定义了10个成员,分别对应每种协议,如TCP,UDP,IP等,在domaininit初始化中,会分别调用每个协议的pr_init接口初始化协议。
free BSD协议栈代码相关推荐
- [置顶] Linux协议栈代码阅读笔记(一)
Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...
- linux 协议栈 位置,[置顶] Linux协议栈代码阅读笔记(一)
Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...
- Netty 私有协议栈 代码实现
私有协议介绍 通信协议从广义上区分,可以分为共有协议和私有协议.由于私有协议的灵活性,它往往会在某个公司或者组织内部使用,按需定制,也因为如此,升级起来会非常方便,灵活性好. Netty私有协议栈功能 ...
- 【转】TI蓝牙BLE 协议栈代码学习
BLE就是低功率蓝牙.要着重了解两种设备: dual-mode双模设备:简单说就是向下兼容. single-mode单模设备:仅仅支持BLE. 关于开发主要讲的是单模设备,它可以只靠纽扣电池即可持续工 ...
- 开源双模蓝牙协议栈 代码结构介绍
零. 概述 本文章主要讲下双模蓝牙协议栈的代码结构以及常用的一些配置选项 一. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产 ...
- 基于NXP的蓝牙BLE协议栈代码分析
重要概念点总结 1.profile 规范.包含有service服务,如电量. 2.service,每一个服务可能包含一个或多个特征值. 3.characteristic 特征值.通信载体,电量为20% ...
- EtherCAT从站协议栈代码笔记之cia402appl.c
原文:https://nobuta.blog.csdn.net/article/details/82425552?utm_medium=distribute.pc_relevant.none-task ...
- EtherCAT从站协议栈代码笔记之ecat_def.h
ecat_def.h 1.Slave Sample Code Configuration Defines // 对各种支持的硬件的条件编译选项,当移植到某一特定硬件平台时,可以将没有用到的注释掉. ...
- SOEM协议栈代码研读笔记(二)
熟悉伺服电机控制的朋友大概都知道,一般伺服电机控制系统,无非就是电机<->驱动器<->控制器<->用户程序.EtherCAT master用在这里大体上相当于控制器 ...
最新文章
- javascript的匿名函数
- 给别人电脑永远设置个别人删不掉的管理员用户
- iOS实现传递不定长的多个参数
- Selenium之XPATH定位(第二篇)
- How to Analyze Java Thread Dumps--reference
- Java黑皮书课后题第8章:**8.17(金融风暴)银行会互相借款……银行的总资产是它当时的余款减去它欠其他银行的贷款。如果一个银行的总资产在某个限以下,那么这个银行是不安全的。编写程序,找出所有不安
- 使用ganglia监控hadoop及hbase集群
- phpmailer发送邮件
- Golang 垃圾回收剖析
- failed to allocate 192.19M (201523200 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY: out of memory
- 如何快速准备高质量的AI数据?
- java怎么判断mysql中是否存在我们查找的索引_10张图告诉你,MySQL 是如何查找数据的?...
- js容易犯错的知识点
- 搜狗输入法彻底杜绝广告以及弹窗的几种办法
- Excel答粉丝问:折线图如何添加参考线?​
- Nodejs爬虫自动爬取百度图片
- 读书笔记11 《蔡康永的说话之道2》 蔡康永
- 用记事本编辑注册表文件
- cad应用技巧:图层特性管理器
- Revit二次开发环境配置(Revit 2020 +Visual Studio 2019)