diff --git a/staticlibs/device/com/android/net/module/util/ServiceConnectivityJni.java b/staticlibs/device/com/android/net/module/util/ServiceConnectivityJni.java index 1d3561afb5..24599b3d01 100644 --- a/staticlibs/device/com/android/net/module/util/ServiceConnectivityJni.java +++ b/staticlibs/device/com/android/net/module/util/ServiceConnectivityJni.java @@ -49,6 +49,15 @@ public class ServiceConnectivityJni { */ public static native void setTimerFdTime(int fd, long timeMs) throws ErrnoException; + /** + * Get the driver name for a given interface using the ethtool API. + * + * @param ifname name of the interface to query. + * @return the name of the driver. + * @throws ErrnoException if ioctl() returns -1. + */ + public static native String getDriverNameForInterface(String ifname) throws ErrnoException; + /** Create tun/tap interface */ public static native int createTunTap(boolean isTun, boolean hasCarrier, boolean setIffMulticast, @NonNull String iface); diff --git a/staticlibs/native/serviceconnectivityjni/com_android_net_module_util_ServiceConnectivityJni.cpp b/staticlibs/native/serviceconnectivityjni/com_android_net_module_util_ServiceConnectivityJni.cpp index 87675891eb..7e9b35029b 100644 --- a/staticlibs/native/serviceconnectivityjni/com_android_net_module_util_ServiceConnectivityJni.cpp +++ b/staticlibs/native/serviceconnectivityjni/com_android_net_module_util_ServiceConnectivityJni.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -80,6 +81,31 @@ static void setTimerFdTime(JNIEnv *env, jclass clazz, jint tfd, } } +static jstring getDriverNameForInterface(JNIEnv *env, jclass clazz, jstring jifname) { + base::unique_fd fd(socket(AF_INET6, SOCK_DGRAM, 0)); + if (!fd.ok()) { + jniThrowErrnoException(env, "getDriverNameForInterface", errno); + return nullptr; + } + + ScopedUtfChars ifname(env, jifname); + if (!ifname.c_str()) { + jniThrowNullPointerException(env, "getDriverNameForInterface: ifname is null"); + return nullptr; + } + + ethtool_drvinfo msg = { .cmd = ETHTOOL_GDRVINFO }; + ifreq ifr = { .ifr_data = reinterpret_cast(&msg) }; + strlcpy(ifr.ifr_name, ifname.c_str(), IFNAMSIZ); + + if (ioctl(fd, SIOCETHTOOL, &ifr)) { + jniThrowErrnoException(env, "getDriverNameForInterface", errno); + return nullptr; + } + + return env->NewStringUTF(msg.driver); +} + static void throwException(JNIEnv *env, int error, const char *action, const char *iface) { const std::string &msg = "Error: " + std::string(action) + " " + @@ -195,6 +221,8 @@ static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"createTimerFd", "()I", (void *)createTimerFd}, {"setTimerFdTime", "(IJ)V", (void *)setTimerFdTime}, + {"getDriverNameForInterface", "(Ljava/lang/String;)Ljava/lang/String;", + (void *)getDriverNameForInterface}, {"setTunTapCarrierEnabled", "(Ljava/lang/String;IZ)V", (void *)setTunTapCarrierEnabled}, {"createTunTap", "(ZZZLjava/lang/String;)I", (void *)createTunTap},