• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2008, The Android Open Source Project
3  *
4  * 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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * 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
14  * 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>
24 #include <cutils/properties.h>
25 
26 extern "C" {
27 int ifc_enable(const char *ifname);
28 int ifc_disable(const char *ifname);
29 int ifc_reset_connections(const char *ifname, int reset_mask);
30 
31 int dhcp_do_request(const char * const ifname,
32                     const char *ipaddr,
33                     const char *gateway,
34                     uint32_t *prefixLength,
35                     const char *dns[],
36                     const char *server,
37                     uint32_t *lease,
38                     const char *vendorInfo,
39                     const char *domains);
40 
41 int dhcp_do_request_renew(const char * const ifname,
42                     const char *ipaddr,
43                     const char *gateway,
44                     uint32_t *prefixLength,
45                     const char *dns[],
46                     const char *server,
47                     uint32_t *lease,
48                     const char *vendorInfo,
49                     const char *domains);
50 
51 int dhcp_stop(const char *ifname);
52 int dhcp_release_lease(const char *ifname);
53 char *dhcp_get_errmsg();
54 }
55 
56 #define NETUTILS_PKG_NAME "android/net/NetworkUtils"
57 
58 namespace 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  */
65 static struct fieldIds {
66     jmethodID clear;
67     jmethodID setInterfaceName;
68     jmethodID addLinkAddress;
69     jmethodID addGateway;
70     jmethodID addDns;
71     jmethodID setDomains;
72     jmethodID setServerAddress;
73     jmethodID setLeaseDuration;
74     jmethodID setVendorInfo;
75 } dhcpResultsFieldIds;
76 
android_net_utils_enableInterface(JNIEnv * env,jobject clazz,jstring ifname)77 static 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 
android_net_utils_disableInterface(JNIEnv * env,jobject clazz,jstring ifname)87 static 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 
android_net_utils_resetConnections(JNIEnv * env,jobject clazz,jstring ifname,jint mask)97 static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
98       jstring ifname, jint mask)
99 {
100     int result;
101 
102     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
103 
104     ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
105           env, clazz, nameStr, mask);
106 
107     result = ::ifc_reset_connections(nameStr, mask);
108     env->ReleaseStringUTFChars(ifname, nameStr);
109     return (jint)result;
110 }
111 
android_net_utils_runDhcpCommon(JNIEnv * env,jobject clazz,jstring ifname,jobject dhcpResults,bool renew)112 static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
113         jobject dhcpResults, bool renew)
114 {
115     int result;
116     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];
121     char    dns3[PROPERTY_VALUE_MAX];
122     char    dns4[PROPERTY_VALUE_MAX];
123     const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
124     char  server[PROPERTY_VALUE_MAX];
125     uint32_t lease;
126     char vendorInfo[PROPERTY_VALUE_MAX];
127     char domains[PROPERTY_VALUE_MAX];
128 
129     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
130     if (nameStr == NULL) return (jboolean)false;
131 
132     if (renew) {
133         result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
134                 dns, server, &lease, vendorInfo, domains);
135     } else {
136         result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
137                 dns, server, &lease, vendorInfo, domains);
138     }
139     if (result != 0) {
140         ALOGD("dhcp_do_request failed");
141     }
142 
143     env->ReleaseStringUTFChars(ifname, nameStr);
144     if (result == 0) {
145         env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
146 
147         // 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) {
158         // set the gateway
159         // dhcpResults->addGateway(gateway)
160         result = env->CallBooleanMethod(dhcpResults,
161                 dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
162     }
163 
164     if (result == 0) {
165         // dhcpResults->addDns(new InetAddress(dns1))
166         result = env->CallBooleanMethod(dhcpResults,
167                 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
168     }
169 
170     if (result == 0) {
171         env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
172                 env->NewStringUTF(domains));
173 
174         result = env->CallBooleanMethod(dhcpResults,
175                 dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
176 
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         }
185     }
186 
187     if (result == 0) {
188         // dhcpResults->setServerAddress(new InetAddress(server))
189         result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
190                 env->NewStringUTF(server));
191     }
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));
201     }
202     return (jboolean)(result == 0);
203 }
204 
205 
android_net_utils_runDhcp(JNIEnv * env,jobject clazz,jstring ifname,jobject info)206 static 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 
android_net_utils_runDhcpRenew(JNIEnv * env,jobject clazz,jstring ifname,jobject info)211 static 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 
android_net_utils_stopDhcp(JNIEnv * env,jobject clazz,jstring ifname)217 static 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 
android_net_utils_releaseDhcpLease(JNIEnv * env,jobject clazz,jstring ifname)227 static 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 
android_net_utils_getDhcpError(JNIEnv * env,jobject clazz)237 static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
238 {
239     return env->NewStringUTF(::dhcp_get_errmsg());
240 }
241 
242 // ----------------------------------------------------------------------------
243 
244 /*
245  * JNI registration.
246  */
247 static JNINativeMethod gNetworkUtilMethods[] = {
248     /* name, signature, funcPtr */
249 
250     { "enableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_enableInterface },
251     { "disableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_disableInterface },
252     { "resetConnections", "(Ljava/lang/String;I)I",  (void *)android_net_utils_resetConnections },
253     { "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 },
255     { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
256     { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
257     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
258 };
259 
register_android_net_NetworkUtils(JNIEnv * env)260 int register_android_net_NetworkUtils(JNIEnv* env)
261 {
262     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");
274     dhcpResultsFieldIds.setDomains =
275             env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
276     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");
282 
283     return AndroidRuntime::registerNativeMethods(env,
284             NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
285 }
286 
287 }; // namespace android
288