定义的数据结构对于C程序的重要性,不言而喻。面向对象设计的程序是一个个对象的集合,而面向过程语言设计的程序则是数据结构与算法的集合。

下面来分析的是dhcp server中的定义结构体:

1)、在packet.h文件里定义了DHCP报文的格式:

struct dhcpMessage报文的字段虽然都有注释,但还是有必要讲下options字段。

options在大多文档中的说法是可选字段,大小不定,对于这个字段的重要性没有太多的强调。其实在DHCP交互过程,客户得到IP的配置过程,这个options字段有着很重要的作用,传递个很多不可或缺的信息。

例如Server与Client交互时,数据包的类型,是通过该字段的指示的。还有Client要成功连接到互联网,不只是需要IP,还需要其他的配置信息,如Dns、Router、Subnet等信息,Server就是通过options字段把这些信息传递给Client。(查看options支持哪些选项信息可以查看文档RFC2132)

问题来啦!!

这么多信息都放到一个字段,怎么合理的组织在一起呢,怎么能让交互双方准确的从这个字段取到相应的信息呢?

options字段才用“CLV“方式组织数据信息,OPT_CODE:标识号,唯一标识后面的信息内容;占1byte;OPT_LEN:长度,表示后面信息内容的长度,占1byte;value(OPT_DATA):信息内容,其长度由OPT_LEN所指定,以byte为单位(RFC2132文档给出所有支持选项的OPT_CODE,和可以确定长度的OPT_LEN的值)

CLV 的数据组织方式:

0 1 2 +Length

Code

Length

DATA

这是一种很漂亮的把多种数据信息组织在一个字段的方式,后面会看到对options字段相应的操作函数,这些函数就是根据CLV的方式对数据进行提取或者组织的。

另外options字段存储的信息分为三大类:

① DHCP_PADDING 填充字节 //读取的信息时候注意跳过

② DHCP_END 结束标志 //标志options字段的结束

③ CLV组织的有价值信息 //real value for us

options字段还有个让人纠结的情况——选项过载,其实也没什么,在后面遇再说吧!

2)、在dhcpd.h里定义里一个贯穿整个Server端程序的结构体struct server_config_t

上面的注释是源文件上的,本来的打算翻译下的,看了下注释很直白,没什么好翻译的,只是讲下其中的专业术语(好像是这么说的)。

network order 网络字节序, host order 主机字节序 相信大家了解她们的区别吧。

(定义类型是 uint32_t … ,说明变量是以network order存储的

常用数据类型 int long … ,说明变量是以host order存储的)

下面讲解下其中一些重要的成员:

① start,end可分配地址空间,每个客户的请求获得的IP都在这个内。IP地址池。

② struct option_set结构体的定义也在dhcpd.h里

Option set翻译过来:选项集合,就是的该结构的意义。上面分析struct dhcpMessage报文里有个选项字段options,她的值就是根据该集合(Option List)填写赋值的。

集合(Option List)里每个结点是一个选项信息,数据CLV的组织方式的。

与报文中options字段的区别是,报文里用一个options字段存储了所有的选项信息,options_set而是把一个一个的选项信息用链表链接起来。

③ 下面的几个是与租赁期限有关的成员变量

unsigned long lease client请求的租赁期限最大值,>lease,就以lease为租赁期限;client请求未指明租赁期限,lease作为其租赁期限(静态租赁的默认租期)。

unsigned long decline_time server的DHCPOFFER报文提供一个IP给client,client检测IP已经被其他主机使用,发送DHCPDECLINE报文给server,server接到该报文后,把IP添加到动态租赁数组里,租赁租期就是decline_time,对应的MAC为blank_chaddr(黑户,很形象^-^,实际值是全0)

unsigned long confict_time server在IP地址池找个a free IP时,检测到IP已被网络中的主机所使用,会把IP添加到动态租赁数组里,租赁期限就是confict_time,MAC:blank_chaddr。

