blob: 6d23c32b330ee87e2e0c4d62950cd06e7f97ff4a [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"
Chad Brubaker12324b42013-07-11 13:30:36 -070020#include "JNIHelp.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021#include <utils/misc.h>
22#include <android_runtime/AndroidRuntime.h>
23#include <utils/Log.h>
24#include <arpa/inet.h>
Robert Greenwalt0216e612011-01-14 16:29:58 -080025#include <cutils/properties.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026
27extern "C" {
Mike Lockwood0900f362009-07-10 17:24:07 -040028int ifc_enable(const char *ifname);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029int ifc_disable(const char *ifname);
Wink Saville8171e6f2011-07-07 16:17:06 -070030int ifc_reset_connections(const char *ifname, int reset_mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Robert Greenwalt3c97f942013-01-09 16:28:19 -080032int dhcp_do_request(const char * const ifname,
Robert Greenwalt0216e612011-01-14 16:29:58 -080033 const char *ipaddr,
34 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070035 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080036 const char *dns[],
Robert Greenwalt0216e612011-01-14 16:29:58 -080037 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070038 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080039 const char *vendorInfo,
Dmitry Shmidtec905452013-07-24 17:42:56 -070040 const char *domains,
41 const char *mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070042
Robert Greenwalt3c97f942013-01-09 16:28:19 -080043int dhcp_do_request_renew(const char * const ifname,
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070044 const char *ipaddr,
45 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070046 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080047 const char *dns[],
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070048 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070049 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080050 const char *vendorInfo,
Dmitry Shmidtec905452013-07-24 17:42:56 -070051 const char *domains,
52 const char *mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054int dhcp_stop(const char *ifname);
55int dhcp_release_lease(const char *ifname);
56char *dhcp_get_errmsg();
57}
58
59#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
60
61namespace android {
62
63/*
64 * The following remembers the jfieldID's of the fields
65 * of the DhcpInfo Java object, so that we don't have
66 * to look them up every time.
67 */
68static struct fieldIds {
Robert Greenwalt4717c262012-10-31 14:32:53 -070069 jmethodID clear;
70 jmethodID setInterfaceName;
71 jmethodID addLinkAddress;
72 jmethodID addGateway;
73 jmethodID addDns;
Robert Greenwalt8058f622012-11-09 10:52:27 -080074 jmethodID setDomains;
Robert Greenwalt4717c262012-10-31 14:32:53 -070075 jmethodID setServerAddress;
76 jmethodID setLeaseDuration;
77 jmethodID setVendorInfo;
78} dhcpResultsFieldIds;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Mike Lockwood0900f362009-07-10 17:24:07 -040080static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
81{
82 int result;
83
84 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
85 result = ::ifc_enable(nameStr);
86 env->ReleaseStringUTFChars(ifname, nameStr);
87 return (jint)result;
88}
89
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
91{
92 int result;
93
94 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
95 result = ::ifc_disable(nameStr);
96 env->ReleaseStringUTFChars(ifname, nameStr);
97 return (jint)result;
98}
99
Wink Saville8171e6f2011-07-07 16:17:06 -0700100static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
101 jstring ifname, jint mask)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102{
103 int result;
104
105 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Wink Saville8171e6f2011-07-07 16:17:06 -0700106
Steve Block5baa3a62011-12-20 16:23:08 +0000107 ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
Wink Saville8171e6f2011-07-07 16:17:06 -0700108 env, clazz, nameStr, mask);
109
110 result = ::ifc_reset_connections(nameStr, mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 env->ReleaseStringUTFChars(ifname, nameStr);
112 return (jint)result;
113}
114
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700115static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
Robert Greenwalt4717c262012-10-31 14:32:53 -0700116 jobject dhcpResults, bool renew)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117{
118 int result;
Robert Greenwalt0216e612011-01-14 16:29:58 -0800119 char ipaddr[PROPERTY_VALUE_MAX];
120 uint32_t prefixLength;
121 char gateway[PROPERTY_VALUE_MAX];
122 char dns1[PROPERTY_VALUE_MAX];
123 char dns2[PROPERTY_VALUE_MAX];
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800124 char dns3[PROPERTY_VALUE_MAX];
125 char dns4[PROPERTY_VALUE_MAX];
126 const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
Robert Greenwalt0216e612011-01-14 16:29:58 -0800127 char server[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 uint32_t lease;
Jeff Sharkey77b87ba2012-04-18 21:55:14 -0700129 char vendorInfo[PROPERTY_VALUE_MAX];
Robert Greenwalt8058f622012-11-09 10:52:27 -0800130 char domains[PROPERTY_VALUE_MAX];
Dmitry Shmidtec905452013-07-24 17:42:56 -0700131 char mtu[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132
133 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800134 if (nameStr == NULL) return (jboolean)false;
135
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700136 if (renew) {
137 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
Dmitry Shmidtec905452013-07-24 17:42:56 -0700138 dns, server, &lease, vendorInfo, domains, mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700139 } else {
140 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
Dmitry Shmidtec905452013-07-24 17:42:56 -0700141 dns, server, &lease, vendorInfo, domains, mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700142 }
Robert Greenwalt28cdf1d2013-03-15 10:48:46 -0700143 if (result != 0) {
Vinit Deshapndec249c2c2013-08-08 10:38:53 -0700144 ALOGD("dhcp_do_request failed : %s (%s)", nameStr, renew ? "renew" : "new");
Robert Greenwalt28cdf1d2013-03-15 10:48:46 -0700145 }
146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 env->ReleaseStringUTFChars(ifname, nameStr);
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700148 if (result == 0) {
Robert Greenwalt4717c262012-10-31 14:32:53 -0700149 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700150
Robert Greenwalt4717c262012-10-31 14:32:53 -0700151 // set mIfaceName
152 // dhcpResults->setInterfaceName(ifname)
153 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
154
155 // set the linkAddress
156 // dhcpResults->addLinkAddress(inetAddress, prefixLength)
157 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
158 env->NewStringUTF(ipaddr), prefixLength);
159 }
160
161 if (result == 0) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700162 // set the gateway
Robert Greenwalt4717c262012-10-31 14:32:53 -0700163 // dhcpResults->addGateway(gateway)
164 result = env->CallBooleanMethod(dhcpResults,
165 dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
166 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700167
Robert Greenwalt4717c262012-10-31 14:32:53 -0700168 if (result == 0) {
169 // dhcpResults->addDns(new InetAddress(dns1))
170 result = env->CallBooleanMethod(dhcpResults,
171 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
172 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700173
Robert Greenwalt4717c262012-10-31 14:32:53 -0700174 if (result == 0) {
Robert Greenwalt8058f622012-11-09 10:52:27 -0800175 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
176 env->NewStringUTF(domains));
177
Robert Greenwalt4717c262012-10-31 14:32:53 -0700178 result = env->CallBooleanMethod(dhcpResults,
179 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800180
181 if (result == 0) {
182 result = env->CallBooleanMethod(dhcpResults,
183 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
184 if (result == 0) {
185 result = env->CallBooleanMethod(dhcpResults,
186 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
187 }
188 }
Robert Greenwalt4717c262012-10-31 14:32:53 -0700189 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700190
Robert Greenwalt4717c262012-10-31 14:32:53 -0700191 if (result == 0) {
192 // dhcpResults->setServerAddress(new InetAddress(server))
193 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
Robert Greenwalt0216e612011-01-14 16:29:58 -0800194 env->NewStringUTF(server));
Robert Greenwalt4717c262012-10-31 14:32:53 -0700195 }
196
197 if (result == 0) {
198 // dhcpResults->setLeaseDuration(lease)
199 env->CallVoidMethod(dhcpResults,
200 dhcpResultsFieldIds.setLeaseDuration, lease);
201
202 // dhcpResults->setVendorInfo(vendorInfo)
203 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
204 env->NewStringUTF(vendorInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205 }
206 return (jboolean)(result == 0);
207}
208
Robert Greenwalt4717c262012-10-31 14:32:53 -0700209
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700210static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
211{
212 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
213}
214
215static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
216{
217 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
218}
219
220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
222{
223 int result;
224
225 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
226 result = ::dhcp_stop(nameStr);
227 env->ReleaseStringUTFChars(ifname, nameStr);
228 return (jboolean)(result == 0);
229}
230
231static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
232{
233 int result;
234
235 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
236 result = ::dhcp_release_lease(nameStr);
237 env->ReleaseStringUTFChars(ifname, nameStr);
238 return (jboolean)(result == 0);
239}
240
241static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
242{
243 return env->NewStringUTF(::dhcp_get_errmsg());
244}
245
Chad Brubaker12324b42013-07-11 13:30:36 -0700246static void android_net_utils_markSocket(JNIEnv *env, jobject thiz, jint socket, jint mark)
247{
248 if (setsockopt(socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
249 jniThrowException(env, "java/lang/IllegalStateException", "Error marking socket");
250 }
251}
252
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253// ----------------------------------------------------------------------------
254
255/*
256 * JNI registration.
257 */
258static JNINativeMethod gNetworkUtilMethods[] = {
259 /* name, signature, funcPtr */
260
Mike Lockwood0900f362009-07-10 17:24:07 -0400261 { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
Wink Saville8171e6f2011-07-07 16:17:06 -0700263 { "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
Robert Greenwalt4717c262012-10-31 14:32:53 -0700264 { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcp },
265 { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcpRenew },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
267 { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
Chad Brubaker12324b42013-07-11 13:30:36 -0700269 { "markSocket", "(II)V", (void*) android_net_utils_markSocket },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270};
271
272int register_android_net_NetworkUtils(JNIEnv* env)
273{
Robert Greenwalt4717c262012-10-31 14:32:53 -0700274 jclass dhcpResultsClass = env->FindClass("android/net/DhcpResults");
275 LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
276 dhcpResultsFieldIds.clear =
277 env->GetMethodID(dhcpResultsClass, "clear", "()V");
278 dhcpResultsFieldIds.setInterfaceName =
279 env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
280 dhcpResultsFieldIds.addLinkAddress =
281 env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
282 dhcpResultsFieldIds.addGateway =
283 env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
284 dhcpResultsFieldIds.addDns =
285 env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
Robert Greenwalt8058f622012-11-09 10:52:27 -0800286 dhcpResultsFieldIds.setDomains =
287 env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
Robert Greenwalt4717c262012-10-31 14:32:53 -0700288 dhcpResultsFieldIds.setServerAddress =
289 env->GetMethodID(dhcpResultsClass, "setServerAddress", "(Ljava/lang/String;)Z");
290 dhcpResultsFieldIds.setLeaseDuration =
291 env->GetMethodID(dhcpResultsClass, "setLeaseDuration", "(I)V");
292 dhcpResultsFieldIds.setVendorInfo =
293 env->GetMethodID(dhcpResultsClass, "setVendorInfo", "(Ljava/lang/String;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294
295 return AndroidRuntime::registerNativeMethods(env,
296 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
297}
298
299}; // namespace android