Android10框架支持双以太网口

1 方法一双网口是两块独立的网卡桥接,linux中可以实现桥接,实现将两块网卡插入同一个交换一样。
Android的kernal中不支持brctl,Android先需要集成busybox1工具。

busybox1.11 ifconfig
busybox1.11 ifconfig eth0 up
busybox1.11 ifconfig eth1 up
busybox1.11 brctl addbr br0 
busybox1.11 brctl addif br0 eth0
busybox1.11 brctl addif br0 eth1
busybox1.11 ifconfig eth0 0.0.0.0
busybox1.11 ifconfig eth1 0.0.0.0
busybox1.11 ifconfig br0 192.168.1.2 netmask 255.255.255.0 #两块网口变成一块br0的网口
busybox1.11 route add default gw 192.168.1.1

ptables -A FORWARD -i eth0 -o eth1 -j ACCEPT
iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
iptables -D FORWARD 4                              /* 删除natctrl_FORWARD规则,FORWARD中的第4条规则  */

2,方法二两块网口仍然是独立的,可以独立设置IP地址,只是通过路由配置可以联通。
在ConnectivityService中更新连接状态updateLinkProperties时,把以太网的路由表写入了legacy_system路由表里面,这张路由表优先级高,会先使用。验证pass,可以ping通两个网段不同的路由器。

