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