Android DHCPプロセス
1、問題の背景
最近、あるプロジェクトでは、静的またはDHCPにかかわらずDNSを正常に修正できないという問題が発生しました.最後に、/etc/dhcpcd/dhcpcd-hooks/20-dnsのためであることが分かった.confというスクリプトでは、DNSを死んでしまいました.次のコードシートは、設定が終わるたびに、設定します.
では、このシナリオは何の役に立つのでしょうか.なぜこのスクリプトはDNSを書くことができますか.これはandroidではDHCPがDHCP Client端子とserver端子の2つの部分に分かれているからです.
2、Dhcpクライアント
クライアント側は、上位アプリからframeworkまでのDHCPリクエストです.このプロセスは難しくありません.一般的にrunDhcp関数が呼び出されます.JNIはframeworksbasecorejniandroid_にあります.net_NetUtils.cppのandroid_net_utils_runDhcpCommon.dhcp_が呼び出されますdo_request関数.ここまでframeworkの部分は終わり、次にsystem/core/libnetutilsに呼び出されます.
dhcp_do_request関数では、[dhcp.eth 0.result]プロパティが[ok]になるとfill_が呼び出されます.ip_info関数、この関数の役割は、IP情報を読み取ることです.
それは誰が本当にDHCPの仕事をしているのか、dhcpdという守護プロセスです.このプロセスはinitに基づいています.svc.dhcpcdで制御されます.このプロセスはこれらの属性を設定し、これらの属性は最後にスクリプトに基づいて設定されます.つまり、上述のスクリプト20-dnsです.confと95-configured.この2つのスクリプトはまたetc/dhcpcd/dhcpcd-run-hooksによって調整されます.大まかな流れは次の通りです.
3、Dhcp server端
dhcpcd呼び出しプロセス:
コードはexternal/dhcpcdで、
4、DHCPプロトコル
一つ、ネットワークパケットをフィルタリングするときにフィルタリングすべきはbootpで、dhcpではありませんよ.dhcpメッセージの種類は以下の通りです.
(1)DHCPDISCOVER(0×01)ClientがDHCPプロセスを開始する最初のメッセージである.
(2)DHCPOFFER(0×02)DHCPDISCOVERメッセージに対するサーバの応答.
(3)DHCPREQUEST(0×03)このメッセージは、SlientがDHCPを開始する過程でserverのDHCPOFFERメッセージに対する応答、またはclientがIPアドレスのリース期間を延長する時に発行されるメッセージである.
(4)DHCPDECLINE(0×04)Clientは、サーバーに割り当てられたIPアドレスが使用できないことを発見し、例えばIPアドレスが衝突した場合、このメッセージを発行し、サーバーにIPアドレスの使用を禁止することを通知する.
(5)DHCPACK(0×05)、サーバーはClientのDHCPREQUESTメッセージの確認応答メッセージに対して、Clientはこのメッセージを受け取った後、やっと本当にIPアドレスと関連する配置情報を獲得した;
(6)DHCPNAK(0×06)サーバはClientのDHCPREQUESTメッセージに対する拒絶応答メッセージを受信し、Clientはこのメッセージを受信した後、一般的に新しいDHCPプロセスを再開する.
(7)DHCPRELEASE(0×07)Clientは、サーバが割り当てたIPアドレスのメッセージを自発的に解放し、サーバがこのメッセージを受信すると、このIPアドレスを回収し、他のClientに割り当てることができる.
(8)DHCPINFORM(0×08)ClientはすでにIPアドレスを取得しており、このメッセージを送信するのは、DHCPSERVERからrouteip,DNSIpなどの他のネットワーク構成情報を取得するためだけであり、このようなメッセージの応用は非常に珍しい.
最近、あるプロジェクトでは、静的またはDHCPにかかわらずDNSを正常に修正できないという問題が発生しました.最後に、/etc/dhcpcd/dhcpcd-hooks/20-dnsのためであることが分かった.confというスクリプトでは、DNSを死んでしまいました.次のコードシートは、設定が終わるたびに、設定します.
setprop dhcp.${intf}.dns${dnsvalue} 203.82.48.3
setprop dhcp.${intf}.dns${standydnsvalue} 203.82.48.4
# Set net..dnsN properties that contain the
# DNS server addresses given by the DHCP server.
if [[ $interface == p2p* ]]
then
intf=p2p
else
intf=$interface
fi
set_dns_props()
{
case "${new_domain_name_servers}" in
"") return 0;;
esac
count=1
for i in 1 2 3 4; do
setprop dhcp.${intf}.dns${i} ""
done
count=1
for dnsaddr in ${new_domain_name_servers}; do
setprop dhcp.${intf}.dns${count} ${dnsaddr}
count=$(($count + 1))
done
dnsvalue=1
standydnsvalue=2
setprop dhcp.${intf}.dns${dnsvalue} 203.82.48.3
setprop dhcp.${intf}.dns${standydnsvalue} 203.82.48.4
separator=" "
if [ -z "$new_domain_name" ]; then
separator=""
else
if [ -z "$new_domain_search" ]; then
separator=""
fi
fi
setprop dhcp.${interface}.domain "${new_domain_name}$separator${new_domain_search}"
}
unset_dns_props()
{
for i in 1 2 3 4; do
setprop dhcp.${intf}.dns${i} ""
done
setprop dhcp.${interface}.domain ""
}
case "${reason}" in
BOUND|INFORM|REBIND|REBOOT|RENEW|TIMEOUT) set_dns_props;;
EXPIRE|FAIL|IPV4LL|RELEASE|STOP) unset_dns_props;;
esac
では、このシナリオは何の役に立つのでしょうか.なぜこのスクリプトはDNSを書くことができますか.これはandroidではDHCPがDHCP Client端子とserver端子の2つの部分に分かれているからです.
2、Dhcpクライアント
クライアント側は、上位アプリからframeworkまでのDHCPリクエストです.このプロセスは難しくありません.一般的にrunDhcp関数が呼び出されます.JNIはframeworksbasecorejniandroid_にあります.net_NetUtils.cppのandroid_net_utils_runDhcpCommon.dhcp_が呼び出されますdo_request関数.ここまでframeworkの部分は終わり、次にsystem/core/libnetutilsに呼び出されます.
dhcp_do_request関数では、[dhcp.eth 0.result]プロパティが[ok]になるとfill_が呼び出されます.ip_info関数、この関数の役割は、IP情報を読み取ることです.
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);
}
それは誰が本当にDHCPの仕事をしているのか、dhcpdという守護プロセスです.このプロセスはinitに基づいています.svc.dhcpcdで制御されます.このプロセスはこれらの属性を設定し、これらの属性は最後にスクリプトに基づいて設定されます.つまり、上述のスクリプト20-dnsです.confと95-configured.この2つのスクリプトはまたetc/dhcpcd/dhcpcd-run-hooksによって調整されます.大まかな流れは次の通りです.
3、Dhcp server端
dhcpcd呼び出しプロセス:
コードはexternal/dhcpcdで、
=>main
# define SYSCONFDIR "/system/etc/dhcpcd"
#define PACKAGE "dhcpcd"
# define CONFIG SYSCONFDIR "/" PACKAGE ".conf"
# define LIBEXECDIR "/system/etc/dhcpcd"
# define SCRIPT LIBEXECDIR "/" PACKAGE "-run-hooks"
=>strlcpy(options->script, SCRIPT, sizeof(options->script));// options->script="/system/etc/dhcpcd /dhcpcd-run-hooks"
=>f = fopen(cf ? cf : CONFIG, "r");// .conf , .conf
=>parse_config_line// "/system/etc/dhcpcd/dhcpcd.conf"
=>parse_option
=> "/system/etc/dhcpcd/dhcpcd.conf" "script"
=> strlcpy(options->script, oarg, sizeof(options->script));
/*
{"script", required_argument, NULL, 'c'},
{"option", required_argument, NULL, 'o'},
"/system/etc/dhcpcd/dhcpcd.conf" :
...
option domain_name_servers, domain_name, domain_search, host_name
...
*/
=>dhcp_run
=>handle_dhcp_packet
=>handle_dhcp
=>bind_dhcp
reason = "TIMEOUT";reason = "BOUND";reason = "REBIND";reason = "RENEW";
system/extra/dhcpcd-4.0.0-beta9/configure.c
=> configure(iface, reason, state->new, state->old, &state->lease, options, 1);
// dhcp dhcp , exec_script ,
// setprop dhcp.${interface}.result "failed"
// setprop dhcp.${interface}.result "ok"
=>exec_script(options, iface->name, reason, NULL, old);
=> configure_env reason
int exec_script(const struct options *options, const char *iface, const char *reason,
const struct dhcp_message *dhcpn, const struct dhcp_message *dhcpo)
=>pid = fork();
=>if(pid == 0)execve(options->script, argv, env);// , "/system/etc/dhcpcd/dhcpcd-run-hooks"
//dhcpcd-run-hooks level , system/etc/dhcpcd/dhcpcd-hook/*
// system/etc/dhcpcd/dhcpcd-hook/* 2
//95-configured
//20-dns.conf
=> while (waitpid(pid, &status, 0) == -1)
4、DHCPプロトコル
一つ、ネットワークパケットをフィルタリングするときにフィルタリングすべきはbootpで、dhcpではありませんよ.dhcpメッセージの種類は以下の通りです.
(1)DHCPDISCOVER(0×01)ClientがDHCPプロセスを開始する最初のメッセージである.
(2)DHCPOFFER(0×02)DHCPDISCOVERメッセージに対するサーバの応答.
(3)DHCPREQUEST(0×03)このメッセージは、SlientがDHCPを開始する過程でserverのDHCPOFFERメッセージに対する応答、またはclientがIPアドレスのリース期間を延長する時に発行されるメッセージである.
(4)DHCPDECLINE(0×04)Clientは、サーバーに割り当てられたIPアドレスが使用できないことを発見し、例えばIPアドレスが衝突した場合、このメッセージを発行し、サーバーにIPアドレスの使用を禁止することを通知する.
(5)DHCPACK(0×05)、サーバーはClientのDHCPREQUESTメッセージの確認応答メッセージに対して、Clientはこのメッセージを受け取った後、やっと本当にIPアドレスと関連する配置情報を獲得した;
(6)DHCPNAK(0×06)サーバはClientのDHCPREQUESTメッセージに対する拒絶応答メッセージを受信し、Clientはこのメッセージを受信した後、一般的に新しいDHCPプロセスを再開する.
(7)DHCPRELEASE(0×07)Clientは、サーバが割り当てたIPアドレスのメッセージを自発的に解放し、サーバがこのメッセージを受信すると、このIPアドレスを回収し、他のClientに割り当てることができる.
(8)DHCPINFORM(0×08)ClientはすでにIPアドレスを取得しており、このメッセージを送信するのは、DHCPSERVERからrouteip,DNSIpなどの他のネットワーク構成情報を取得するためだけであり、このようなメッセージの応用は非常に珍しい.