unsigned long offer_time server发送DHCPOFFER报文时,即向client提供了IP地址,server会把IP和对应得MAC添加的动态租赁表里,但这个IP不一定会被client使用,所以添加到动态租赁表里的租赁期限要短,offer_time就是这个租赁期限(default : 60s)。(当server接收到DHCPREQUEST的时候会把租赁期限修改成请求的租赁期限)。

unsigned long min_lease client端的请求租赁期限不能小于min_lease。

④ 与保存租赁信息有关的两个成员变量:

char remaining 摘自dhcpd.conf里的注释(以及翻译和注解):

# If remaining is true (default), udhcpd will store the time

# remaining for each lease in the udhcpd leases file. This is

# for embedded systems that cannot keep time between reboots.

# If you set remaining to no, the absolute time that the lease

# expires at will be stored in the dhcpd.leases file.

# 如果剩下的就是true(默认),udhcpd将存储时间文件中

# 的每个udhcpd租赁租赁剩余。

# 这对于嵌入式系统,不能保持在重新启动的时间。

# (即重新启动就不算入租赁时间里)

# 如果您设置其余为NO,绝对时间,

# 租赁期满时将被储存在dhcpd.leases文件档案。

# 绝对时间,例: starts 0 2000/01/30 08:02:54;

# ends 5 2000/02/04 08:02:54;

# 而嵌入式存储的是租赁剩余时间

# 即 leases[i].expires - time(0) 的值

unsigne long auto_time how long should udhcpd wait before writing a config file.

if this is zero, it will only write one on SIGUSR1

多长时间把动态租赁表里的信息写入文件(dhcpd.leases)里。

Auto_time = 0的,只有等到SIGUSR1信号的时候才写。

⑤ struct static_lease *static_lease

/* dhcpd.h */

struct static_lease{

uint8_t *mac;

uint32_t *ip;

struct static_lease *next;

};

因为DHCP允许手动为client端配置IP,server端管理这些手动配置的IP就是使用该结构。

在dhcpd.c文件里声明定义一个struct server_config_t的全局变量server_config,server对于client的响应交互都必须有这个变量的参与。

3)、server端对于租赁出去的IP的管理基于以下这个结构体:

uint8_t chaddr[16]; 客户机的 MAC地址;

uint32_t yiaddr; 客户机租赁的IP地址;

uint32_t expires; 客户机租赁IP的到期时间

(是未来的一个时间点,是从1970.1.1午夜开始到租赁到期时刻的秒数)

这里有些奇怪,使用uint32_t声明的expires存储方式用的是host order, 这是因为server在把租赁记录保存到dhcpd.leases文件时使用的是network order方式保存的。(个人认为声明为unsigned long类型更为合适)

在dhcpd.c文件里声明定义一个 指向struct dhcpOferedAddr类型数组的全局指针变量leases。leases指向的数组大小由IP地址池大小决定的。

Server端主要的结构体就是这些,他们是整个server端程序跑起来的基础。还有一些其他结构体的设计是为了某些函数特别定制的,在分析具体函数再做讲解。

