1 /*
2  * Copyright (C) 2019 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 package android.net;
17 
18 import android.annotation.NonNull;
19 import android.annotation.Nullable;
20 import android.annotation.SystemApi;
21 import android.os.Parcel;
22 import android.os.ParcelFileDescriptor;
23 import android.os.Parcelable;
24 import android.util.Log;
25 
26 import java.net.NetworkInterface;
27 import java.net.SocketException;
28 
29 /**
30  * This class is used to return the interface name, fd, MAC, and MTU of the test interface
31  *
32  * TestNetworkInterfaces are created by TestNetworkService and provide a
33  * wrapper around a tun/tap interface that can be used in integration tests.
34  *
35  * @hide
36  */
37 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
38 public final class TestNetworkInterface implements Parcelable {
39     private static final String TAG = "TestNetworkInterface";
40 
41     @NonNull
42     private final ParcelFileDescriptor mFileDescriptor;
43     @NonNull
44     private final String mInterfaceName;
45     @Nullable
46     private final MacAddress mMacAddress;
47     private final int mMtu;
48 
49     @Override
describeContents()50     public int describeContents() {
51         return (mFileDescriptor != null) ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
52     }
53 
54     @Override
writeToParcel(@onNull Parcel out, int flags)55     public void writeToParcel(@NonNull Parcel out, int flags) {
56         out.writeParcelable(mFileDescriptor, flags);
57         out.writeString(mInterfaceName);
58         out.writeParcelable(mMacAddress, flags);
59         out.writeInt(mMtu);
60     }
61 
TestNetworkInterface(@onNull ParcelFileDescriptor pfd, @NonNull String intf)62     public TestNetworkInterface(@NonNull ParcelFileDescriptor pfd, @NonNull String intf) {
63         mFileDescriptor = pfd;
64         mInterfaceName = intf;
65 
66         MacAddress macAddress = null;
67         int mtu = 1500;
68         try {
69             // This constructor is called by TestNetworkManager which runs inside the system server,
70             // which has permission to read the MacAddress.
71             NetworkInterface nif = NetworkInterface.getByName(mInterfaceName);
72 
73             // getHardwareAddress() returns null for tun interfaces.
74             byte[] hardwareAddress = nif.getHardwareAddress();
75             if (hardwareAddress != null) {
76                 macAddress = MacAddress.fromBytes(nif.getHardwareAddress());
77             }
78             mtu = nif.getMTU();
79         } catch (SocketException e) {
80             Log.e(TAG, "Failed to fetch MacAddress or MTU size from NetworkInterface", e);
81         }
82         mMacAddress = macAddress;
83         mMtu = mtu;
84     }
85 
TestNetworkInterface(@onNull Parcel in)86     private TestNetworkInterface(@NonNull Parcel in) {
87         mFileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
88         mInterfaceName = in.readString();
89         mMacAddress = in.readParcelable(MacAddress.class.getClassLoader());
90         mMtu = in.readInt();
91     }
92 
93     @NonNull
getFileDescriptor()94     public ParcelFileDescriptor getFileDescriptor() {
95         return mFileDescriptor;
96     }
97 
98     @NonNull
getInterfaceName()99     public String getInterfaceName() {
100         return mInterfaceName;
101     }
102 
103     /**
104      * Returns the tap interface MacAddress.
105      *
106      * When TestNetworkInterface wraps a tun interface, the MAC address is null.
107      *
108      * @return the tap interface MAC address or null.
109      */
110     @Nullable
getMacAddress()111     public MacAddress getMacAddress() {
112         return mMacAddress;
113     }
114 
115     /**
116      * Returns the interface MTU.
117      *
118      * MTU defaults to 1500 if an error occurs.
119      *
120      * @return MTU in bytes.
121      */
getMtu()122     public int getMtu() {
123         return mMtu;
124     }
125 
126     @NonNull
127     public static final Parcelable.Creator<TestNetworkInterface> CREATOR =
128             new Parcelable.Creator<TestNetworkInterface>() {
129                 public TestNetworkInterface createFromParcel(Parcel in) {
130                     return new TestNetworkInterface(in);
131                 }
132 
133                 public TestNetworkInterface[] newArray(int size) {
134                     return new TestNetworkInterface[size];
135                 }
136             };
137 }
138