|
|
本帖最后由 510819776 于 2021-5-28 19:15 编辑
ipv6到来了,但是安卓手机居然不支持dhcpv6
安卓只能支持 slaac 模式
我从chroot aarch64 3.13版本的alpine linux 中提取了 isc dhcp client 用来为安卓提供dhcp服务
dhclient -6 wlan0 -v 此命令获取新ipv6地址
dhclient -6 wlan0 -r -v 释放ipv6地址
使用很简单,下载附件,解压得到dhcp6文件夹
然后把dhcp6整个文件夹拷贝到手机/data下面
当然是需要root的
拷贝好打开终端模拟器
su
busybox chmod -R 777 /data/dhcp6
setenforce 0
/data/dhcp6/dhclient -6 wlan0 -v 即可
释放ip地址可以用
/data/dhcp6/dhclient -6 wlan -v -r即可
内置一个最新的dnsmasq 2.85版本
这个软件构架是aarch64 适合安卓5.0或以上版本
在我的红米note2 安卓5.0 和红米10x 5g 安卓10测试 正常使用
需要注意一下 这个dhclient 软件支持ipv4和ipv6
但是安卓的 dns4 dns6 设置和 linux终究不一样
安卓不使用/etc/resolv.conf
setipv6 这个文件其实是一个linux的shell脚本
如果出现脚本报错情况 可以自己用文本编辑器修改setipv6大家可以对setipv6进行精简,这个脚本里面配置/etc/resolv.conf的命令部分可以删掉
安卓不使用/etc/resolv.conf来配置dns
这个获取ipv4 ipv6的软件 原理很简单
先用dhclient 来获取dhcp服务器的各种参数
然后 将这些参数全部保存成临时变量 之后借助setipv6脚本和系统自带的ip 以及其他命令来配置dhcpv6参数
对应到安卓 其实只有 写入ipv6地址有用 dns6由安卓自己完成(路由器设置的)
查看手机获取的dns6命令是
getgrop | grep net.dns
ip查看命令是
busybox ifconfig wlan0
贴上自己精简后的setipv6
#!/data/dhcp6/busybox sh
ip=/system/bin/ip
#sleep=/system/xbin/sleep
#seq=/system/xbin/seq
#ifconfig=/system/xbin/ifconfig
_shellcheck_external_variables() {
: alias_ip_address="$alias_ip_address"
: alias_subnet_mask="$alias_subnet_mask"
: cur_ip6_address="$cur_ip6_address"
: cur_ip6_prefixlen="$cur_ip6_prefixlen"
: dad_wait_time="$dad_wait_time"
: interface="$interface"
: new_broadcast_address="$new_broadcast_address"
: new_dhcp6_domain_search="$new_dhcp6_domain_search"
: new_dhcp6_name_servers="$new_dhcp6_name_servers"
: new_domain_name="$new_domain_name"
: new_domain_name_servers="$new_domain_name_servers"
: new_host_name="$new_host_name"
: new_interface_mtu="$new_interface_mtu"
: new_ip6_address="$new_ip6_address"
: new_ip6_prefixlen="$new_ip6_prefixlen"
: new_ip_address="$new_ip_address"
: new_max_life="$new_max_life"
: new_preferred_life="$new_preferred_life"
: new_rfc3442_classless_static_routes="$new_rfc3442_classless_static_routes"
: new_routers="$new_routers"
: new_subnet_mask="$new_subnet_mask"
: old_dhcp6_domain_search="$old_dhcp6_domain_search"
: old_dhcp6_name_servers="$old_dhcp6_name_servers"
: old_host_name="$old_host_name"
: old_ip6_address="$old_ip6_address"
: old_ip6_prefixlen="$old_ip6_prefixlen"
: old_ip_address="$old_ip_address"
: reason="$reason"
}
exit_with_hooks() {
local exit_status
exit_status="${1}"
exit "${exit_status}"
}
ipv6_addr_del() {
"${ip}" -6 addr del "$@" dev "${interface}"
}
# shellcheck disable=SC2039
ipv6_addr_show() {
local dev
dev="${1}"
"${ip}" -6 addr show ${dev:+dev "${dev}"}
}
# shellcheck disable=SC2039
ipv6_addr_filter() {
local dev
dev="${1}"
shift
ipv6_addr_show "${dev}" | grep -F -e "${*}"
}
# shellcheck disable=SC2039
ipv6_addr_has_tentative() {
local dev
dev="${1}"
shift
ipv6_addr_filter "${dev}" "${@}" | grep -F -e tentative >/dev/null 2>&1
}
ip_link_set() {
${ip} link set "${@}"
}
link_set_up() {
ip_link_set dev "${interface}" up
}
link_set_mtu() {
[ -n "${1}" ] || return 0
ip_link_set dev "${interface}" mtu "${1}"
}
# shellcheck disable=SC2039
_ip_addr_flush() {
"${ip}" -6 addr flush "${@}"
}
ipv6_addr_flush() {
_ip_addr_flush "$@"
}
add_ipv6_addr_with_DAD() {
local _i
"${ip}" -6 addr replace "${new_ip6_address}/${new_ip6_prefixlen}" \
dev "${interface}" scope global valid_lft "${new_max_life}" \
preferred_lft "${new_preferred_life}"
if [ "${dad_wait_time}" -le 0 ]; then
return 0
fi
for _i in $(/data/dhcp6/busybox seq 1 "${dad_wait_time}"); do
/data/dhcp6/busybox sleep 1
addr="$(ipv6_addr_filter "${interface}" \
"${new_ip6_address}/${new_ip6_prefixlen}")"
tentative="$(echo "${addr}" | grep tentative)"
dadfailed="$(echo "${addr}" | grep dadfailed)"
if [ -n "${dadfailed}" ]; then
ipv6_addr_del "${new_ip6_address}/${new_ip6_prefixlen}"
exit_with_hooks 3
fi
if [ -z "${tentative}" ]; then
if [ -n "${addr}" ]; then
return 0
else
exit_with_hooks 3
fi
fi
done
return 0
}
# shellcheck disable=SC2039
init_if_metric() {
local _if_metric
_if_metric="${IF_METRIC}"
if [ "${new_routers%% *}" != "${new_routers}" ]; then
_if_metric="${_if_metric:-1}"
fi
if_metric="${_if_metric}"
echo "${_if_metric}"
}
case "${reason}" in
PREINIT)
echo
;;
PREINIT6)
#print_dhcp_info
interface_up_wait_time=5
for _i in $(/data/dhcp6/busybox seq 0 ${interface_up_wait_time}); do
if /data/dhcp6/busybox ifconfig "${interface}" | grep RUNNING >/dev/null 2>&1; then
break
fi
/data/dhcp6/busybox sleep 1
done; unset -v _i
ipv6_addr_flush dev "${interface}" scope global permanent
if [ "${dad_wait_time}" -gt 0 ]; then
if ipv6_addr_has_tentative "${interface}" inet6; then
for _i in $(seq 0 "${dad_wait_time}"); do
/data/dhcp6/busybox sleep 1
if ! ipv6_addr_has_tentative "${interface}" inet6; then
break
fi
done; unset -v _i
fi
fi
;;
BOUND6|RENEW6|REBIND6)
if [ "${new_ip6_address}" ] && [ "${new_ip6_prefixlen}" ]; then
add_ipv6_addr_with_DAD
fi
;;
DEPREF6)
if [ -z "${cur_ip6_prefixlen}" ]; then
exit_with_hooks 2
fi
"${ip}" -6 addr change "${cur_ip6_address}/${cur_ip6_prefixlen}" \
dev "${interface}" scope global preferred_lft 0
;;
EXPIRE6|RELEASE6|STOP6)
if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then
exit_with_hooks 2
fi
ipv6_addr_del "${old_ip6_address}/${old_ip6_prefixlen}"
;;
esac
echo "$reason"
#print_dhcp_info
busybox ifconfig "${interface}" | busybox grep inet
getprop | grep net.dns
exit_with_hooks 0
android的dns v6很神奇,不知道怎么搞的
./dhclient -6 wlan0 -v 执行两次后
getprop | grep net.dns 命令可以看到
net.dns1 net.dns2自动变成了 路由器里面的dns6地址
但这应该与脚本无关吧
路由器是openwrt 使用dnsmasq提供dhcp v6服务
这是我对ipv6 dnsmasq不成熟的一点理解
###################################################################
#运行dnsmasq的服务器ip设置为2::1/64,剩余64位客户端根据某些算法自动填充,无状态dhcp
dnsmasq -u root -i br-lan -h -K -n -N -R --dhcp-no-override -F 2::2,2::9,slaac --port=0 --dhcp-option=option6:dns-server,[8::8],[8::4]
这个命令适合安卓,ios支持dhcpv6 win支持dhcpv6 linux mac都支持dhcpv6
#运行dnsmasq的服务器ip设置为2::1/112,有状态dhcp
#dnsmasq -u root -h -K -n -N -R -i br-lan -F 2::2,2::9,112,10m --dhcp-no-override --enable-ra --port=0 --dhcp-option=option6:dns-server,[8::8],[8::4]
这个命令安卓是无法获取到ipv6地址的
但是可以用dhclient 或 wide dhcpv6 client 获取到ipv6地址
安卓busybox udhcpc6命令会崩溃....
#运行dnsmasq的服务器ip设置为2::1/112,静态指定ipv6地址
#客户端duid获取方式,前台运行dnsmasq后l可以看到duid信息
#duid windows可以直接ipconfig /all查看
静态ipv6指定
#dnsmasq -u root -i enp0s25 -h -K -n -N -R --dhcp-no-override --dhcp-sequential-ip --port=0 -F 2::2,2::9,112,100m --enable-ra --dhcp-host=id:00:01:00:01:28:41:4f:af:08:00:27:a2:03:a3,[2::33]
此命令执行前删除/var/lib/misc/dnsmasq.leases
除非是slaac,无状态配置,否则要加上--enable-ra参数,不加虽能获取ip,但ping不通
#dnsmasq -u root -i enp0s25 -h -K -n -N -R --dhcp-no-override --dhcp-sequential-ip --port=0 --dhcp-host=id:00:01:00:01:28:41:4f:af:08:00:27:a2:03:a3,[2::33] --enable-ra
这个命令应该也行,不过由于duid 会动态变化,一般不建议锁死ipv6
-h --no-host
-K --dhcp-authoritative
-n --no-poll
-N --no-negcache
-R --no-resolv
--dhcp-sequential-ip
安卓客户端可使用dhclient -6 wlan0 获取dhcpv6地址
也可以用wide-dhcpv6-client中的dhcp6c -i wlan0获取dhcpv6地址
################################################
附件下载
dhcp6.7z
(1.85 MB, 下载次数: 6)
|
|