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