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