blob: 724d9fb74ac6e78cfa0626228f72ee0ce16023ff [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright 2008, The Android Open Source Project
3 *
Elliott Hughesdd66bcb2011-04-12 11:28:59 -07004 * 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007 *
Elliott Hughesdd66bcb2011-04-12 11:28:59 -07008 * http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009 *
Elliott Hughesdd66bcb2011-04-12 11:28:59 -070010 * 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014 * 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);
Wink Saville8171e6f2011-07-07 16:17:06 -070029int ifc_reset_connections(const char *ifname, int reset_mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31int dhcp_do_request(const char *ifname,
Robert Greenwalt0216e612011-01-14 16:29:58 -080032 const char *ipaddr,
33 const char *gateway,
34 uint32_t *prefixLength,
35 const char *dns1,
36 const char *dns2,
37 const char *server,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038 uint32_t *lease);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070039
40int dhcp_do_request_renew(const char *ifname,
41 const char *ipaddr,
42 const char *gateway,
43 uint32_t *prefixLength,
44 const char *dns1,
45 const char *dns2,
46 const char *server,
47 uint32_t *lease);
48
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049int dhcp_stop(const char *ifname);
50int dhcp_release_lease(const char *ifname);
51char *dhcp_get_errmsg();
52}
53
54#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
55
56namespace android {
57
58/*
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.
62 */
63static struct fieldIds {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 jmethodID constructorId;
65 jfieldID ipaddress;
Robert Greenwalt0216e612011-01-14 16:29:58 -080066 jfieldID prefixLength;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 jfieldID dns1;
68 jfieldID dns2;
69 jfieldID serverAddress;
70 jfieldID leaseDuration;
Robert Greenwalt0216e612011-01-14 16:29:58 -080071} dhcpInfoInternalFieldIds;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072
Mike Lockwood0900f362009-07-10 17:24:07 -040073static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
74{
75 int result;
76
77 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
78 result = ::ifc_enable(nameStr);
79 env->ReleaseStringUTFChars(ifname, nameStr);
80 return (jint)result;
81}
82
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
84{
85 int result;
86
87 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
88 result = ::ifc_disable(nameStr);
89 env->ReleaseStringUTFChars(ifname, nameStr);
90 return (jint)result;
91}
92
Wink Saville8171e6f2011-07-07 16:17:06 -070093static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
94 jstring ifname, jint mask)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095{
96 int result;
97
98 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Wink Saville8171e6f2011-07-07 16:17:06 -070099
Steve Block5baa3a62011-12-20 16:23:08 +0000100 ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
Wink Saville8171e6f2011-07-07 16:17:06 -0700101 env, clazz, nameStr, mask);
102
103 result = ::ifc_reset_connections(nameStr, mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 env->ReleaseStringUTFChars(ifname, nameStr);
105 return (jint)result;
106}
107
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700108static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
109 jobject info, bool renew)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110{
111 int result;
Robert Greenwalt0216e612011-01-14 16:29:58 -0800112 char ipaddr[PROPERTY_VALUE_MAX];
113 uint32_t prefixLength;
114 char gateway[PROPERTY_VALUE_MAX];
115 char dns1[PROPERTY_VALUE_MAX];
116 char dns2[PROPERTY_VALUE_MAX];
117 char server[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 uint32_t lease;
119
120 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800121 if (nameStr == NULL) return (jboolean)false;
122
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700123 if (renew) {
124 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
125 dns1, dns2, server, &lease);
126 } else {
127 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
128 dns1, dns2, server, &lease);
129 }
130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 env->ReleaseStringUTFChars(ifname, nameStr);
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700132 if (result == 0) {
Robert Greenwalt0216e612011-01-14 16:29:58 -0800133 env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700134
135 // set the gateway
136 jclass cls = env->FindClass("java/net/InetAddress");
137 jmethodID method = env->GetStaticMethodID(cls, "getByName",
138 "(Ljava/lang/String;)Ljava/net/InetAddress;");
139 jvalue args[1];
140 args[0].l = env->NewStringUTF(gateway);
141 jobject inetAddressObject = env->CallStaticObjectMethodA(cls, method, args);
142
143 if (!env->ExceptionOccurred()) {
144 cls = env->FindClass("android/net/RouteInfo");
145 method = env->GetMethodID(cls, "<init>", "(Ljava/net/InetAddress;)V");
146 args[0].l = inetAddressObject;
147 jobject routeInfoObject = env->NewObjectA(cls, method, args);
148
149 cls = env->FindClass("android/net/DhcpInfoInternal");
150 method = env->GetMethodID(cls, "addRoute", "(Landroid/net/RouteInfo;)V");
151 args[0].l = routeInfoObject;
152 env->CallVoidMethodA(info, method, args);
153 } else {
154 // if we have an exception (host not found perhaps), just don't add the route
155 env->ExceptionClear();
156 }
157
Robert Greenwalt0216e612011-01-14 16:29:58 -0800158 env->SetIntField(info, dhcpInfoInternalFieldIds.prefixLength, prefixLength);
159 env->SetObjectField(info, dhcpInfoInternalFieldIds.dns1, env->NewStringUTF(dns1));
160 env->SetObjectField(info, dhcpInfoInternalFieldIds.dns2, env->NewStringUTF(dns2));
161 env->SetObjectField(info, dhcpInfoInternalFieldIds.serverAddress,
162 env->NewStringUTF(server));
163 env->SetIntField(info, dhcpInfoInternalFieldIds.leaseDuration, lease);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 }
165 return (jboolean)(result == 0);
166}
167
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700168static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
169{
170 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
171}
172
173static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
174{
175 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
176}
177
178
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800179static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
180{
181 int result;
182
183 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
184 result = ::dhcp_stop(nameStr);
185 env->ReleaseStringUTFChars(ifname, nameStr);
186 return (jboolean)(result == 0);
187}
188
189static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
190{
191 int result;
192
193 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
194 result = ::dhcp_release_lease(nameStr);
195 env->ReleaseStringUTFChars(ifname, nameStr);
196 return (jboolean)(result == 0);
197}
198
199static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
200{
201 return env->NewStringUTF(::dhcp_get_errmsg());
202}
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204// ----------------------------------------------------------------------------
205
206/*
207 * JNI registration.
208 */
209static JNINativeMethod gNetworkUtilMethods[] = {
210 /* name, signature, funcPtr */
211
Mike Lockwood0900f362009-07-10 17:24:07 -0400212 { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
Wink Saville8171e6f2011-07-07 16:17:06 -0700214 { "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
Robert Greenwalt0216e612011-01-14 16:29:58 -0800215 { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcp },
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700216 { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)Z", (void *)android_net_utils_runDhcpRenew },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217 { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
218 { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
220};
221
222int register_android_net_NetworkUtils(JNIEnv* env)
223{
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700224 jclass dhcpInfoInternalClass = env->FindClass("android/net/DhcpInfoInternal");
225 LOG_FATAL_IF(dhcpInfoInternalClass == NULL, "Unable to find class android/net/DhcpInfoInternal");
226 dhcpInfoInternalFieldIds.constructorId = env->GetMethodID(dhcpInfoInternalClass, "<init>", "()V");
227 dhcpInfoInternalFieldIds.ipaddress = env->GetFieldID(dhcpInfoInternalClass, "ipAddress", "Ljava/lang/String;");
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700228 dhcpInfoInternalFieldIds.prefixLength = env->GetFieldID(dhcpInfoInternalClass, "prefixLength", "I");
229 dhcpInfoInternalFieldIds.dns1 = env->GetFieldID(dhcpInfoInternalClass, "dns1", "Ljava/lang/String;");
230 dhcpInfoInternalFieldIds.dns2 = env->GetFieldID(dhcpInfoInternalClass, "dns2", "Ljava/lang/String;");
231 dhcpInfoInternalFieldIds.serverAddress = env->GetFieldID(dhcpInfoInternalClass, "serverAddress", "Ljava/lang/String;");
232 dhcpInfoInternalFieldIds.leaseDuration = env->GetFieldID(dhcpInfoInternalClass, "leaseDuration", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233
234 return AndroidRuntime::registerNativeMethods(env,
235 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
236}
237
238}; // namespace android