1、DHCP client 和 dhcpcd server直接的信息交互: socket
Client 和server 經過property_get/set 共享內存來共享信息。 ide
property_get/set(key,value),保存在共享內存中,系統中的各個進程能夠經過property_service訪問。 ui
2、DHCP 客戶端: spa
啓動dhcp 請求: router
源碼:Gingerbread/System/core/libnetutils/dhcp_utils.c server
int dhcp_do_request(const char *interface, in_addr_t *ipaddr, in_addr_t *gateway, in_addr_t *mask, in_addr_t *dns1, in_addr_t *dns2, in_addr_t *server, uint32_t *lease) dns
{ 進程
property_set(「dhcp_eth0.result」, ""); ip
property_set("ctl.start", "dhcpcd_eth0"); 內存
wait_for_property(「init.svc.dhcpcd_eth0」,」 running」, 10);
wait_for_property(「dhcp_eth0.result」, NULL, 30);
property_get(「dhcp_eth0.result」, prop_value, NULL));
if (strcmp(prop_value, "ok") == 0) {
fill_ip_info(interface, ipaddr, gateway, mask, dns1, dns2, server, lease);
return 0;
} else {
snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value);
return -1;
}
}
static void fill_ip_info(const char *interface, in_addr_t *ipaddr, in_addr_t *gateway, in_addr_t *mask, in_addr_t *dns1, in_addr_t *dns2, in_addr_t *server, uint32_t *lease)
{
property_get(「dhcp.eth0. ipaddress」, prop_value,NULL);
property_get(「dhcp.eth0. gateway」, prop_value,NULL);
property_get(「dhcp.eth0. mask」, prop_value,NULL);
property_get(「dhcp.eth0. dns1」, prop_value,NULL);
property_get(「dhcp.eth0. dns2」, prop_value,NULL);
property_get(「dhcp.eth0. server」, prop_value,NULL);
property_get(「dhcp.eth0. leasetime」, prop_value,NULL);
}
3、Dchpcd 服務端進程:
源碼:Gingerbread/external/dhcpcd/dhcpcd.c
Main()
{
dhcp_run(options, &pid_fd);
}
dhcp_run()
{
client_setup(state, options);
for (;;) {
if (r == 0)
r = handle_timeout(state, options); /client狀態機處理,發送dhcp 請求/
else if (r > 0) {
handle_dhcp_packet(state, options);
}
handle_timeout(struct if_state *state, const struct options *options)
{
switch(state->state) {
case STATE_RENEW_REQUESTED:
state->state = STATE_REBINDING;
case STATE_INIT:
state->state = STATE_REQUESTING;
}
switch (state->state) {
case STATE_DISCOVERING:
send_message(state, DHCP_DISCOVER, options);
break;
case STATE_REQUESTING:
if (state->options & DHCPCD_INFORM) {
send_message(state, DHCP_INFORM, options);
break;
}
case STATE_RENEWING:
case STATE_REBINDING:
if (iface->raw_fd == -1)
do_socket(state, SOCKET_OPEN);
send_message(state, DHCP_REQUEST, options);
break;
}}
handle_dhcp_packet()àhandle_dhcp()àbind_dhcp()àconfigure()àrun_script()
執行腳本文件/system/etc/dhcpcd/dhcpcd-run-hooks,腳本文件調用setprop命令設置dhcp相關參數,並設置dhcp result.
case "${reason}" in
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT)
setprop dhcp.${interface}.ipaddress "${new_ip_address}"
setprop dhcp.${interface}.gateway "${new_routers%% *}"
setprop dhcp.${interface}.mask "${new_subnet_mask}"
setprop dhcp.${interface}.leasetime "${new_dhcp_lease_time}"
setprop dhcp.${interface}.server "${new_dhcp_server_identifier}"
setprop dhcp.${interface}.result "ok"
;;
EXPIRE|FAIL|IPV4LL|STOP)
setprop dhcp.${interface}.result "failed"
;;
RELEASE)
setprop dhcp.${interface}.result "released"
;;