android_net_NetUtils.cpp revision 0900f3657664d9046e6723825fd32b244eef2b6c
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
25extern "C" {
26int ifc_enable(const char *ifname);
27int ifc_disable(const char *ifname);
28int ifc_add_host_route(const char *ifname, uint32_t addr);
29int ifc_remove_host_routes(const char *ifname);
30int ifc_set_default_route(const char *ifname, uint32_t gateway);
31int ifc_get_default_route(const char *ifname);
32int ifc_remove_default_route(const char *ifname);
33int ifc_reset_connections(const char *ifname);
34int 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
36int 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);
44int dhcp_stop(const char *ifname);
45int dhcp_release_lease(const char *ifname);
46char *dhcp_get_errmsg();
47}
48
49#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
50
51namespace 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 */
58static 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
70static 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
80static 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
90static 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
100static 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
110static 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
120static 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
130static 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
140static 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
150static 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
172static 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
182static 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
192static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
193{
194    return env->NewStringUTF(::dhcp_get_errmsg());
195}
196
197static 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 */
220static 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
238int 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