2 * Copyright 2008, The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "NetUtils"
20 #include <utils/misc.h>
21 #include <android_runtime/AndroidRuntime.h>
22 #include <utils/Log.h>
23 #include <arpa/inet.h>
24 #include <cutils/properties.h>
27 int ifc_enable(const char *ifname);
28 int ifc_disable(const char *ifname);
29 int ifc_reset_connections(const char *ifname, int reset_mask);
31 int dhcp_do_request(const char *ifname,
34 uint32_t *prefixLength,
40 int dhcp_do_request_renew(const char *ifname,
43 uint32_t *prefixLength,
49 int dhcp_stop(const char *ifname);
50 int dhcp_release_lease(const char *ifname);
51 char *dhcp_get_errmsg();
54 #define NETUTILS_PKG_NAME "android/net/NetworkUtils"
59 * The following remembers the jfieldID's of the fields
60 * of the DhcpInfo Java object, so that we don't have
61 * to look them up every time.
63 static struct fieldIds {
64 jclass dhcpInfoInternalClass;
65 jmethodID constructorId;
67 jfieldID prefixLength;
70 jfieldID serverAddress;
71 jfieldID leaseDuration;
72 } dhcpInfoInternalFieldIds;
74 static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
78 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
79 result = ::ifc_enable(nameStr);
80 env->ReleaseStringUTFChars(ifname, nameStr);
84 static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
88 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
89 result = ::ifc_disable(nameStr);
90 env->ReleaseStringUTFChars(ifname, nameStr);
94 static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
95 jstring ifname, jint mask)
99 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
101 LOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
102 env, clazz, nameStr, mask);
104 result = ::ifc_reset_connections(nameStr, mask);
105 env->ReleaseStringUTFChars(ifname, nameStr);
109 static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
110 jobject info, bool renew)
113 char ipaddr[PROPERTY_VALUE_MAX];
114 uint32_t prefixLength;
115 char gateway[PROPERTY_VALUE_MAX];
116 char dns1[PROPERTY_VALUE_MAX];
117 char dns2[PROPERTY_VALUE_MAX];
118 char server[PROPERTY_VALUE_MAX];
121 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
122 if (nameStr == NULL) return (jboolean)false;
125 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
126 dns1, dns2, server, &lease);
128 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
129 dns1, dns2, server, &lease);
132 env->ReleaseStringUTFChars(ifname, nameStr);
133 if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
134 env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
137 jclass cls = env->FindClass("java/net/InetAddress");
138 jmethodID method = env->GetStaticMethodID(cls, "getByName",
139 "(Ljava/lang/String;)Ljava/net/InetAddress;");
141 args[0].l = env->NewStringUTF(gateway);
142 jobject inetAddressObject = env->CallStaticObjectMethodA(cls, method, args);
144 if (!env->ExceptionOccurred()) {
145 cls = env->FindClass("android/net/RouteInfo");
146 method = env->GetMethodID(cls, "<init>", "(Ljava/net/InetAddress;)V");
147 args[0].l = inetAddressObject;
148 jobject routeInfoObject = env->NewObjectA(cls, method, args);
150 cls = env->FindClass("android/net/DhcpInfoInternal");
151 method = env->GetMethodID(cls, "addRoute", "(Landroid/net/RouteInfo;)V");
152 args[0].l = routeInfoObject;
153 env->CallVoidMethodA(info, method, args);
155 // if we have an exception (host not found perhaps), just don't add the route
156 env->ExceptionClear();
159 env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength);
160 env->SetObjectField(info, dhcpInfoInternalFieldIds.dns1, env->NewStringUTF(dns1));
161 env->SetObjectField(info, dhcpInfoInternalFieldIds.dns2, env->NewStringUTF(dns2));
162 env->SetObjectField(info, dhcpInfoInternalFieldIds.serverAddress,
163 env->NewStringUTF(server));
164 env->SetIntField(info, dhcpInfoInternalFieldIds.leaseDuration, lease);
166 return (jboolean)(result == 0);
169 static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
171 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
174 static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
176 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
180 static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
184 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
185 result = ::dhcp_stop(nameStr);
186 env->ReleaseStringUTFChars(ifname, nameStr);
187 return (jboolean)(result == 0);
190 static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
194 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
195 result = ::dhcp_release_lease(nameStr);
196 env->ReleaseStringUTFChars(ifname, nameStr);
197 return (jboolean)(result == 0);
200 static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
202 return env->NewStringUTF(::dhcp_get_errmsg());
205 // ----------------------------------------------------------------------------
210 static JNINativeMethod gNetworkUtilMethods[] = {
211 /* name, signature, funcPtr */
213 { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
214 { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
215 { "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
216 { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcp },
217 { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcpRenew },
218 { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
219 { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
220 { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
223 int register_android_net_NetworkUtils(JNIEnv* env)
225 jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
226 LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
228 dhcpInfoInternalFieldIds.dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
229 if (dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
230 dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "<init>", "()V");
231 dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
232 dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "prefixLength", "I");
233 dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
234 dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
235 dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
236 dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "leaseDuration", "I");
239 return AndroidRuntime::registerNativeMethods(env,
240 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
243 }; // namespace android