blob: 32cf286527ae0b34501ba60e003d84d67e546bcd [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"
Paul Jensen38764952014-05-20 11:25:35 -040021#include "NetdClient.h"
22#include "resolv_netid.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023#include <utils/misc.h>
24#include <android_runtime/AndroidRuntime.h>
25#include <utils/Log.h>
26#include <arpa/inet.h>
Robert Greenwalt0216e612011-01-14 16:29:58 -080027#include <cutils/properties.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
29extern "C" {
Mike Lockwood0900f362009-07-10 17:24:07 -040030int ifc_enable(const char *ifname);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031int ifc_disable(const char *ifname);
Wink Saville8171e6f2011-07-07 16:17:06 -070032int ifc_reset_connections(const char *ifname, int reset_mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
Robert Greenwalt3c97f942013-01-09 16:28:19 -080034int dhcp_do_request(const char * const ifname,
Robert Greenwalt0216e612011-01-14 16:29:58 -080035 const char *ipaddr,
36 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070037 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080038 const char *dns[],
Robert Greenwalt0216e612011-01-14 16:29:58 -080039 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070040 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080041 const char *vendorInfo,
Dmitry Shmidtec905452013-07-24 17:42:56 -070042 const char *domains,
43 const char *mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070044
Robert Greenwalt3c97f942013-01-09 16:28:19 -080045int dhcp_do_request_renew(const char * const ifname,
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070046 const char *ipaddr,
47 const char *gateway,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070048 uint32_t *prefixLength,
Robert Greenwalt3c97f942013-01-09 16:28:19 -080049 const char *dns[],
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070050 const char *server,
Jeff Sharkey77b87ba2012-04-18 21:55:14 -070051 uint32_t *lease,
Robert Greenwalt8058f622012-11-09 10:52:27 -080052 const char *vendorInfo,
Dmitry Shmidtec905452013-07-24 17:42:56 -070053 const char *domains,
54 const char *mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056int dhcp_stop(const char *ifname);
57int dhcp_release_lease(const char *ifname);
58char *dhcp_get_errmsg();
59}
60
61#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
62
63namespace android {
64
65/*
66 * The following remembers the jfieldID's of the fields
67 * of the DhcpInfo Java object, so that we don't have
68 * to look them up every time.
69 */
70static struct fieldIds {
Robert Greenwalt4717c262012-10-31 14:32:53 -070071 jmethodID clear;
72 jmethodID setInterfaceName;
73 jmethodID addLinkAddress;
74 jmethodID addGateway;
75 jmethodID addDns;
Robert Greenwalt8058f622012-11-09 10:52:27 -080076 jmethodID setDomains;
Robert Greenwalt4717c262012-10-31 14:32:53 -070077 jmethodID setServerAddress;
78 jmethodID setLeaseDuration;
79 jmethodID setVendorInfo;
80} dhcpResultsFieldIds;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
Wink Saville8171e6f2011-07-07 16:17:06 -070082static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
83 jstring ifname, jint mask)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084{
85 int result;
86
87 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Wink Saville8171e6f2011-07-07 16:17:06 -070088
Steve Block5baa3a62011-12-20 16:23:08 +000089 ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
Wink Saville8171e6f2011-07-07 16:17:06 -070090 env, clazz, nameStr, mask);
91
92 result = ::ifc_reset_connections(nameStr, mask);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 env->ReleaseStringUTFChars(ifname, nameStr);
94 return (jint)result;
95}
96
Irfan Sheriff31be7cf2011-04-28 10:25:31 -070097static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
Robert Greenwalt4717c262012-10-31 14:32:53 -070098 jobject dhcpResults, bool renew)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099{
100 int result;
Robert Greenwalt0216e612011-01-14 16:29:58 -0800101 char ipaddr[PROPERTY_VALUE_MAX];
102 uint32_t prefixLength;
103 char gateway[PROPERTY_VALUE_MAX];
104 char dns1[PROPERTY_VALUE_MAX];
105 char dns2[PROPERTY_VALUE_MAX];
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800106 char dns3[PROPERTY_VALUE_MAX];
107 char dns4[PROPERTY_VALUE_MAX];
108 const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
Robert Greenwalt0216e612011-01-14 16:29:58 -0800109 char server[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 uint32_t lease;
Jeff Sharkey77b87ba2012-04-18 21:55:14 -0700111 char vendorInfo[PROPERTY_VALUE_MAX];
Robert Greenwalt8058f622012-11-09 10:52:27 -0800112 char domains[PROPERTY_VALUE_MAX];
Dmitry Shmidtec905452013-07-24 17:42:56 -0700113 char mtu[PROPERTY_VALUE_MAX];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114
115 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
Robert Greenwalt0216e612011-01-14 16:29:58 -0800116 if (nameStr == NULL) return (jboolean)false;
117
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700118 if (renew) {
119 result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
Dmitry Shmidtec905452013-07-24 17:42:56 -0700120 dns, server, &lease, vendorInfo, domains, mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700121 } else {
122 result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
Dmitry Shmidtec905452013-07-24 17:42:56 -0700123 dns, server, &lease, vendorInfo, domains, mtu);
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700124 }
Robert Greenwalt28cdf1d2013-03-15 10:48:46 -0700125 if (result != 0) {
Vinit Deshapndec249c2c2013-08-08 10:38:53 -0700126 ALOGD("dhcp_do_request failed : %s (%s)", nameStr, renew ? "renew" : "new");
Robert Greenwalt28cdf1d2013-03-15 10:48:46 -0700127 }
128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 env->ReleaseStringUTFChars(ifname, nameStr);
Brian Carlstrom46e18c112011-04-05 22:44:45 -0700130 if (result == 0) {
Robert Greenwalt4717c262012-10-31 14:32:53 -0700131 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700132
Robert Greenwalt4717c262012-10-31 14:32:53 -0700133 // set mIfaceName
134 // dhcpResults->setInterfaceName(ifname)
135 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
136
137 // set the linkAddress
138 // dhcpResults->addLinkAddress(inetAddress, prefixLength)
139 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
140 env->NewStringUTF(ipaddr), prefixLength);
141 }
142
143 if (result == 0) {
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700144 // set the gateway
Robert Greenwalt4717c262012-10-31 14:32:53 -0700145 // dhcpResults->addGateway(gateway)
146 result = env->CallBooleanMethod(dhcpResults,
147 dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
148 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700149
Robert Greenwalt4717c262012-10-31 14:32:53 -0700150 if (result == 0) {
151 // dhcpResults->addDns(new InetAddress(dns1))
152 result = env->CallBooleanMethod(dhcpResults,
153 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
154 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700155
Robert Greenwalt4717c262012-10-31 14:32:53 -0700156 if (result == 0) {
Robert Greenwalt8058f622012-11-09 10:52:27 -0800157 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
158 env->NewStringUTF(domains));
159
Robert Greenwalt4717c262012-10-31 14:32:53 -0700160 result = env->CallBooleanMethod(dhcpResults,
161 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
Robert Greenwalt3c97f942013-01-09 16:28:19 -0800162
163 if (result == 0) {
164 result = env->CallBooleanMethod(dhcpResults,
165 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
166 if (result == 0) {
167 result = env->CallBooleanMethod(dhcpResults,
168 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
169 }
170 }
Robert Greenwalt4717c262012-10-31 14:32:53 -0700171 }
Robert Greenwaltaa70f102011-04-28 14:28:50 -0700172
Robert Greenwalt4717c262012-10-31 14:32:53 -0700173 if (result == 0) {
174 // dhcpResults->setServerAddress(new InetAddress(server))
175 result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
Robert Greenwalt0216e612011-01-14 16:29:58 -0800176 env->NewStringUTF(server));
Robert Greenwalt4717c262012-10-31 14:32:53 -0700177 }
178
179 if (result == 0) {
180 // dhcpResults->setLeaseDuration(lease)
181 env->CallVoidMethod(dhcpResults,
182 dhcpResultsFieldIds.setLeaseDuration, lease);
183
184 // dhcpResults->setVendorInfo(vendorInfo)
185 env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
186 env->NewStringUTF(vendorInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 }
188 return (jboolean)(result == 0);
189}
190
Robert Greenwalt4717c262012-10-31 14:32:53 -0700191
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700192static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
193{
194 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
195}
196
Paul Jensen32a58f02014-06-20 13:58:14 -0400197static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname,
198 jobject info)
Irfan Sheriff31be7cf2011-04-28 10:25:31 -0700199{
200 return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
201}
202
203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
205{
206 int result;
207
208 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
209 result = ::dhcp_stop(nameStr);
210 env->ReleaseStringUTFChars(ifname, nameStr);
211 return (jboolean)(result == 0);
212}
213
214static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
215{
216 int result;
217
218 const char *nameStr = env->GetStringUTFChars(ifname, NULL);
219 result = ::dhcp_release_lease(nameStr);
220 env->ReleaseStringUTFChars(ifname, nameStr);
221 return (jboolean)(result == 0);
222}
223
224static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
225{
226 return env->NewStringUTF(::dhcp_get_errmsg());
227}
228
Paul Jensen32a58f02014-06-20 13:58:14 -0400229static jboolean android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
Paul Jensen38764952014-05-20 11:25:35 -0400230{
Paul Jensen32a58f02014-06-20 13:58:14 -0400231 return (jboolean) !setNetworkForProcess(netId);
Paul Jensen38764952014-05-20 11:25:35 -0400232}
233
Paul Jensen38764952014-05-20 11:25:35 -0400234static jint android_net_utils_getNetworkBoundToProcess(JNIEnv *env, jobject thiz)
235{
236 return getNetworkForProcess();
237}
238
Paul Jensen32a58f02014-06-20 13:58:14 -0400239static jboolean android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz,
240 jint netId)
Paul Jensen38764952014-05-20 11:25:35 -0400241{
Paul Jensen32a58f02014-06-20 13:58:14 -0400242 return (jboolean) !setNetworkForResolv(netId);
Paul Jensen38764952014-05-20 11:25:35 -0400243}
244
Paul Jensen32a58f02014-06-20 13:58:14 -0400245static jboolean android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jint socket,
246 jint netId)
Paul Jensen38764952014-05-20 11:25:35 -0400247{
Paul Jensen32a58f02014-06-20 13:58:14 -0400248 return (jboolean) !setNetworkForSocket(netId, socket);
Paul Jensen38764952014-05-20 11:25:35 -0400249}
250
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400251static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket)
252{
253 return (jboolean) !protectFromVpn(socket);
254}
255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256// ----------------------------------------------------------------------------
257
258/*
259 * JNI registration.
260 */
261static JNINativeMethod gNetworkUtilMethods[] = {
262 /* name, signature, funcPtr */
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 },
Paul Jensen32a58f02014-06-20 13:58:14 -0400269 { "bindProcessToNetwork", "(I)Z", (void*) android_net_utils_bindProcessToNetwork },
Paul Jensen38764952014-05-20 11:25:35 -0400270 { "getNetworkBoundToProcess", "()I", (void*) android_net_utils_getNetworkBoundToProcess },
Paul Jensen32a58f02014-06-20 13:58:14 -0400271 { "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
Paul Jensen32a58f02014-06-20 13:58:14 -0400272 { "bindSocketToNetwork", "(II)Z", (void*) android_net_utils_bindSocketToNetwork },
Paul Jensen6bc2c2c2014-05-07 15:27:40 -0400273 { "protectFromVpn", "(I)Z", (void*)android_net_utils_protectFromVpn },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274};
275
276int register_android_net_NetworkUtils(JNIEnv* env)
277{
Robert Greenwalt4717c262012-10-31 14:32:53 -0700278 jclass dhcpResultsClass = env->FindClass("android/net/DhcpResults");
279 LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
280 dhcpResultsFieldIds.clear =
281 env->GetMethodID(dhcpResultsClass, "clear", "()V");
282 dhcpResultsFieldIds.setInterfaceName =
283 env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
284 dhcpResultsFieldIds.addLinkAddress =
285 env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
286 dhcpResultsFieldIds.addGateway =
287 env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
288 dhcpResultsFieldIds.addDns =
289 env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
Robert Greenwalt8058f622012-11-09 10:52:27 -0800290 dhcpResultsFieldIds.setDomains =
291 env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
Robert Greenwalt4717c262012-10-31 14:32:53 -0700292 dhcpResultsFieldIds.setServerAddress =
293 env->GetMethodID(dhcpResultsClass, "setServerAddress", "(Ljava/lang/String;)Z");
294 dhcpResultsFieldIds.setLeaseDuration =
295 env->GetMethodID(dhcpResultsClass, "setLeaseDuration", "(I)V");
296 dhcpResultsFieldIds.setVendorInfo =
297 env->GetMethodID(dhcpResultsClass, "setVendorInfo", "(Ljava/lang/String;)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298
299 return AndroidRuntime::registerNativeMethods(env,
300 NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
301}
302
303}; // namespace android