udhcp源码详解(二)--转的更多相关文章

  1. udhcp源码详解(五) 之DHCP包--options字段

    中间有很长一段时间没有更新udhcp源码详解的博客,主要是源码里的函数太多,不知道要不要一个一个讲下去,要知道讲DHCP的实现理论的话一篇博文也就可以大致的讲完,但实现的源码却要关心很多的问题,比如说 ...

  2. udhcp源码详解(四) 之租赁IP的管理

    Server端对于租赁出去的IP的管理是基于结构体dhcpOfferedAddr的,该结构体的定义是在leases.c文件里:(结构体的成员介绍说明见详解之数据结构) 1: struct dhcpOf ...

  3. udhcp源码详解(三) 下 之配置信息的读取

    上节讲解了read_config函数,读取配置信息到server_config的相应成员变量里,但read_config函数只负责把配置信息重文件里读出来,具体怎么把信息填写到指定的地址内,是调用ke ...

  4. udhcp源码详解(三)上 之配置信息的读取

    上节介绍了存储管理配置信息的结构体struct server_config_t,该结构体贯穿整个server端程序的运行. 在dhcpd.c里的用该结构体定义个一个全局的变量: struct serv ...

  5. udhcp源码详解(一)之文件组织结构(dhcp server) --转

    udhcp目录下有十几个源文件,一个源文件相对应一个模块,完成一系列相关的功能,例如在static_leases.c主要针对static_lease链表增删查找等操作. dhcpd.c——   整个d ...

  6. OkHttp3源码详解(二) 整体流程

    1.简单使用 同步: @Override public Response execute() throws IOException { synchronized (this) { if (execut ...

  7. vue 源码详解(二): 组件生命周期初始化、事件系统初始化

    vue 源码详解(二): 组件生命周期初始化.事件系统初始化 上一篇文章 生成 Vue 实例前的准备工作 讲解了实例化前的准备工作, 接下来我们继续看, 我们调用 new Vue() 的时候, 其内部 ...

  8. spring事务详解(三)源码详解

    系列目录 spring事务详解(一)初探事务 spring事务详解(二)简单样例 spring事务详解(三)源码详解 spring事务详解(四)测试验证 spring事务详解(五)总结提高 一.引子 ...

  9. Shiro 登录认证源码详解

    Shiro 登录认证源码详解 Apache Shiro 是一个强大且灵活的 Java 开源安全框架,拥有登录认证.授权管理.企业级会话管理和加密等功能,相比 Spring Security 来说要更加 ...

随机推荐

  1. STL源码分析-iterator(迭代器)

    1. GOF 迭代器设计模式 前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,但是后面觉得,实现具体容器之前有必要介绍一下iterator(迭代器) .那么迭代器是什么呢 ...

  2. find指令使用手册

    find 目录 条件 选项 find . –print find . –print0 .指明在当前目录中查找 -print 打印匹配文件的文件名,使用‘\n’作为分隔文件的定位符 -print0 打印 ...

  3. webpack 之 plugin

    loader和plugins的区别是:前者处理单个文件,而后者作用于整个打包过程 内置插件:BannerPlugin 可以在打包后的文件上方添加备注信息,如版权说明等 // webpack.confi ...

  4. python基础 : 1.计算机基础 2.注释 3.变量 4.标识符 5.输出 6.格式化输出 7.输入 8.算数运算符 9.字符串操作

  5. viva correction statements

    * List of amendments| No. | Location     | Amendments                                                ...

  6. 分享下找到的Github上大神的EmpireofCode进攻策略:反正我是用了没反应,改了代码后单位不进攻,蠢站在那里,我自己的策略调调能打败不少人,这个日后慢慢研究吧,Github上暂时找到的唯一策略

    from queue import PriorityQueue from enum import Enum from battle import commander from battle impor ...

  7. JavaEE JDBC 了解数据库连接池

    了解数据库连接池 @author ixenos 数据库连接是有限的资源,如果用户需要离开应用一段时间,那么他占用的连接就不应该保持开放状态: 另一方面,每次查询都获取连接并在随后关闭它的代价也很高. ...

  8. POJ 1236 学校网络间的强连通

    题目大意: N个学校之间有单向的网络,每个学校得到一套软件后,可以通过单向网络向周边的学校传输.问题1:初始至少需要向多少个学校发放软件,使得网络内所有的学校最终都能得到软件.问题2:至少需要添加几条 ...

  9. IPython的常见用法

    IPython :交互式的Python命令行 安装: pip install ipython 使用(命令行中启动): ipython # 与Python解释器的使用方法一致 IPython高级功能: ...

  10. POJ1256 Anagram

    Time Limit: 1000MS   Memory Limit: 10000KB   64bit IO Format: %lld & %llu Submit Status Descript ...