1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.ip; 18 19 import android.net.INetd; 20 import android.net.InterfaceConfiguration; 21 import android.net.LinkAddress; 22 import android.net.util.NetdService; 23 import android.net.util.SharedLog; 24 import android.os.INetworkManagementService; 25 import android.os.RemoteException; 26 import android.os.ServiceSpecificException; 27 import android.system.OsConstants; 28 29 import java.net.InetAddress; 30 31 32 /** 33 * Encapsulates the multiple IP configuration operations performed on an interface. 34 * 35 * TODO: refactor/eliminate the redundant ways to set and clear addresses. 36 * 37 * @hide 38 */ 39 public class InterfaceController { 40 private final static boolean DBG = false; 41 42 private final String mIfName; 43 private final INetworkManagementService mNMS; 44 private final INetd mNetd; 45 private final SharedLog mLog; 46 47 public InterfaceController(String ifname, INetworkManagementService nms, INetd netd, 48 SharedLog log) { 49 mIfName = ifname; 50 mNMS = nms; 51 mNetd = netd; 52 mLog = log; 53 } 54 55 public boolean setIPv4Address(LinkAddress address) { 56 final InterfaceConfiguration ifcg = new InterfaceConfiguration(); 57 ifcg.setLinkAddress(address); 58 try { 59 mNMS.setInterfaceConfig(mIfName, ifcg); 60 if (DBG) mLog.log("IPv4 configuration succeeded"); 61 } catch (IllegalStateException | RemoteException e) { 62 logError("IPv4 configuration failed: %s", e); 63 return false; 64 } 65 return true; 66 } 67 68 public boolean clearIPv4Address() { 69 try { 70 final InterfaceConfiguration ifcg = new InterfaceConfiguration(); 71 ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0")); 72 mNMS.setInterfaceConfig(mIfName, ifcg); 73 } catch (IllegalStateException | RemoteException e) { 74 logError("Failed to clear IPv4 address on interface %s: %s", mIfName, e); 75 return false; 76 } 77 return true; 78 } 79 80 public boolean enableIPv6() { 81 try { 82 mNMS.enableIpv6(mIfName); 83 } catch (IllegalStateException | RemoteException e) { 84 logError("enabling IPv6 failed: %s", e); 85 return false; 86 } 87 return true; 88 } 89 90 public boolean disableIPv6() { 91 try { 92 mNMS.disableIpv6(mIfName); 93 } catch (IllegalStateException | RemoteException e) { 94 logError("disabling IPv6 failed: %s", e); 95 return false; 96 } 97 return true; 98 } 99 100 public boolean setIPv6PrivacyExtensions(boolean enabled) { 101 try { 102 mNMS.setInterfaceIpv6PrivacyExtensions(mIfName, enabled); 103 } catch (IllegalStateException | RemoteException e) { 104 logError("error setting IPv6 privacy extensions: %s", e); 105 return false; 106 } 107 return true; 108 } 109 110 public boolean setIPv6AddrGenModeIfSupported(int mode) { 111 try { 112 mNMS.setIPv6AddrGenMode(mIfName, mode); 113 } catch (RemoteException e) { 114 logError("Unable to set IPv6 addrgen mode: %s", e); 115 return false; 116 } catch (ServiceSpecificException e) { 117 if (e.errorCode != OsConstants.EOPNOTSUPP) { 118 logError("Unable to set IPv6 addrgen mode: %s", e); 119 return false; 120 } 121 } 122 return true; 123 } 124 125 public boolean addAddress(LinkAddress addr) { 126 return addAddress(addr.getAddress(), addr.getPrefixLength()); 127 } 128 129 public boolean addAddress(InetAddress ip, int prefixLen) { 130 try { 131 mNetd.interfaceAddAddress(mIfName, ip.getHostAddress(), prefixLen); 132 } catch (ServiceSpecificException | RemoteException e) { 133 logError("failed to add %s/%d: %s", ip, prefixLen, e); 134 return false; 135 } 136 return true; 137 } 138 139 public boolean removeAddress(InetAddress ip, int prefixLen) { 140 try { 141 mNetd.interfaceDelAddress(mIfName, ip.getHostAddress(), prefixLen); 142 } catch (ServiceSpecificException | RemoteException e) { 143 logError("failed to remove %s/%d: %s", ip, prefixLen, e); 144 return false; 145 } 146 return true; 147 } 148 149 public boolean clearAllAddresses() { 150 try { 151 mNMS.clearInterfaceAddresses(mIfName); 152 } catch (Exception e) { 153 logError("Failed to clear addresses: %s", e); 154 return false; 155 } 156 return true; 157 } 158 159 private void logError(String fmt, Object... args) { 160 mLog.e(String.format(fmt, args)); 161 } 162 } 163