openwrt 之dhcp客户端调用分析

客户端程序

root@BDCOM:/proc/1679# ps -w | grep udh
 1679 root      1484 S    udhcpc -p /var/run/udhcpc-eth0.2.pid -s /lib/netifd/dhcp.script -f -t 0 -i eth0.2 -V 3830d84fd8bc77bf -C

其父进程为 netifd

root@BDCOM:/proc/1679# cat stat
1679 (udhcpc) S 1593 0 0 0 -1 4194560 167 1266 0 0 0 3 8 6 20 0 1 0 3924 1519616 110 2147483647 4194304 4613096 2146095136 2146093040 1997973920 0 0 4100 114688 2149225712 0 0 18 0 0 0 0 0 0 4678632 4679983 10878976 2146098997 2146099102 2146099102 2146099183 0
root@BDCOM:/proc/1679# ps | grep netif
 1593 root      1552 S    /sbin/netifd

 

下面来看udhcpc这个程序是如何被执行的:

首先来看下面的dhcp.sh文件

root@BDCOM:/lib/netifd/proto# ls
3g.sh    dhcp.sh  ppp.sh   qmi.sh

找到下面的代码

	proto_run_command "$config" udhcpc \
		-p /var/run/udhcpc-$iface.pid \
		-s /lib/netifd/dhcp.script \
		-f -t 0 -i "$iface" \
		${ipaddr:+-r $ipaddr} \
		${hostname:+-H $hostname} \
		${vendorid:+-V $vendorid} \
		$clientid $broadcast $dhcpopts

dhcp客户端就是通过上面的脚本调用执行的

proto_run_command函数在netifd-proto.sh中有定义
函数的最后一句是:

_proto_notify "$interface"
_proto_notify() {
	local interface="$1"
	local options="$2"
	json_add_string "interface" "$interface"
	ubus $options call network.interface notify_proto "$(json_dump)"
}
最终调用的是ubus命令,通知notify_proto。

接下来进入netifd的源代码里,在ubus.c文件中

static struct ubus_method iface_object_methods[] = {
	{ .name = "lds", .handler = netifd_handle_down },
	{ .name = "up", .handler = netifd_handle_up },
	{ .name = "down", .handler = netifd_handle_down },
	{ .name = "status", .handler = netifd_handle_status },
	{ .name = "prepare", .handler = netifd_handle_iface_prepare },
	{ .name = "dump", .handler = netifd_handle_dump },
	UBUS_METHOD("add_device", netifd_iface_handle_device, dev_link_policy ),
	UBUS_METHOD("remove_device", netifd_iface_handle_device, dev_link_policy ),
	{ .name = "notify_proto", .handler = netifd_iface_notify_proto },
	{ .name = "remove", .handler = netifd_iface_remove },
	{ .name = "set_data", .handler = netifd_handle_set_data },
};

notify_proto进入的是netifd_iface_notify_proto函数,执行iface->proto->notify(iface->proto, msg);最终调用的是

proto_shell_notify函数->proto_shell_run_command->netifd_start_process->创建子进程并执行


还有个问题没有解决是,最开始的dhcp.sh是如何被执行的?

该脚本执行有两个入口点,第一处在netifd初始化过程中

static void
netifd_parse_script_handler(const char *name, script_dump_cb cb)
{
	struct json_tokener *tok = NULL;
	json_object *obj;
	static char buf[512];
	char *start, *cmd;
	FILE *f;
	int len;

#define DUMP_SUFFIX	" '' dump"

	cmd = alloca(strlen(name) + 1 + sizeof(DUMP_SUFFIX));
	sprintf(cmd, "%s" DUMP_SUFFIX, name);

	f = popen(cmd, "r");
	if (!f)
		return;
...
其执行了dhcp.sh '' dump,通过popen执行并返回json结果

第二处为proto_shell_handler->netifd_start_process->分配子进程执行


以上内容仅供参考





你可能感兴趣的:(openwrt)