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
  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
  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
 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 }