frameworks/base/services/core/java/com/android/server/ConnectivityService.java
     private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
             LinkProperties oldLp) {
         int netId = networkAgent.network.netId;
         updateRoutes(newLp, oldLp, netId);
         updateDnses(newLp, oldLp, netId);
+        log("trchen updateLinkProperties "+ networkAgent + " newLp= " + newLp);
+        saveEthernetInformation(newLp,true);
+
+        int NetworkType = networkAgent.networkInfo.getType();
+        if(NetworkType == ConnectivityManager.TYPE_ETHERNET) {
+             CompareResult<RouteInfo> routeDiff = new CompareResult<RouteInfo>();
+             for (RouteInfo route : newLp.getAllRoutes()) {
+                 if (route.hasGateway()) continue;
+                 if (!(route.getDestination().getAddress() instanceof Inet4Address)) continue;
+                 try {
+                    log("trchen addLegacyRouteForNetId " );
+                    mNMS.addLegacyRouteForNetId(netId, route, getCallingUid());
+
+                 } catch (Exception e) {
+                    // never crash - catch them all
+                    loge("Exception trying to add a route: " + e);
+                 }
+            }
+        }

同时,把LinkProperties中的IP地址、网关、dns信息保存到系统属性中,供给app查询,这里非常规改法。

+    private final static String nullIpInfo = "0.0.0.0";
+    private void saveEthernetInformation(LinkProperties mLinkProperties,boolean up) {
+       Log.i(TAG, "saveEthernetInformation " + mLinkProperties.getInterfaceName());
+       Log.i(TAG, "saveEthernetInformation up  " +up);
+       if(up){
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".ipaddress",getLinkIpAddress(mLinkProperties));
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".mask",getLinkNetmask(mLinkProperties));
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".gateway",getLinkGateway(mLinkProperties));
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".dns1",getLinkDns(mLinkProperties));
+       }else{
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".ipaddress",null);
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".mask",null);
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".gateway",null);
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".dns1",null);
+       }
+       Log.i(TAG, "saveEthernetInformation ipaddress  " +SystemProperties.get("dhcp."+ mLinkProperties.getInterfaceName() +".ipaddress")+"  ="+mLinkProperties.getInterfaceName());
+    }
+    private String getLinkIpAddress(LinkProperties mLinkProperties) {
+        for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
+            InetAddress source = l.getAddress();
+            //Log.d(TAG, "getIpAddress: " + source.getHostAddress());
+            if (source instanceof Inet4Address) {
+                return source.getHostAddress();
+            }
+        }
+        return "";
+    }
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".ipaddress",null);
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".mask",null);
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".gateway",null);
+          SystemProperties.set("dhcp."+ mLinkProperties.getInterfaceName() +".dns1",null);
+       }
+       Log.i(TAG, "saveEthernetInformation ipaddress  " +SystemProperties.get("dhcp."+ mLinkProperties.getInterfaceName() +".ipaddress")+"  ="+mLinkProperties.getInterfaceName());
+    }
+    private String getLinkIpAddress(LinkProperties mLinkProperties) {
+        for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
+            InetAddress source = l.getAddress();
+            //Log.d(TAG, "getIpAddress: " + source.getHostAddress());
+            if (source instanceof Inet4Address) {
+                return source.getHostAddress();
+            }
+        }
+        return "";
+    }
+    private String getLinkNetmask(LinkProperties mLinkProperties) {
+        for (LinkAddress l : mLinkProperties.getLinkAddresses()) {
+            InetAddress source = l.getAddress();
+            if (source instanceof Inet4Address) {
+                return linkprefix2netmask(l.getPrefixLength());
+            }
+        }
+        return "";
+    }
+    private  String linkprefix2netmask(int prefix) {
+        // convert prefix to netmask
+        if (true) {
+            int mask = 0xFFFFFFFF << (32 - prefix);
+            //Log.d(TAG, "mask = " + mask + " prefix = " + prefix);
+            return ((mask>>>24) & 0xff) + "." + ((mask>>>16) & 0xff) + "." + ((mask>>>8) & 0xff) + "." + ((mask) & 0xff);
+        } else {
+            return NetworkUtils.intToInetAddress(NetworkUtils.prefixLengthToNetmaskInt(prefix)).getHostName();
+        }
+    }
+    private String getLinkGateway(LinkProperties mLinkProperties) {
+        for (RouteInfo route : mLinkProperties.getRoutes()) {
+            if (route.hasGateway()) {
+                 InetAddress gateway = route.getGateway();
+                 if (route.isIPv4Default()) {
+                     return gateway.getHostAddress();
+                 }
+            }
+        }
+        return "";
+    }
+    private String getLinkDns(LinkProperties mLinkProperties) {
+        String dns = "";
+        for (InetAddress nameserver : mLinkProperties.getDnsServers()) {
+            dns += nameserver.getHostAddress();
+        }
+        return dns;
+    }

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 11 中,以太网同时联网的实现需要借助 NetworkStack 和 Ethernet 管理器。下面是一个简单的代码示例: 1. 获取 Ethernet 管理器实例: ``` EthernetManager ethernetManager = (EthernetManager) context.getSystemService(Context.ETHERNET_SERVICE); ``` 2. 创建两个 Ethernet 连接: ``` EthernetManager.EthernetNetworkCallback callback1 = new EthernetManager.EthernetNetworkCallback() { // 处理网络连接状态变化 }; EthernetNetworkSpecifier specifier1 = new EthernetNetworkSpecifier.Builder() .setMacAddress(MacAddress.fromString("xx:xx:xx:xx:xx:xx")) .build(); ethernetManager.requestNetwork(specifier1, callback1); EthernetManager.EthernetNetworkCallback callback2 = new EthernetManager.EthernetNetworkCallback() { // 处理网络连接状态变化 }; EthernetNetworkSpecifier specifier2 = new EthernetNetworkSpecifier.Builder() .setMacAddress(MacAddress.fromString("xx:xx:xx:xx:xx:xx")) .build(); ethernetManager.requestNetwork(specifier2, callback2); ``` 其中,`MacAddress.fromString()` 方法需要传入对应的 MAC 地址。 3. 获取 NetworkStack 实例: ``` NetworkStackClient networkStackClient = NetworkStackClient.getInstance(); ``` 4. 创建两个网络: ``` InetAddress ipv4Address1 = InetAddress.getByName("192.168.0.100"); InetAddress ipv4Address2 = InetAddress.getByName("192.168.1.100"); int interface1 = networkStackClient.createEthernetNetworkInterface(specifier1, ipv4Address1); int interface2 = networkStackClient.createEthernetNetworkInterface(specifier2, ipv4Address2); ``` 5. 将网络添加到路由表中: ``` NetworkStack.setInterfaceIpv4Address(interface1, ipv4Address1, 24); NetworkStack.addRoute(interface1, InetAddress.getByName("0.0.0.0"), 0); NetworkStack.setInterfaceIpv4Address(interface2, ipv4Address2, 24); NetworkStack.addRoute(interface2, InetAddress.getByName("0.0.0.0"), 0); ``` 6. 完成以上步骤后,两个以太网就可以同时联网了。 需要注意的是,这只是一个简单的示例代码,实际运行时需要根据具体情况进行修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值