Home | History | Annotate | Download | only in ip
      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