1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <libintl.h>
30 #include <arpa/inet.h>
31 #include <jni.h>
32 #include <com_sun_dhcpmgr_bridge_Bridge.h>
33
34 #include "exception.h"
35 #include "dd_opt.h"
36 #include "class_cache.h"
37
38 /*
39 * Retrieve default value for an option with a string value. Returns a
40 * single String.
41 */
42 /*ARGSUSED*/
43 JNIEXPORT jstring JNICALL
Java_com_sun_dhcpmgr_bridge_Bridge_getStringOption(JNIEnv * env,jobject obj,jshort code,jstring jarg)44 Java_com_sun_dhcpmgr_bridge_Bridge_getStringOption(
45 JNIEnv *env,
46 jobject obj,
47 jshort code,
48 jstring jarg)
49 {
50 jstring jstr;
51 struct dhcp_option *opt;
52 ushort_t scode = (ushort_t)code;
53 const char *arg;
54
55 /* Get the option whose default value we want to generate. */
56 arg = (*env)->GetStringUTFChars(env, jarg, NULL);
57 if (arg == NULL) {
58 /* exception thrown */
59 return (NULL);
60 }
61
62 /* Get the option data */
63 opt = dd_getopt(scode, arg, NULL);
64 (*env)->ReleaseStringUTFChars(env, jarg, arg);
65
66 if (opt == NULL) {
67 throw_memory_exception(env);
68 return (NULL);
69 }
70
71 if (opt->error_code != 0) {
72 throw_bridge_exception(env, opt->u.msg);
73 dd_freeopt(opt);
74 return (NULL);
75 }
76
77 /* Set the return value */
78 jstr = (*env)->NewStringUTF(env, opt->u.ret.data.strings[0]);
79 dd_freeopt(opt);
80 return (jstr);
81 }
82
83 /*
84 * Get the default value for an option whose value is one or more IP
85 * addresses. Returns an array of IPAddress objects.
86 */
87 /*ARGSUSED*/
88 JNIEXPORT jobjectArray JNICALL
Java_com_sun_dhcpmgr_bridge_Bridge_getIPOption(JNIEnv * env,jobject obj,jshort code,jstring jarg)89 Java_com_sun_dhcpmgr_bridge_Bridge_getIPOption(
90 JNIEnv *env,
91 jobject obj,
92 jshort code,
93 jstring jarg)
94 {
95 jclass ip_class;
96 jmethodID ip_cons;
97 jobjectArray jlist = NULL;
98 jobject jaddr;
99 jstring jstr;
100 struct dhcp_option *opt;
101 ushort_t scode = (ushort_t)code;
102 int i;
103 const char *arg;
104
105 /* Get classes and methods we need */
106 ip_class = find_class(env, IP_CLASS);
107 if (ip_class == NULL) {
108 /* exception thrown */
109 return (NULL);
110 }
111 ip_cons = get_methodID(env, ip_class, IP_CONS);
112 if (ip_cons == NULL) {
113 /* exception thrown */
114 return (NULL);
115 }
116
117 /* Retrieve option to generate value for */
118 arg = (*env)->GetStringUTFChars(env, jarg, NULL);
119 if (arg == NULL) {
120 /* exception thrown */
121 return (NULL);
122 }
123
124 /* Go get the default value */
125 opt = dd_getopt(scode, arg, NULL);
126 (*env)->ReleaseStringUTFChars(env, jarg, arg);
127
128 if (opt == NULL) {
129 throw_memory_exception(env);
130 return (NULL);
131 }
132
133 if (opt->error_code != 0) {
134 throw_bridge_exception(env, opt->u.msg);
135 dd_freeopt(opt);
136 return (NULL);
137 }
138
139 /* Construct the array */
140 jlist = (*env)->NewObjectArray(env, opt->u.ret.count, ip_class, NULL);
141 if (jlist == NULL) {
142 /* exception thrown */
143 dd_freeopt(opt);
144 return (NULL);
145 }
146
147 /* For each address, create an object and add it to the array */
148 for (i = 0; i < opt->u.ret.count; ++i) {
149 jstr = (*env)->NewStringUTF(env,
150 inet_ntoa(*opt->u.ret.data.addrs[i]));
151 if (jstr == NULL) {
152 /* exception thrown */
153 break;
154 }
155 jaddr = (*env)->NewObject(env, ip_class, ip_cons, jstr);
156 if (jaddr == NULL) {
157 /* exception thrown */
158 break;
159 }
160
161 (*env)->SetObjectArrayElement(env, jlist, i, jaddr);
162 if ((*env)->ExceptionOccurred(env) != NULL) {
163 break;
164 }
165 }
166
167 dd_freeopt(opt);
168 return (jlist);
169 }
170
171 /*
172 * Generate the default value for an option whose value is a list of numbers.
173 * Returns an array of longs.
174 */
175 /*ARGSUSED*/
176 JNIEXPORT jlongArray JNICALL
Java_com_sun_dhcpmgr_bridge_Bridge_getNumberOption(JNIEnv * env,jobject obj,jshort code,jstring jarg)177 Java_com_sun_dhcpmgr_bridge_Bridge_getNumberOption(
178 JNIEnv *env,
179 jobject obj,
180 jshort code,
181 jstring jarg)
182 {
183 jlongArray list;
184 struct dhcp_option *opt;
185 const char *arg;
186 ushort_t scode = (ushort_t)code;
187 jlong *listel;
188 int i;
189
190 /* Get option to retrieve */
191 arg = (*env)->GetStringUTFChars(env, jarg, NULL);
192 if (arg == NULL) {
193 /* exception thrown */
194 return (NULL);
195 }
196
197 opt = dd_getopt(scode, arg, NULL);
198 (*env)->ReleaseStringUTFChars(env, jarg, arg);
199
200 if (opt == NULL) {
201 throw_memory_exception(env);
202 return (NULL);
203 }
204
205 if (opt->error_code != 0) {
206 throw_bridge_exception(env, opt->u.msg);
207 dd_freeopt(opt);
208 return (NULL);
209 }
210
211 /* Allocate return array */
212 list = (*env)->NewLongArray(env, opt->u.ret.count);
213 if (list == NULL) {
214 /* exception thrown */
215 dd_freeopt(opt);
216 return (NULL);
217 }
218
219 /* Get access to elements of return array, then copy data in */
220 listel = (*env)->GetLongArrayElements(env, list, NULL);
221 if (listel == NULL) {
222 /* exception thrown */
223 dd_freeopt(opt);
224 return (NULL);
225 }
226
227 for (i = 0; i < opt->u.ret.count; ++i) {
228 listel[i] = opt->u.ret.data.numbers[i];
229 }
230
231 /* Tell VM we're done so it can finish putting data back */
232 (*env)->ReleaseLongArrayElements(env, list, listel, 0);
233
234 dd_freeopt(opt);
235 return (list);
236 }
237