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

上节介绍了存储管理配置信息的结构体struct server_config_t,该结构体贯穿整个server端程序的运行。

在dhcpd.c里的用该结构体定义个一个全局的变量:

struct server_config_t server_config;

在server启动做的第一件事就是初始化这个全局变量server_config:

现在就进入read_config函数,一睹其真容!

学习这个函数,在以后遇到要读取配置信息可以参照read_config函数的写法。

read_config函数的定义是在file.c文件里。

分析read_config函数之前先来看一个结构体数组:

结构体的定义:

该结构体数组的定义以及初始化:

结构体名和数组名可以看出,config_keyword,配置信息关键字,正如其名,是辅助读取配置信息的。

数组里的每个config_keyword结构体元素中的keyword成员的值,与server_config_t里的成员变量名一一对应,该成员指示的就是配置的是server_config_t里的哪个成员。

读取配置信息的操作,配置信息读取存储到哪里,以及配置信息的默认值,这些由config_keywork里的后面的3个成员给出的。

成员heandler是一个函数指针,指向的函数即提供了怎么读取配置信息,以及把配置信息写到指定地址内。

arg, def则作为handler指向函数的两个各参数,arg告诉函数把配置信息存储到的地址,def则是配置信息的值,def是配置信息的默认值。

keyword数组里每个元素里的函数指针handler指向的这些函数,其定义都在file.c文件里。

handler函数的类型 : int (const *handler)(const char *line, void *arg)

1) read_ip: 把字符串格式的IP地址转换成uint32_t的IP格式,并存储到arg所指的内存。

2) read_u32: 把字符串格式的数转换成uint32_t类型数字,并存储到arg所指的内存。

3) read_yn: line字符串是“yes” 还是 “no”?若“yes”,将arg所指的内存赋1,反之,赋0

4) read_str:首先free(*arg)释放掉*arg指的内存,再根据字符串line的大小分配内存,并把line里的值复制到里面,让*arg指向新分配的内存。

5) read_opt: 从字符串line里读取options写到*arg所指的struct option_set链表里。(链表的每个结点data以CLV方式组织数据)

read_opt对选项的信息的读取借助里也借助结构数组(在options.c里定义的),所以函数比较复杂,这里只用知道函数作用。

6) read_staticlease:从line字符串里读取MAC、IP地址字符串里MAC与IP用’/t’or’=’作为分隔)再把MAC和IP添加到*arg所指的static_lease链表里。static_lease链表是dhcp Server管理已租赁出去的IP和获得该IP的客户机的MAC绑定。

7) read_mac: 从字符串格式MAC地址里读出MAC并转化的MAC存储arg所指的内存里

上面的read_xxx函数,read成功返回1, 失败返回0。

上面讲解的这么的多都是read_config函数的基础,好啦,现在正式进入read_config函数:

若read_config函数到这就结束了,server依靠这些默认配置的值也可以工作(options字段没有默认值,不能给client其他的网络配置,但可以给client端分配IP的),但这样的话,程序就缺乏灵活性,IP地址池不能修改,租赁时间无法设定等。

上面这段就是从文件里读取配置信息,下面是摘自udhcp.conf文件的部分配置信息:

while(fgets(buffer, READ_CONFIG_BUF_SIZE, in))

每次从文件里读取一行,存放在buffer里,在对buffer处理,空行、注释行(还有只有token, 没有line的)直接跳过继续读取下一行。

token = strtok(buffer, “ /t”); 取到该行的keyword (文件里key与value之间使用空格或’/t’)

line = strtok(NULL, “”); 取到该行的配置信息值

这样(还需简单处理下)就可以根据keywords数组把从文件读取到的配置信息写到server_config相应的成员里。

差不多了,总结下read_config函数,她对配置的对象全局变量server_conifg,通过一个辅助结构数组来对server_config里的成员变量进行赋值的。真正对于成员的赋值操作都是通过数组里元素的函数指针handler指向的函数进行的。

read_config只是做了从文件的每行读出信息,并作些处理,得到token和line,利用token在数组里找到对应的handler和arg,………

原文地址:https://www.cnblogs.com/woainilsr/p/3181017.html