blob: 904eaf918fcef14ba14b7974f98dea187b7dcea5 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright 2008, 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#define LOG_TAG "NetUtils"
18
19#include "jni.h"
20#include <utils/misc.h>
21#include <android_runtime/AndroidRuntime.h>
22#include <utils/Log.h>
23#include <arpa/inet.h>
Robert Greenwalt0216e612011-01-14 16:29:58 -080024#include <cutils/properties.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025
26extern "C" {
Mike Lockwood0900f362009-07-10 17:24:07 -040027int ifc_enable(const char *ifname);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028int ifc_disable(const char *ifname);
Robert Greenwalt585ac0f2010-08-27 09:24:29 -070029int ifc_add_route(const char *ifname, const char *destStr, uint32_t prefixLen, const char *gwStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030int ifc_remove_host_routes(const char *ifname);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031int ifc_get_default_route(const char *ifname);
32int ifc_remove_default_route(const char *ifname);
33int ifc_reset_connections(const char *ifname);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034
35int dhcp_do_request(const char *ifname,
Robert Greenwalt0216e612011-01-14 16:29:58 -080036 const char *ipaddr,
37 const char *gateway,
38 uint32_t *prefixLength,
39 const char *dns1,
40 const char *dns2,
41 const char *server,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042 uint32_t *lease);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070043
44int dhcp_do_request_renew(const char *ifname,
45 const char *ipaddr,
46 const char *gateway,
47 uint32_t *prefixLength,
48 const char *dns1,
49 const char *dns2,
50 const char *server,
51 uint32_t *lease);
52
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053int dhcp_stop(const char *ifname);
54int dhcp_release_lease(const char *ifname);
55char *dhcp_get_errmsg();
56}
57
58#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
59
60namespace android {
61
62/*
63 * The following remembers the jfieldID's of the fields
64 * of the DhcpInfo Java object, so that we don't have
65 * to look them up every time.
66 */
67static struct fieldIds {
Robert Greenwalt0216e612011-01-14 16:29:58 -080068 jclass dhcpInfoInternalClass;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069 jmethodID constructorId;
70 jfieldID ipaddress;
Robert Greenwalt0216e612011-01-14 16:29:58 -080071 jfieldID prefixLength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 jfieldID dns1;
73 jfieldID dns2;
74 jfieldID serverAddress;
75 jfieldID leaseDuration;
Robert Greenwalt0216e612011-01-14 16:29:58 -080076} dhcpInfoInternalFieldIds;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
Mike Lockwood0900f362009-07-10 17:24:07 -040078static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
79{
80 int result;
81
82 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
83 result = ::ifc_enable(nameStr);
84 env->ReleaseStringUTFChars(ifname, nameStr);
85 return (jint)result;
86}
87
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
89{
90 int result;
91
92 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
93 result = ::ifc_disable(nameStr);
94 env->ReleaseStringUTFChars(ifname, nameStr);
95 return (jint)result;
96}
97
Robert Greenwalt585ac0f2010-08-27 09:24:29 -070098static jint android_net_utils_addRoute(JNIEnv* env, jobject clazz, jstring ifname,
99 jstring dst, jint prefixLength, jstring gw)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100{
101 int result;
102
103 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt585ac0f2010-08-27 09:24:29 -0700104 const char *dstStr = env->GetStringUTFChars(dst, NULL);
105 const char *gwStr = NULL;
106 if (gw != NULL) {
107 gwStr = env->GetStringUTFChars(gw, NULL);
108 }
109 result = ::ifc_add_route(nameStr, dstStr, prefixLength, gwStr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 env->ReleaseStringUTFChars(ifname, nameStr);
Robert Greenwalt585ac0f2010-08-27 09:24:29 -0700111 env->ReleaseStringUTFChars(dst, dstStr);
112 if (gw != NULL) {
113 env->ReleaseStringUTFChars(gw, gwStr);
114 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115 return (jint)result;
116}
117
118static jint android_net_utils_removeHostRoutes(JNIEnv* env, jobject clazz, jstring ifname)
119{
120 int result;
121
122 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
123 result = ::ifc_remove_host_routes(nameStr);
124 env->ReleaseStringUTFChars(ifname, nameStr);
125 return (jint)result;
126}
127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128static jint android_net_utils_getDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
129{
130 int result;
131
132 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
133 result = ::ifc_get_default_route(nameStr);
134 env->ReleaseStringUTFChars(ifname, nameStr);
135 return (jint)result;
136}
137
138static jint android_net_utils_removeDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
139{
140 int result;
141
142 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
143 result = ::ifc_remove_default_route(nameStr);
144 env->ReleaseStringUTFChars(ifname, nameStr);
145 return (jint)result;
146}
147
148static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstring ifname)
149{
150 int result;
151
152 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
153 result = ::ifc_reset_connections(nameStr);
154 env->ReleaseStringUTFChars(ifname, nameStr);
155 return (jint)result;
156}
157
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700158static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
159 jobject info, bool renew)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160{
161 int result;
Robert Greenwalt0216e612011-01-14 16:29:58 -0800162 char ipaddr[PROPERTY_VALUE_MAX];
163 uint32_t prefixLength;
164 char gateway[PROPERTY_VALUE_MAX];
165 char dns1[PROPERTY_VALUE_MAX];
166 char dns2[PROPERTY_VALUE_MAX];
167 char server[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 uint32_t lease;
169
170 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800171 if (nameStr == NULL) return (jboolean)false;
172
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700173 if (renew) {
174 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
175 dns1, dns2, server, &lease);
176 } else {
177 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
178 dns1, dns2, server, &lease);
179 }
180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800181 env->ReleaseStringUTFChars(ifname, nameStr);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800182 if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
183 env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700184
185 // set the gateway
186 jclass cls = env->FindClass("java/net/InetAddress");
187 jmethodID method = env->GetStaticMethodID(cls, "getByName",
188 "(Ljava/lang/String;)Ljava/net/InetAddress;");
189 jvalue args[1];
190 args[0].l = env->NewStringUTF(gateway);
191 jobject inetAddressObject = env->CallStaticObjectMethodA(cls, method, args);
192
193 if (!env->ExceptionOccurred()) {
194 cls = env->FindClass("android/net/RouteInfo");
195 method = env->GetMethodID(cls, "<init>", "(Ljava/net/InetAddress;)V");
196 args[0].l = inetAddressObject;
197 jobject routeInfoObject = env->NewObjectA(cls, method, args);
198
199 cls = env->FindClass("android/net/DhcpInfoInternal");
200 method = env->GetMethodID(cls, "addRoute", "(Landroid/net/RouteInfo;)V");
201 args[0].l = routeInfoObject;
202 env->CallVoidMethodA(info, method, args);
203 } else {
204 // if we have an exception (host not found perhaps), just don't add the route
205 env->ExceptionClear();
206 }
207
Robert Greenwalt0216e612011-01-14 16:29:58 -0800208 env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength);
209 env->SetObjectField(info, dhcpInfoInternalFieldIds.dns1, env->NewStringUTF(dns1));
210 env->SetObjectField(info, dhcpInfoInternalFieldIds.dns2, env->NewStringUTF(dns2));
211 env->SetObjectField(info, dhcpInfoInternalFieldIds.serverAddress,
212 env->NewStringUTF(server));
213 env->SetIntField(info, dhcpInfoInternalFieldIds.leaseDuration, lease);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 }
215 return (jboolean)(result == 0);
216}
217
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700218static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
219{
220 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
221}
222
223static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
224{
225 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
226}
227
228
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
230{
231 int result;
232
233 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
234 result = ::dhcp_stop(nameStr);
235 env->ReleaseStringUTFChars(ifname, nameStr);
236 return (jboolean)(result == 0);
237}
238
239static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
240{
241 int result;
242
243 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
244 result = ::dhcp_release_lease(nameStr);
245 env->ReleaseStringUTFChars(ifname, nameStr);
246 return (jboolean)(result == 0);
247}
248
249static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
250{
251 return env->NewStringUTF(::dhcp_get_errmsg());
252}
253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254// ----------------------------------------------------------------------------
255
256/*
257 * JNI registration.
258 */
259static JNINativeMethod gNetworkUtilMethods[] = {
260 /* name, signature, funcPtr */
261
Mike Lockwood0900f362009-07-10 17:24:07 -0400262 { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
Robert Greenwalt585ac0f2010-08-27 09:24:29 -0700264 { "addRoute", "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)I",
265 (void *)android_net_utils_addRoute },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 { "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes },
Robert Greenwalt585ac0f2010-08-27 09:24:29 -0700267 { "getDefaultRouteNative", "(Ljava/lang/String;)I",
268 (void *)android_net_utils_getDefaultRoute },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 { "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute },
270 { "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections },
Robert Greenwalt0216e612011-01-14 16:29:58 -0800271 { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcp },
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700272 { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcpRenew },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
274 { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
276};
277
278int register_android_net_NetworkUtils(JNIEnv* env)
279{
280 jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
281 LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
282
Robert Greenwalt0216e612011-01-14 16:29:58 -0800283 dhcpInfoInternalFieldIds.dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
284 if (dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
285 dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "<init>", "()V");
286 dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
Robert Greenwalt0216e612011-01-14 16:29:58 -0800287 dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "prefixLength", "I");
288 dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
289 dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
290 dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
291 dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalFieldIds.dhcpInfoInternalClass, "leaseDuration", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 }
293
294 return AndroidRuntime::registerNativeMethods(env,
295 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
296}
297
298}; // namespace android