随着5G手机流量套餐充足,在没有Wi-Fi环境下,手机移动数据共享给其它设备也越来越多的人使用。
本文主要讲述移动数据共享功能的设置方法和原理,方便大家操作和理解。
共享方式
移动数据共享就是将手机当作网卡的功能,可有如下共享方式
-
USB tethering方式,即通过USB做网卡使用手机的移动数据(default data);
-
手机作为Wi-Fi无线热点(Hotspot),共享移动数据(default data);
-
通过蓝牙共享手机的Wi-Fi或者移动数据(default data);
设置方法
Android用户进设置->连接与共享->个人热点
Wi-Fi无线热点
开启个人热点,设置热点名称和密码,需要连接该热点的设备开启Wi-Fi,搜索到该热点并输入密码进行连接即可。
蓝牙共享
开启蓝牙网络共享,需要打开双方蓝牙功能并进行配对连接,连接设备的Wi-Fi功能不用开启,设置共享的设备无论开启的是移动数据或者Wi-Fi,都可以共享给连接的设备。
USB共享
USB网络共享,需要手机通过USB线与电脑进行连接,手机端选择USB网络共享,电脑端关闭Wi-Fi,允许连接Remote NDIS即可。
手机端
电脑端
原理介绍
该功能核心是通过iptable NAT(Network Address Translation)转换实现,将源地址与目标地址进行转变,在UE中实现中转。将来自Tether-Client的数据通过Tether-Host转换后无差分通过上行iface发出。
在framework层通过如下方式,在两个iface之间达成NAT
//frameworks/base/services/core/java/com/android/server/connectivity/Tethering.java
case CMD_TETHER_CONNECTION_CHANGED:
cleanupUpstream();
if (newUpstreamIfaceName != null) {
try {
mNMService.enableNat(mIfaceName, newUpstreamIfaceName);
mNMService.startInterfaceForwarding(mIfaceName,
newUpstreamIfaceName);
最终透过Netd socket将NAT命令发送至Netd daemon,而Netd作为在init.rc中定义的系统级daemon,初始化后通过iptables cmd在系统中设置了如下的iptable 规则
/system/netd/server/CommandListener.cpp
createChildChains(V4V6, "filter", "FORWARD", FILTER_FORWARD);
createChildChains(V4, "mangle", "FORWARD", MANGLE_FORWARD);
createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING); gCtls->bandwidthCtrl.setupIptablesHooks();
//iptable rules
-A FORWARD -j natctrl_FORWARD
-A natctrl_FORWARD -j DROP
-N natctrl_mangle_FORWARD
-A FORWARD -j natctrl_mangle_FORWARD
-A natctrl_mangle_FORWARD -p tcp -m tcp --tcp-flags SYN SYN -j TCPMSS –clamp-mss-to-pmtu
重要的是最后一条规则,这条规则是使TCP的SYN包中MSS字段根据upstream的MTU自动调整,相互兼容,避免downstream的数据包因超过通路upstream的MTU而无法通过。关于MSS的计算,通常ipv4协议MSS=MTU减40(IP数据包包头20字节和TCP数据包头20字节)。
当开启设备的一种数据共享后,以开启hotspot共享为例,in_iface = wlan0,ext_iface = rmnet_data0,使出口为rmnet_data0的数据包,按照rmnet_data0网络接口设备的当前ip自动进行dst address的nat。
table nat added chain:
-A natctrl_nat_POSTROUTING -o rmnet_data0 -j MASQUERADE
table filter added chain:
-A natctrl_FORWARD -i rmnet_data0 -o wlan0 -m state --state RELATED,ESTABLISHED -g natctrl_tether_counters
-A natctrl_FORWARD -i wlan0-o rmnet_data0-m state --state INVALID -j DROP
-A natctrl_FORWARD -i wlan0-o rmnet_data0-g natctrl_tether_counters
-A natctrl_tether_counters -i wlan0-o rmnet_data0-j RETURN
-A natctrl_tether_counters -i rmnet_data0-o wlan0-j RETURN
在ap0与rmnet_data0之间建立一条nat通道,保证有效数据能够成功通过iface转发。