• 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 
25 extern "C" {
26 int ifc_enable(const char *ifname);
27 int ifc_disable(const char *ifname);
28 int ifc_add_host_route(const char *ifname, uint32_t addr);
29 int ifc_remove_host_routes(const char *ifname);
30 int ifc_set_default_route(const char *ifname, uint32_t gateway);
31 int ifc_get_default_route(const char *ifname);
32 int ifc_remove_default_route(const char *ifname);
33 int ifc_reset_connections(const char *ifname);
34 int ifc_configure(const char *ifname, in_addr_t ipaddr, in_addr_t netmask, in_addr_t gateway, in_addr_t dns1, in_addr_t dns2);
35 
36 int dhcp_do_request(const char *ifname,
37                     in_addr_t *ipaddr,
38                     in_addr_t *gateway,
39                     in_addr_t *mask,
40                     in_addr_t *dns1,
41                     in_addr_t *dns2,
42                     in_addr_t *server,
43                     uint32_t  *lease);
44 int dhcp_stop(const char *ifname);
45 int dhcp_release_lease(const char *ifname);
46 char *dhcp_get_errmsg();
47 
48 int dhcp_do_request_renew(const char *ifname,
49                     in_addr_t *ipaddr,
50                     in_addr_t *gateway,
51                     in_addr_t *mask,
52                     in_addr_t *dns1,
53                     in_addr_t *dns2,
54                     in_addr_t *server,
55                     uint32_t  *lease);
56 }
57 
58 #define NETUTILS_PKG_NAME "android/net/NetworkUtils"
59 
60 namespace android {
61 
62 /*
63  * The following remembers the jfieldID's of the fields
64  * of the DhcpInfo Java object, so that we don't have
65  * to look them up every time.
66  */
67 static struct fieldIds {
68     jclass dhcpInfoClass;
69     jmethodID constructorId;
70     jfieldID ipaddress;
71     jfieldID gateway;
72     jfieldID netmask;
73     jfieldID dns1;
74     jfieldID dns2;
75     jfieldID serverAddress;
76     jfieldID leaseDuration;
77 } dhcpInfoFieldIds;
78 
android_net_utils_enableInterface(JNIEnv * env,jobject clazz,jstring ifname)79 static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
80 {
81     int result;
82 
83     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
84     result = ::ifc_enable(nameStr);
85     env->ReleaseStringUTFChars(ifname, nameStr);
86     return (jint)result;
87 }
88 
android_net_utils_disableInterface(JNIEnv * env,jobject clazz,jstring ifname)89 static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
90 {
91     int result;
92 
93     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
94     result = ::ifc_disable(nameStr);
95     env->ReleaseStringUTFChars(ifname, nameStr);
96     return (jint)result;
97 }
98 
android_net_utils_addHostRoute(JNIEnv * env,jobject clazz,jstring ifname,jint addr)99 static jint android_net_utils_addHostRoute(JNIEnv* env, jobject clazz, jstring ifname, jint addr)
100 {
101     int result;
102 
103     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
104     result = ::ifc_add_host_route(nameStr, addr);
105     env->ReleaseStringUTFChars(ifname, nameStr);
106     return (jint)result;
107 }
108 
android_net_utils_removeHostRoutes(JNIEnv * env,jobject clazz,jstring ifname)109 static jint android_net_utils_removeHostRoutes(JNIEnv* env, jobject clazz, jstring ifname)
110 {
111     int result;
112 
113     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
114     result = ::ifc_remove_host_routes(nameStr);
115     env->ReleaseStringUTFChars(ifname, nameStr);
116     return (jint)result;
117 }
118 
android_net_utils_setDefaultRoute(JNIEnv * env,jobject clazz,jstring ifname,jint gateway)119 static jint android_net_utils_setDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname, jint gateway)
120 {
121     int result;
122 
123     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
124     result = ::ifc_set_default_route(nameStr, gateway);
125     env->ReleaseStringUTFChars(ifname, nameStr);
126     return (jint)result;
127 }
128 
android_net_utils_getDefaultRoute(JNIEnv * env,jobject clazz,jstring ifname)129 static jint android_net_utils_getDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
130 {
131     int result;
132 
133     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
134     result = ::ifc_get_default_route(nameStr);
135     env->ReleaseStringUTFChars(ifname, nameStr);
136     return (jint)result;
137 }
138 
android_net_utils_removeDefaultRoute(JNIEnv * env,jobject clazz,jstring ifname)139 static jint android_net_utils_removeDefaultRoute(JNIEnv* env, jobject clazz, jstring ifname)
140 {
141     int result;
142 
143     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
144     result = ::ifc_remove_default_route(nameStr);
145     env->ReleaseStringUTFChars(ifname, nameStr);
146     return (jint)result;
147 }
148 
android_net_utils_resetConnections(JNIEnv * env,jobject clazz,jstring ifname)149 static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz, jstring ifname)
150 {
151     int result;
152 
153     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
154     result = ::ifc_reset_connections(nameStr);
155     env->ReleaseStringUTFChars(ifname, nameStr);
156     return (jint)result;
157 }
158 
android_net_utils_runDhcp(JNIEnv * env,jobject clazz,jstring ifname,jobject info)159 static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
160 {
161     int result;
162     in_addr_t ipaddr, gateway, mask, dns1, dns2, server;
163     uint32_t lease;
164 
165     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
166     result = ::dhcp_do_request(nameStr, &ipaddr, &gateway, &mask,
167                                         &dns1, &dns2, &server, &lease);
168     env->ReleaseStringUTFChars(ifname, nameStr);
169     if (result == 0 && dhcpInfoFieldIds.dhcpInfoClass != NULL) {
170         env->SetIntField(info, dhcpInfoFieldIds.ipaddress, ipaddr);
171         env->SetIntField(info, dhcpInfoFieldIds.gateway, gateway);
172         env->SetIntField(info, dhcpInfoFieldIds.netmask, mask);
173         env->SetIntField(info, dhcpInfoFieldIds.dns1, dns1);
174         env->SetIntField(info, dhcpInfoFieldIds.dns2, dns2);
175         env->SetIntField(info, dhcpInfoFieldIds.serverAddress, server);
176         env->SetIntField(info, dhcpInfoFieldIds.leaseDuration, lease);
177     }
178     return (jboolean)(result == 0);
179 }
180 
android_net_utils_stopDhcp(JNIEnv * env,jobject clazz,jstring ifname)181 static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
182 {
183     int result;
184 
185     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
186     result = ::dhcp_stop(nameStr);
187     env->ReleaseStringUTFChars(ifname, nameStr);
188     return (jboolean)(result == 0);
189 }
190 
android_net_utils_releaseDhcpLease(JNIEnv * env,jobject clazz,jstring ifname)191 static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
192 {
193     int result;
194 
195     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
196     result = ::dhcp_release_lease(nameStr);
197     env->ReleaseStringUTFChars(ifname, nameStr);
198     return (jboolean)(result == 0);
199 }
200 
android_net_utils_getDhcpError(JNIEnv * env,jobject clazz)201 static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
202 {
203     return env->NewStringUTF(::dhcp_get_errmsg());
204 }
205 
android_net_utils_configureInterface(JNIEnv * env,jobject clazz,jstring ifname,jint ipaddr,jint mask,jint gateway,jint dns1,jint dns2)206 static jboolean android_net_utils_configureInterface(JNIEnv* env,
207         jobject clazz,
208         jstring ifname,
209         jint ipaddr,
210         jint mask,
211         jint gateway,
212         jint dns1,
213         jint dns2)
214 {
215     int result;
216     uint32_t lease;
217 
218     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
219     result = ::ifc_configure(nameStr, ipaddr, mask, gateway, dns1, dns2);
220     env->ReleaseStringUTFChars(ifname, nameStr);
221     return (jboolean)(result == 0);
222 }
223 
android_net_utils_runDhcpRenew(JNIEnv * env,jobject clazz,jstring ifname,jobject info)224 static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
225 {
226     int result = -1;
227     in_addr_t ipaddr, gateway, mask, dns1, dns2, server;
228     uint32_t lease;
229 
230     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
231     result = ::dhcp_do_request_renew(nameStr, &ipaddr, &gateway, &mask,
232             &dns1, &dns2, &server, &lease);
233     env->ReleaseStringUTFChars(ifname, nameStr);
234     if (result == 0 && dhcpInfoFieldIds.dhcpInfoClass != NULL) {
235         env->SetIntField(info, dhcpInfoFieldIds.ipaddress, ipaddr);
236         env->SetIntField(info, dhcpInfoFieldIds.gateway, gateway);
237         env->SetIntField(info, dhcpInfoFieldIds.netmask, mask);
238         env->SetIntField(info, dhcpInfoFieldIds.dns1, dns1);
239         env->SetIntField(info, dhcpInfoFieldIds.dns2, dns2);
240         env->SetIntField(info, dhcpInfoFieldIds.serverAddress, server);
241         env->SetIntField(info, dhcpInfoFieldIds.leaseDuration, lease);
242     }
243 
244     return (jboolean)(result == 0);
245 }
246 // ----------------------------------------------------------------------------
247 
248 /*
249  * JNI registration.
250  */
251 static JNINativeMethod gNetworkUtilMethods[] = {
252     /* name, signature, funcPtr */
253 
254     { "enableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_enableInterface },
255     { "disableInterface", "(Ljava/lang/String;)I",  (void *)android_net_utils_disableInterface },
256     { "addHostRoute", "(Ljava/lang/String;I)I",  (void *)android_net_utils_addHostRoute },
257     { "removeHostRoutes", "(Ljava/lang/String;)I",  (void *)android_net_utils_removeHostRoutes },
258     { "setDefaultRoute", "(Ljava/lang/String;I)I",  (void *)android_net_utils_setDefaultRoute },
259     { "getDefaultRoute", "(Ljava/lang/String;)I",  (void *)android_net_utils_getDefaultRoute },
260     { "removeDefaultRoute", "(Ljava/lang/String;)I",  (void *)android_net_utils_removeDefaultRoute },
261     { "resetConnections", "(Ljava/lang/String;)I",  (void *)android_net_utils_resetConnections },
262     { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfo;)Z",  (void *)android_net_utils_runDhcp },
263     { "stopDhcp", "(Ljava/lang/String;)Z",  (void *)android_net_utils_stopDhcp },
264     { "releaseDhcpLease", "(Ljava/lang/String;)Z",  (void *)android_net_utils_releaseDhcpLease },
265     { "configureNative", "(Ljava/lang/String;IIIII)Z",  (void *)android_net_utils_configureInterface },
266     { "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
267     { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfo;)Z",  (void *)android_net_utils_runDhcpRenew}
268 };
269 
register_android_net_NetworkUtils(JNIEnv * env)270 int register_android_net_NetworkUtils(JNIEnv* env)
271 {
272     jclass netutils = env->FindClass(NETUTILS_PKG_NAME);
273     LOG_FATAL_IF(netutils == NULL, "Unable to find class " NETUTILS_PKG_NAME);
274 
275     dhcpInfoFieldIds.dhcpInfoClass = env->FindClass("android/net/DhcpInfo");
276     if (dhcpInfoFieldIds.dhcpInfoClass != NULL) {
277         dhcpInfoFieldIds.constructorId = env->GetMethodID(dhcpInfoFieldIds.dhcpInfoClass, "<init>", "()V");
278         dhcpInfoFieldIds.ipaddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "ipAddress", "I");
279         dhcpInfoFieldIds.gateway = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "gateway", "I");
280         dhcpInfoFieldIds.netmask = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "netmask", "I");
281         dhcpInfoFieldIds.dns1 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns1", "I");
282         dhcpInfoFieldIds.dns2 = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "dns2", "I");
283         dhcpInfoFieldIds.serverAddress = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "serverAddress", "I");
284         dhcpInfoFieldIds.leaseDuration = env->GetFieldID(dhcpInfoFieldIds.dhcpInfoClass, "leaseDuration", "I");
285     }
286 
287     return AndroidRuntime::registerNativeMethods(env,
288             NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
289 }
290 
291 }; // namespace android
292