blob: faae11ec3bb6b637c52e27c9ce063cb0f51bc83e [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
Robert Greenwalt3c97f942013-01-09 16:28:19 -080031int dhcp_do_request(const char * const ifname,
Robert Greenwalt0216e612011-01-14 16:29:58 -080032 const char *ipaddr,
33 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070034 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080035 const char *dns[],
Robert Greenwalt0216e612011-01-14 16:29:58 -080036 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070037 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080038 const char *vendorInfo,
39 const char *domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070040
Robert Greenwalt3c97f942013-01-09 16:28:19 -080041int dhcp_do_request_renew(const char * const ifname,
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070042 const char *ipaddr,
43 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070044 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080045 const char *dns[],
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070046 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070047 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080048 const char *vendorInfo,
49 const char *domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051int dhcp_stop(const char *ifname);
52int dhcp_release_lease(const char *ifname);
53char *dhcp_get_errmsg();
54}
55
56#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
57
58namespace android {
59
60/*
61 * The following remembers the jfieldID's of the fields
62 * of the DhcpInfo Java object, so that we don't have
63 * to look them up every time.
64 */
65static struct fieldIds {
Robert Greenwalt4717c262012-10-31 14:32:53 -070066 jmethodID clear;
67 jmethodID setInterfaceName;
68 jmethodID addLinkAddress;
69 jmethodID addGateway;
70 jmethodID addDns;
Robert Greenwalt8058f622012-11-09 10:52:27 -080071 jmethodID setDomains;
Robert Greenwalt4717c262012-10-31 14:32:53 -070072 jmethodID setServerAddress;
73 jmethodID setLeaseDuration;
74 jmethodID setVendorInfo;
75} dhcpResultsFieldIds;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
Mike Lockwood0900f362009-07-10 17:24:07 -040077static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
78{
79 int result;
80
81 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
82 result = ::ifc_enable(nameStr);
83 env->ReleaseStringUTFChars(ifname, nameStr);
84 return (jint)result;
85}
86
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
88{
89 int result;
90
91 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
92 result = ::ifc_disable(nameStr);
93 env->ReleaseStringUTFChars(ifname, nameStr);
94 return (jint)result;
95}
96
Wink Saville8171e6f2011-07-07 16:17:06 -070097static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
98 jstring ifname, jint mask)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099{
100 int result;
101
102 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Wink Saville8171e6f2011-07-07 16:17:06 -0700103
Steve Block5baa3a62011-12-20 16:23:08 +0000104 ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
Wink Saville8171e6f2011-07-07 16:17:06 -0700105 env, clazz, nameStr, mask);
106
107 result = ::ifc_reset_connections(nameStr, mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 env->ReleaseStringUTFChars(ifname, nameStr);
109 return (jint)result;
110}
111
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700112static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
Robert Greenwalt4717c262012-10-31 14:32:53 -0700113 jobject dhcpResults, bool renew)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114{
115 int result;
Robert Greenwalt0216e612011-01-14 16:29:58 -0800116 char ipaddr[PROPERTY_VALUE_MAX];
117 uint32_t prefixLength;
118 char gateway[PROPERTY_VALUE_MAX];
119 char dns1[PROPERTY_VALUE_MAX];
120 char dns2[PROPERTY_VALUE_MAX];
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800121 char dns3[PROPERTY_VALUE_MAX];
122 char dns4[PROPERTY_VALUE_MAX];
123 const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
Robert Greenwalt0216e612011-01-14 16:29:58 -0800124 char server[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 uint32_t lease;
Jeff Sharkey77b87ba2012-04-18 21:55:14 -0700126 char vendorInfo[PROPERTY_VALUE_MAX];
Robert Greenwalt8058f622012-11-09 10:52:27 -0800127 char domains[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128
129 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800130 if (nameStr == NULL) return (jboolean)false;
131
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700132 if (renew) {
133 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800134 dns, server, &lease, vendorInfo, domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700135 } else {
136 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800137 dns, server, &lease, vendorInfo, domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700138 }
Robert Greenwalt28cdf1d2013-03-15 10:48:46 -0700139 if (result != 0) {
140 ALOGD("dhcp_do_request failed");
141 }
142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 env->ReleaseStringUTFChars(ifname, nameStr);
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700144 if (result == 0) {
Robert Greenwalt4717c262012-10-31 14:32:53 -0700145 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700146
Robert Greenwalt4717c262012-10-31 14:32:53 -0700147 // set mIfaceName
148 // dhcpResults->setInterfaceName(ifname)
149 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
150
151 // set the linkAddress
152 // dhcpResults->addLinkAddress(inetAddress, prefixLength)
153 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
154 env->NewStringUTF(ipaddr), prefixLength);
155 }
156
157 if (result == 0) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700158 // set the gateway
Robert Greenwalt4717c262012-10-31 14:32:53 -0700159 // dhcpResults->addGateway(gateway)
160 result = env->CallBooleanMethod(dhcpResults,
161 dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
162 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700163
Robert Greenwalt4717c262012-10-31 14:32:53 -0700164 if (result == 0) {
165 // dhcpResults->addDns(new InetAddress(dns1))
166 result = env->CallBooleanMethod(dhcpResults,
167 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
168 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700169
Robert Greenwalt4717c262012-10-31 14:32:53 -0700170 if (result == 0) {
Robert Greenwalt8058f622012-11-09 10:52:27 -0800171 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
172 env->NewStringUTF(domains));
173
Robert Greenwalt4717c262012-10-31 14:32:53 -0700174 result = env->CallBooleanMethod(dhcpResults,
175 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800176
177 if (result == 0) {
178 result = env->CallBooleanMethod(dhcpResults,
179 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
180 if (result == 0) {
181 result = env->CallBooleanMethod(dhcpResults,
182 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
183 }
184 }
Robert Greenwalt4717c262012-10-31 14:32:53 -0700185 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700186
Robert Greenwalt4717c262012-10-31 14:32:53 -0700187 if (result == 0) {
188 // dhcpResults->setServerAddress(new InetAddress(server))
189 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
Robert Greenwalt0216e612011-01-14 16:29:58 -0800190 env->NewStringUTF(server));
Robert Greenwalt4717c262012-10-31 14:32:53 -0700191 }
192
193 if (result == 0) {
194 // dhcpResults->setLeaseDuration(lease)
195 env->CallVoidMethod(dhcpResults,
196 dhcpResultsFieldIds.setLeaseDuration, lease);
197
198 // dhcpResults->setVendorInfo(vendorInfo)
199 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
200 env->NewStringUTF(vendorInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 }
202 return (jboolean)(result == 0);
203}
204
Robert Greenwalt4717c262012-10-31 14:32:53 -0700205
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700206static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
207{
208 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
209}
210
211static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
212{
213 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
214}
215
216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
218{
219 int result;
220
221 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
222 result = ::dhcp_stop(nameStr);
223 env->ReleaseStringUTFChars(ifname, nameStr);
224 return (jboolean)(result == 0);
225}
226
227static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
228{
229 int result;
230
231 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
232 result = ::dhcp_release_lease(nameStr);
233 env->ReleaseStringUTFChars(ifname, nameStr);
234 return (jboolean)(result == 0);
235}
236
237static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
238{
239 return env->NewStringUTF(::dhcp_get_errmsg());
240}
241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242// ----------------------------------------------------------------------------
243
244/*
245 * JNI registration.
246 */
247static JNINativeMethod gNetworkUtilMethods[] = {
248 /* name, signature, funcPtr */
249
Mike Lockwood0900f362009-07-10 17:24:07 -0400250 { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
Wink Saville8171e6f2011-07-07 16:17:06 -0700252 { "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
Robert Greenwalt4717c262012-10-31 14:32:53 -0700253 { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcp },
254 { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcpRenew },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
256 { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
258};
259
260int register_android_net_NetworkUtils(JNIEnv* env)
261{
Robert Greenwalt4717c262012-10-31 14:32:53 -0700262 jclass dhcpResultsClass = env->FindClass("android/net/DhcpResults");
263 LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
264 dhcpResultsFieldIds.clear =
265 env->GetMethodID(dhcpResultsClass, "clear", "()V");
266 dhcpResultsFieldIds.setInterfaceName =
267 env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
268 dhcpResultsFieldIds.addLinkAddress =
269 env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
270 dhcpResultsFieldIds.addGateway =
271 env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
272 dhcpResultsFieldIds.addDns =
273 env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
Robert Greenwalt8058f622012-11-09 10:52:27 -0800274 dhcpResultsFieldIds.setDomains =
275 env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
Robert Greenwalt4717c262012-10-31 14:32:53 -0700276 dhcpResultsFieldIds.setServerAddress =
277 env->GetMethodID(dhcpResultsClass, "setServerAddress", "(Ljava/lang/String;)Z");
278 dhcpResultsFieldIds.setLeaseDuration =
279 env->GetMethodID(dhcpResultsClass, "setLeaseDuration", "(I)V");
280 dhcpResultsFieldIds.setVendorInfo =
281 env->GetMethodID(dhcpResultsClass, "setVendorInfo", "(Ljava/lang/String;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282
283 return AndroidRuntime::registerNativeMethods(env,
284 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
285}
286
287}; // namespace android