blob: 526159f4f1544d6e96ae07e83e3564a3595c4f05 [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,
40 const char *domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070041
Robert Greenwalt3c97f942013-01-09 16:28:19 -080042int dhcp_do_request_renew(const char * const ifname,
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070043 const char *ipaddr,
44 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070045 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080046 const char *dns[],
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070047 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070048 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080049 const char *vendorInfo,
50 const char *domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052int dhcp_stop(const char *ifname);
53int dhcp_release_lease(const char *ifname);
54char *dhcp_get_errmsg();
55}
56
57#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
58
59namespace android {
60
61/*
62 * The following remembers the jfieldID's of the fields
63 * of the DhcpInfo Java object, so that we don't have
64 * to look them up every time.
65 */
66static struct fieldIds {
Robert Greenwalt4717c262012-10-31 14:32:53 -070067 jmethodID clear;
68 jmethodID setInterfaceName;
69 jmethodID addLinkAddress;
70 jmethodID addGateway;
71 jmethodID addDns;
Robert Greenwalt8058f622012-11-09 10:52:27 -080072 jmethodID setDomains;
Robert Greenwalt4717c262012-10-31 14:32:53 -070073 jmethodID setServerAddress;
74 jmethodID setLeaseDuration;
75 jmethodID setVendorInfo;
76} dhcpResultsFieldIds;
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
Wink Saville8171e6f2011-07-07 16:17:06 -070098static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
99 jstring ifname, jint mask)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100{
101 int result;
102
103 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Wink Saville8171e6f2011-07-07 16:17:06 -0700104
Steve Block5baa3a62011-12-20 16:23:08 +0000105 ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
Wink Saville8171e6f2011-07-07 16:17:06 -0700106 env, clazz, nameStr, mask);
107
108 result = ::ifc_reset_connections(nameStr, mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 env->ReleaseStringUTFChars(ifname, nameStr);
110 return (jint)result;
111}
112
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700113static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
Robert Greenwalt4717c262012-10-31 14:32:53 -0700114 jobject dhcpResults, bool renew)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115{
116 int result;
Robert Greenwalt0216e612011-01-14 16:29:58 -0800117 char ipaddr[PROPERTY_VALUE_MAX];
118 uint32_t prefixLength;
119 char gateway[PROPERTY_VALUE_MAX];
120 char dns1[PROPERTY_VALUE_MAX];
121 char dns2[PROPERTY_VALUE_MAX];
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800122 char dns3[PROPERTY_VALUE_MAX];
123 char dns4[PROPERTY_VALUE_MAX];
124 const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
Robert Greenwalt0216e612011-01-14 16:29:58 -0800125 char server[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 uint32_t lease;
Jeff Sharkey77b87ba2012-04-18 21:55:14 -0700127 char vendorInfo[PROPERTY_VALUE_MAX];
Robert Greenwalt8058f622012-11-09 10:52:27 -0800128 char domains[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129
130 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800131 if (nameStr == NULL) return (jboolean)false;
132
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700133 if (renew) {
134 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800135 dns, server, &lease, vendorInfo, domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700136 } else {
137 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800138 dns, server, &lease, vendorInfo, domains);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700139 }
Robert Greenwalt28cdf1d2013-03-15 10:48:46 -0700140 if (result != 0) {
141 ALOGD("dhcp_do_request failed");
142 }
143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 env->ReleaseStringUTFChars(ifname, nameStr);
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700145 if (result == 0) {
Robert Greenwalt4717c262012-10-31 14:32:53 -0700146 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700147
Robert Greenwalt4717c262012-10-31 14:32:53 -0700148 // set mIfaceName
149 // dhcpResults->setInterfaceName(ifname)
150 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
151
152 // set the linkAddress
153 // dhcpResults->addLinkAddress(inetAddress, prefixLength)
154 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
155 env->NewStringUTF(ipaddr), prefixLength);
156 }
157
158 if (result == 0) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700159 // set the gateway
Robert Greenwalt4717c262012-10-31 14:32:53 -0700160 // dhcpResults->addGateway(gateway)
161 result = env->CallBooleanMethod(dhcpResults,
162 dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
163 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700164
Robert Greenwalt4717c262012-10-31 14:32:53 -0700165 if (result == 0) {
166 // dhcpResults->addDns(new InetAddress(dns1))
167 result = env->CallBooleanMethod(dhcpResults,
168 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
169 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700170
Robert Greenwalt4717c262012-10-31 14:32:53 -0700171 if (result == 0) {
Robert Greenwalt8058f622012-11-09 10:52:27 -0800172 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
173 env->NewStringUTF(domains));
174
Robert Greenwalt4717c262012-10-31 14:32:53 -0700175 result = env->CallBooleanMethod(dhcpResults,
176 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800177
178 if (result == 0) {
179 result = env->CallBooleanMethod(dhcpResults,
180 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
181 if (result == 0) {
182 result = env->CallBooleanMethod(dhcpResults,
183 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
184 }
185 }
Robert Greenwalt4717c262012-10-31 14:32:53 -0700186 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700187
Robert Greenwalt4717c262012-10-31 14:32:53 -0700188 if (result == 0) {
189 // dhcpResults->setServerAddress(new InetAddress(server))
190 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
Robert Greenwalt0216e612011-01-14 16:29:58 -0800191 env->NewStringUTF(server));
Robert Greenwalt4717c262012-10-31 14:32:53 -0700192 }
193
194 if (result == 0) {
195 // dhcpResults->setLeaseDuration(lease)
196 env->CallVoidMethod(dhcpResults,
197 dhcpResultsFieldIds.setLeaseDuration, lease);
198
199 // dhcpResults->setVendorInfo(vendorInfo)
200 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
201 env->NewStringUTF(vendorInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 }
203 return (jboolean)(result == 0);
204}
205
Robert Greenwalt4717c262012-10-31 14:32:53 -0700206
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700207static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
208{
209 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
210}
211
212static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
213{
214 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
215}
216
217
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
219{
220 int result;
221
222 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
223 result = ::dhcp_stop(nameStr);
224 env->ReleaseStringUTFChars(ifname, nameStr);
225 return (jboolean)(result == 0);
226}
227
228static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
229{
230 int result;
231
232 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
233 result = ::dhcp_release_lease(nameStr);
234 env->ReleaseStringUTFChars(ifname, nameStr);
235 return (jboolean)(result == 0);
236}
237
238static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
239{
240 return env->NewStringUTF(::dhcp_get_errmsg());
241}
242
Chad Brubaker12324b42013-07-11 13:30:36 -0700243static void android_net_utils_markSocket(JNIEnv *env, jobject thiz, jint socket, jint mark)
244{
245 if (setsockopt(socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
246 jniThrowException(env, "java/lang/IllegalStateException", "Error marking socket");
247 }
248}
249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250// ----------------------------------------------------------------------------
251
252/*
253 * JNI registration.
254 */
255static JNINativeMethod gNetworkUtilMethods[] = {
256 /* name, signature, funcPtr */
257
Mike Lockwood0900f362009-07-10 17:24:07 -0400258 { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
Wink Saville8171e6f2011-07-07 16:17:06 -0700260 { "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
Robert Greenwalt4717c262012-10-31 14:32:53 -0700261 { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcp },
262 { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcpRenew },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 { "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
264 { "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
Chad Brubaker12324b42013-07-11 13:30:36 -0700266 { "markSocket", "(II)V", (void*) android_net_utils_markSocket },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267};
268
269int register_android_net_NetworkUtils(JNIEnv* env)
270{
Robert Greenwalt4717c262012-10-31 14:32:53 -0700271 jclass dhcpResultsClass = env->FindClass("android/net/DhcpResults");
272 LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
273 dhcpResultsFieldIds.clear =
274 env->GetMethodID(dhcpResultsClass, "clear", "()V");
275 dhcpResultsFieldIds.setInterfaceName =
276 env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
277 dhcpResultsFieldIds.addLinkAddress =
278 env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
279 dhcpResultsFieldIds.addGateway =
280 env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
281 dhcpResultsFieldIds.addDns =
282 env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
Robert Greenwalt8058f622012-11-09 10:52:27 -0800283 dhcpResultsFieldIds.setDomains =
284 env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
Robert Greenwalt4717c262012-10-31 14:32:53 -0700285 dhcpResultsFieldIds.setServerAddress =
286 env->GetMethodID(dhcpResultsClass, "setServerAddress", "(Ljava/lang/String;)Z");
287 dhcpResultsFieldIds.setLeaseDuration =
288 env->GetMethodID(dhcpResultsClass, "setLeaseDuration", "(I)V");
289 dhcpResultsFieldIds.setVendorInfo =
290 env->GetMethodID(dhcpResultsClass, "setVendorInfo", "(Ljava/lang/String;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291
292 return AndroidRuntime::registerNativeMethods(env,
293 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
294}
295
296}; // namespace android